in Java könnte ich eine enum mit zusätzlichen Daten leicht beschreiben.
Ich könnte es so beschreiben.
Fügen Sie dann eine statische Methode hinzu, die über Werte () iteriert, alle Daten zu einer Hash-Map hinzufügt und es ermöglicht, aus der Karte vollständige Enum-Daten durch eines ihrer Attribute als Schlüssel abzurufen.
Kurz gesagt, Enum ist ein sehr entwickelter Typ in Java.
Jetzt,
Umzug nach c #, was sind meine Möglichkeiten?
Ich möchte ein Enum mit seinen Attributen halten, es auf eine Karte laden und nach Schlüssel retreiven, wenn ich es brauche. Habe ich etwas zu helfen (wie ein Singletone für jedes Enum - was keine gute Idee ist).
Danke.
Ich würde nur eine statische Klasse mit public static readonly
Instanzen von jedem Typ erstellen und den Graben komplett auflösen. Sie können sie als Wörterbuchschlüssel verwenden oder tun, was Sie wollen. Wenn Sie sie immer noch einem zugrunde liegenden Datentyp zuordnen möchten ( int
), können Sie auch implizite Operatoren dafür erstellen.
Beispielverwendung:
%Vor% Wenn Ihnen ein zugrunde liegender Wert egal ist, schließen Sie ihn nicht ein. Überlegen Sie auch, ob das Dictionary
-Mapping threadsafe für Ihre Verwendung sein sollte. Sie können auch eine statische IEnumerable<OperatorType>
(oder eine andere Sammlung) bereitstellen, um alle Operatoren zu definieren, wenn Sie möchten.
BEARBEITEN: Beim zweiten Gedanken sind explicit
-Operatoren möglicherweise vorzuziehen, anstatt implicit
, um sowohl den typischen .NET-Best Practices zu entsprechen als auch typische enum
-Konvertierungen besser anzupassen.
Die praktischste Problemumgehung könnte darin bestehen, eine Erweiterungsmethode für Ihren Enum-Typ zu erstellen und die zugehörigen Symbole zurückzugeben.
In etwa so:
%Vor%Natürlich können Sie eine komplexere Erweiterungsmethode mit Rückgabewert usw. schreiben, dies ist nur ein Beispiel dafür.
C # hat nicht wirklich die gleiche Funktion. Es gibt jedoch mehrere Möglichkeiten, um wirklich nah (und möglicherweise auch flexibler) zu kommen.
Wenn Sie sich an reguläre Enums halten, können Sie Attribute verwenden, um mit zusätzlichen Informationen anzureichern. Natürlich erfordert dies Reflexion, um damit zu arbeiten.
%Vor%Es gibt mehrere Muster, um damit zu arbeiten, z.B. Ссылка , google für mehr.
Ein anderer Ansatz kann darin bestehen, Ihre Aufzählungstypen mithilfe regulärer Klassen zu verbessern:
%Vor%In diesem Artikel werden einige andere Möglichkeiten beschrieben, mit enumähnlichen Typen in C # zu arbeiten
Sie können ein Attribut erstellen:
%Vor%Wenden Sie es dann auf Ihre enum
an %Vor%Um die Attributdaten zu erhalten, können Sie reflection verwenden. Im Folgenden finden Sie ein Beispiel für das Abrufen des Attributs für "Weniger"
%Vor%Da diese Enums jedoch nicht zur Laufzeit erstellt werden, können Sie Ihre Effizienz steigern, indem Sie eine statische Methode erstellen, die den Wert in einem Wörterbuch nachschlägt. Tun Sie dies als eine Erweiterungsmethode für die Benutzerfreundlichkeit
%Vor%Um nun die Werte zu erhalten, machen Sie einfach folgendes:
%Vor%Seien Sie vorsichtig bei Null-Referenz-Ausnahmen (da es null zurückgibt, wenn es kein Attribut findet). Wenn Sie nach Schlüssel suchen möchten, können Sie einfach andere Erweiterungsmethoden erstellen, die den Zeichenfolgenwert als Schlüssel verwenden.
Wenn Sie wirklich die Funktionalität von Java-Stil Aufzählungen in C # benötigen, sehe ich drei sinnvolle Möglichkeiten, es zu implementieren:
Verwenden Sie eine C # -Enumerierung und eine statische Klasse von Hilfsmethoden. Sie verlieren die Typensicherheit, aber dies ist eine ansonsten sehr praktikable Lösung.
Verwenden Sie eine C # -Enumerierung und eine Reihe von Erweiterungsmethoden. Wahrscheinlich die idiomatische C # -Lösung, aber Sie müssen sich immer noch mit dem Verlust der Typsicherheit befassen (Ihre Erweiterungsmethoden sollten in der Lage sein, Werte außer Reichweite zu bewältigen, wenn auch nur durch Auslösen einer Ausnahme).
Verwenden Sie die typsicheren Enumeration Muster , das in Java üblich war, bevor die Sprache das enum
-Schlüsselwort in Java 5 erhielt. Wenn Sie nicht-triviale Logik für jeden enum-Wert haben, wäre dies meine Präferenz.