Ich würde gerne wissen, ob es möglich ist, Attribute der enum
Werte und nicht der enum
selbst zu erhalten. Angenommen, ich habe Folgendes enum
:
using System.ComponentModel; // for DescriptionAttribute
enum FunkyAttributesEnum
{
[Description("Name With Spaces1")]
NameWithoutSpaces1,
[Description("Name With Spaces2")]
NameWithoutSpaces2
}
Was ich möchte, ist der Aufzählungstyp, 2-Tupel des Aufzählungszeichenfolgenwerts und seine Beschreibung.
Wert war einfach:
Array values = System.Enum.GetValues(typeof(FunkyAttributesEnum));
foreach (int value in values)
Tuple.Value = Enum.GetName(typeof(FunkyAttributesEnum), value);
Aber wie erhalte ich den Wert des Beschreibungsattributs zum Auffüllen Tuple.Desc
? Ich kann mir überlegen, wie ich es machen soll, wenn das Attribut zu sich enum
selbst gehört, aber ich bin ratlos, wie ich es aus dem Wert des machen kann enum
.
c#
reflection
enums
.net-attributes
Alex K.
quelle
quelle
DescriptionAttribute
.Antworten:
Dies sollte tun, was Sie brauchen.
quelle
Dieser Code sollte Ihnen eine nette kleine Erweiterungsmethode für jede Aufzählung geben, mit der Sie ein generisches Attribut abrufen können. Ich glaube, es unterscheidet sich von der obigen Lambda-Funktion, weil es einfacher und geringfügig zu verwenden ist - Sie müssen nur den generischen Typ übergeben.
quelle
IndexOutOfRangeException
?GetCustomAttributes()
dann das erste Element zu erhalten, anstatt aufzurufenGetCustomAttribute()
?Dies ist eine generische Implementierung, bei der ein Lambda für die Auswahl verwendet wird
Nennen Sie es so:
quelle
FlagsAttribute
). In diesem Fallenumeration.GetType().GetMember(enumeration.ToString())[0]
wird fehlschlagen.value.GetType().GetField(value.ToString()).GetCustomAttributes(false).OfType<T>().SingleOrDefault()
aber Sie müssen zugeben, dass Ihr expliziter Weg besser ist.Ich habe hier einige Antworten zusammengeführt, um eine etwas erweiterbarere Lösung zu erstellen. Ich biete es nur für den Fall an, dass es in Zukunft für andere hilfreich ist. Originalbeitrag hier .
Diese Lösung erstellt zwei Erweiterungsmethoden für Enum. Mit der ersten Option können Sie mithilfe der Reflexion alle mit Ihrem Wert verknüpften Attribute abrufen. Der zweite Aufruf ruft speziell das ab
DescriptionAttribute
und gibt seinenDescription
Wert zurück.Verwenden Sie als Beispiel das
DescriptionAttribute
Attribut vonSystem.ComponentModel
Um die obige Erweiterungsmethode zu verwenden, rufen Sie jetzt einfach Folgendes auf:
oder
quelle
Zusätzlich zur AdamCrawford-Antwort habe ich eine speziellere Erweiterungsmethode erstellt, die davon speist, um die Beschreibung zu erhalten.
Um die Beschreibung zu erhalten, können Sie daher entweder die ursprüngliche Erweiterungsmethode als verwenden
oder Sie können die Erweiterungsmethode hier einfach wie folgt aufrufen:
Das sollte Ihren Code hoffentlich etwas lesbarer machen.
quelle
Fließender Einzeiler ...
Hier verwende ich das,
DisplayAttribute
das sowohl dieName
als auch dieDescription
Eigenschaften enthält.Beispiel
Ausgabe
quelle
Hier ist Code zum Abrufen von Informationen aus einem Anzeigeattribut. Es verwendet eine generische Methode, um das Attribut abzurufen. Wenn das Attribut nicht gefunden wird, konvertiert es den Aufzählungswert in eine Zeichenfolge, wobei die Groß- / Kleinschreibung in die Groß- und Kleinschreibung konvertiert wird (Code hier erhalten ).
Dies ist die Erweiterungsmethode für Zeichenfolgen zum Konvertieren in Groß- und Kleinschreibung:
quelle
Ich habe diese Erweiterungsmethode implementiert, um die Beschreibung aus Enum-Werten zu erhalten. Es funktioniert für alle Arten von Aufzählungen.
quelle
Holen Sie sich das Wörterbuch von enum.
Nennen Sie das jetzt wie ...
EnumDecription Ext-Methode
quelle
Hier ist die .NET Core-Version von AdamCrawfords Antwort unter Verwendung von System.Reflection.TypeExtensions .
quelle
Hinzufügen meiner Lösung für Net Framework und NetCore.
Ich habe dies für meine Net Framework-Implementierung verwendet:
Dies funktioniert nicht für NetCore, daher habe ich es so geändert:
Aufzählungsbeispiel:
Beispielnutzung für beide statischen Elemente hinzugefügt:
quelle
Mit einigen der neueren C # -Sprachenfunktionen können Sie die Zeilenanzahl reduzieren:
quelle
Ich habe diese Antwort gegeben, um ein Kombinationsfeld aus einem Enum-Attribut einzurichten, was großartig war.
Ich musste dann die Rückseite codieren, damit ich die Auswahl aus der Box erhalten und die Aufzählung im richtigen Typ zurückgeben kann.
Ich habe auch den Code geändert, um den Fall zu behandeln, in dem ein Attribut fehlte
Für die Vorteile der nächsten Person ist hier meine endgültige Lösung
}}
quelle
Wenn Ihr
enum
Wert so ist, dassEquals
Sie möglicherweise auf einige Fehler stoßen, indem Sie einige Erweiterungen in vielen Antworten verwenden. Dies liegt daran, dass normalerweise davon ausgegangen wird, dasstypeof(YourEnum).GetMember(YourEnum.Value)
nur ein Wert zurückgegeben wird, nämlich derMemberInfo
von Ihnenenum
. Hier ist eine etwas sicherere Version der Antwort von Adam Crawford .quelle
Diese Erweiterungsmethode erhält eine Zeichenfolgendarstellung eines Aufzählungswerts unter Verwendung seines XmlEnumAttribute. Wenn kein XmlEnumAttribute vorhanden ist, wird auf enum.ToString () zurückgegriffen.
quelle
Und wenn Sie die vollständige Liste der Namen möchten, können Sie so etwas tun
quelle
Leute, wenn es hilft, werde ich meine Lösung mit Ihnen teilen: Definition des benutzerdefinierten Attributs:
Jetzt, weil ich es innerhalb der HtmlHelper-Definition der HtmlHelper-Erweiterung brauchte:
Ich hoffe es hilft
quelle
Jetzt wird in diesem Fall ein Fehler erzeugt. 1 "Gleich"
Wenn es also derselbe ist, wird der Aufzählungsname anstelle des Anzeigenamens zurückgegeben, da enumMember.GetCustomAttribute () null wird, wenn Anzeigename und Aufzählungsname identisch sind.
quelle
Alternativ können Sie Folgendes tun:
quelle
So habe ich es gelöst, ohne benutzerdefinierte Helfer oder Erweiterungen mit .NET Core 3.1 zu verwenden.
Klasse
Rasierer
quelle
Leistung ist wichtig
Wenn Sie eine bessere Leistung wünschen, ist dies der richtige Weg:
Warum hat dies eine bessere Leistung?
Da die integrierten Methoden alle Code verwenden, der diesem sehr ähnlich ist, außer dass sie auch eine Reihe anderer Codes ausführen, die uns egal sind . Der Enum-Code von C # ist im Allgemeinen ziemlich schrecklich.
Der obige Code wurde linearisiert und optimiert, sodass er nur die Bits enthält, die uns wichtig sind.
Warum ist der eingebaute Code langsam?
Zunächst zu Enum.ToString () -vs- Enum.GetName (..)
Verwenden Sie immer Letzteres. (Oder noch besser auch nicht, wie weiter unten deutlich wird.)
ToString () verwendet letzteres intern, erledigt aber auch eine Reihe anderer Dinge, die wir nicht wollen, z. B. Versuche, Flags zu kombinieren, Zahlen auszudrucken usw. Wir sind nur an Konstanten interessiert, die in der Aufzählung definiert sind.
Enum.GetName ruft wiederum alle Felder ab, erstellt ein String-Array für alle Namen, verwendet das obige ToUInt64 für alle RawConstantValues, um ein UInt64-Array aller Werte zu erstellen, sortiert beide Arrays nach dem UInt64-Wert und erhält schließlich den Namen von das Name-Array durch Ausführen einer BinarySearch im UInt64-Array, um den Index des gewünschten Werts zu finden.
... und dann werfen wir die Felder weg und die sortierten Arrays verwenden diesen Namen, um das Feld wieder zu finden.
Ein Wort: "Ugh!"
quelle
Alternativ können Sie Folgendes tun:
Und erhalten Sie die Beschreibung mit folgendem:
Meiner Meinung nach ist dies eine effizientere Methode, um das zu tun, was Sie erreichen möchten, da keine Reflexion erforderlich ist.
quelle
Sie können auch einen Aufzählungswert wie definieren.
Name_Without_Spaces
Wenn Sie eine Beschreibung wünschenName_Without_Spaces.ToString().Replace('_', ' ')
, können Sie die Unterstriche durch Leerzeichen ersetzen.quelle