Ich weiß, dass Folgendes nicht möglich ist, da der Typ der Aufzählung ein int sein muss
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
Aus meiner Datenbank erhalte ich ein Feld mit nicht umfassenden Codes (the OEM
und CMB
s). Ich würde dieses Feld zu einem enum
oder etwas anderem Verständlichem machen wollen. Denn wenn das Ziel lesbar ist, sollte die Lösung knapp sein.
Welche anderen Optionen habe ich?
Antworten:
Ich verwende lieber Eigenschaften in einer Klasse anstelle von Methoden, da sie eher enumartig aussehen.
Hier ist ein Beispiel für einen Logger:
Übergeben Sie typsichere Zeichenfolgenwerte als Parameter:
Verwendungszweck:
quelle
ToString
Methode zur Rückgabe überschriebenValue
. Und dann implizite Cast-Operatoren zu und von einer Zeichenfolge bereitgestellt.public static implicit operator String(LogCategory category) { return Value; }
.Sie können auch das Erweiterungsmodell verwenden:
Ihre Erweiterungsklasse
Verwendungszweck:
quelle
public static string ToDescriptionString(this Enum ...
dh ohne explizite Eingabe inMyEnum
.Wie wäre es mit einer statischen Klasse mit Konstanten?
quelle
GroupTypes
Argumenttyp übergeben, da es sich um eine statische Klasse handelt. Das ist das Problem, das sogar Miens Antwort löst. In diesem Fall würden Sie stattdessen haben müssenvoid DoSomething(string groupType)
, die dann Mittel , diegroupType
haben könnte überhaupt eine beliebige Zeichenfolge Wert , auch Werte , die Sie nicht erwartet werden, das heißt , Sie für diese ungültigen Typen hergestellt werden müssen und entscheiden , wie sie zu behandeln (zB durch Auslösen einer Ausnahme). Sogar Miens Antwort löst dies, indem die Anzahl der gültigen Eingaben auf die von derLogCategory
Klasse definierten Optionen begrenzt wird .Sie können den Elementen in der Aufzählung Attribute hinzufügen und dann mithilfe der Reflektion die Werte aus den Attributen abrufen.
Sie müssten den "Feld" -Spezifizierer verwenden, um die Attribute wie folgt anzuwenden:
Sie würden dann über die statischen Felder des Aufzählungstyps (in diesem Fall GroupTypes) nachdenken und
DescriptionAttribute
den Wert für den Wert ermitteln, den Sie mithilfe von Reflection gesucht haben:Ich habe mich dafür entschieden, das
DescriptionAttribute
obige selbst zurückzugeben, falls Sie feststellen möchten, ob das Attribut überhaupt angewendet wird oder nicht.quelle
Sie können es tatsächlich sehr einfach tun. Verwenden Sie den folgenden Code.
Wenn Sie dann den Zeichenfolgenwert jedes Enum-Elements abrufen möchten, verwenden Sie einfach die folgende Codezeile.
Ich habe diese Methode in der Vergangenheit erfolgreich verwendet, und ich habe auch eine Konstantenklasse verwendet, um Zeichenfolgenkonstanten zu halten. Beide funktionieren ziemlich gut, aber ich bevorzuge dies.
quelle
Versuchen Sie, einer statischen Klasse Konstanten hinzuzufügen. Sie erhalten keinen Typ, aber Sie haben lesbare, organisierte Konstanten:
quelle
Erstellen Sie eine zweite Aufzählung für Ihre Datenbank, die Folgendes enthält:
Jetzt können Sie Enum.Parse verwenden, um den korrekten DBGroupTypes-Wert aus den Zeichenfolgen "OEM" und "CMB" abzurufen. Sie können diese dann in int konvertieren und die richtigen Werte aus der richtigen Aufzählung abrufen, die Sie in Ihrem Modell weiter verwenden möchten.
quelle
Verwenden Sie eine Klasse.
Edit: Besseres Beispiel
quelle
Eine andere Möglichkeit, das Problem zu lösen, besteht darin, eine Aufzählung und ein Array von Zeichenfolgen zu haben, die die Aufzählungswerte der Liste der Zeichenfolgen zuordnen:
Sie können es so etwas verwenden:
Es wird CMB aufgefordert
PROS:
Nachteile:
quelle
Hier ist die Erweiterungsmethode, mit der ich den Aufzählungswert als Zeichenfolge abgerufen habe. Hier ist zuerst die Aufzählung.
Das Description-Attribut stammt von System.ComponentModel.
Und hier ist meine Erweiterungsmethode:
Jetzt können Sie mit dem folgenden Code auf die Aufzählung als Zeichenfolgenwert zugreifen:
quelle
Haben Sie eine Nachschlagetabelle mit einem Wörterbuch in Betracht gezogen?
Sie können dann GroupTypeLookup.TryGetValue () verwenden, um eine Zeichenfolge beim Lesen nachzuschlagen.
quelle
quelle
C # unterstützt keine aufgezählten Zeichenfolgen, aber in den meisten Situationen können Sie eine Liste oder ein Wörterbuch verwenden, um den gewünschten Effekt zu erzielen.
ZB So drucken Sie Pass / Fail-Ergebnisse:
quelle
Ich würde es zu einer Klasse machen und eine Aufzählung ganz vermeiden. Und dann können Sie mit einem Typhandler das Objekt erstellen, wenn Sie es aus der Datenbank holen.
IE:
quelle
Ich würde einfach ein Wörterbuch erstellen und den Code als Schlüssel verwenden.
Bearbeiten: Um den Kommentar zu einer umgekehrten Suche (Finden des Schlüssels) zu adressieren, wäre dies nicht besonders effizient. Wenn dies notwendig ist, würde ich eine neue Klasse schreiben, um damit umzugehen.
quelle
Meine erste Frage - Haben Sie Zugriff auf die Datenbank selbst? Dies sollte in der Datenbank normalisiert werden, andernfalls ist jede Lösung fehleranfällig. Nach meiner Erfahrung werden in Datenfeldern mit "OEM" und "CMB" häufig Dinge wie "OEM" und andere "Mistdaten" im Laufe der Zeit gemischt. Wenn Sie sie normalisieren können, können Sie den Schlüssel verwenden in der Tabelle mit den Elementen als Aufzählung, und Sie sind fertig, mit einer viel saubereren Struktur.
Wenn das nicht verfügbar ist, würde ich Ihre Aufzählung erstellen und eine Klasse erstellen, um Ihre Zeichenfolge für Sie in die Aufzählung zu analysieren. Dies würde Ihnen zumindest eine gewisse Flexibilität bei der Behandlung von nicht standardmäßigen Einträgen und viel mehr Flexibilität bei der Überfüllung oder Behandlung von Fehlern geben, als wenn Sie eine der Problemumgehungen mit Enum.Parse / Reflection / etc. Ein Wörterbuch würde funktionieren, könnte aber zusammenbrechen, wenn Sie jemals Fallprobleme usw. haben.
Ich würde empfehlen, eine Klasse zu schreiben, damit Sie Folgendes tun können:
Dadurch bleibt der größte Teil Ihrer Lesbarkeit erhalten, ohne dass die Datenbank geändert werden muss.
quelle
Wenn ich das richtig verstehe, benötigen Sie eine Konvertierung von Zeichenfolge in Aufzählung:
Wenn Sie möchten, können Sie es mit Generika für den Aufzählungstyp ausgefallener machen.
quelle
In VS 2015 können Sie nameof verwenden
Verwendungszweck:
quelle
Eine kleine Änderung an der Glennular Extension-Methode, damit Sie die Erweiterung auch für andere Zwecke als nur für ENUM verwenden können.
Oder mit Linq
quelle
Nach der Antwort von @Even Mien habe ich versucht, ein bisschen weiter zu gehen und es generisch zu machen. Ich scheine fast da zu sein, aber ein Fall widersteht immer noch und ich kann meinen Code wahrscheinlich ein bisschen vereinfachen.
Ich poste es hier, wenn jemand sieht, wie ich es verbessern und vor allem dafür sorgen kann, dass es funktioniert, da ich es nicht aus einem String zuweisen kann
Bisher habe ich folgende Ergebnisse:
Wo die Magie passiert:
Ich muss dies erst dann für meine Aufzählungen deklarieren:
quelle
Neu in .Net Core 3.0 / C # 8.0 (wenn Ihre Arbeitsumgebung es Ihnen ermöglicht, Ihr Projekt zu aktualisieren) ist eine kurze switch-Anweisung, die etwas aufzählend aussieht. Letztendlich ist es die gleiche langweilige Switch-Anweisung, die wir seit Jahren verwenden.
Der einzige wirkliche Unterschied besteht darin, dass die switch-Anweisung einen neuen Anzug bekommen hat.
Sie werden feststellen, dass der Code, über den ich von hier kopiert habe , tatsächlich eine Aufzählung als Parameter verwendet.
Es ist nicht genau das, was Sie wollen (und vertrauen Sie mir, ich wollte schon seit langer Zeit etwas Ähnliches wie das OP), aber ich habe tatsächlich das Gefühl, dass dies ein Olivenzweig von MS ist. JMO.
Hoffe es hilft jemandem!
quelle
Ich habe eine Struktur verwendet, auf die in einer früheren Antwort hingewiesen wurde, aber jede Komplexität beseitigt. Für mich war dies am ähnlichsten wie das Erstellen einer Aufzählung von Zeichenfolgen. Es wird auf die gleiche Weise verwendet, wie eine Aufzählung verwendet wird.
Anwendungsbeispiel:
quelle
Ich habe sogar ein paar Enums implementiert, wie von @Even (via
class X
undpublic static X
Mitglieder) vorgeschlagen, um später herauszufinden, dass es heutzutage ab .Net 4.5 das Richtige gibtToString()
Methode gibt.Jetzt setze ich alles wieder in Aufzählungen um.
quelle
Dies ist eine Möglichkeit, es als stark typisierten Parameter oder als Zeichenfolge zu verwenden :
quelle
Sie können zwei Aufzählungen verwenden. Eine für die Datenbank und die andere für die Lesbarkeit.
Sie müssen nur sicherstellen, dass sie synchron bleiben, was wie geringe Kosten erscheint. Sie müssen die Werte nicht festlegen, sondern nur die Positionen gleich festlegen. Durch das Festlegen der Werte wird jedoch deutlich, dass die beiden Aufzählungen zusammenhängen, und es wird verhindert, dass Fehler die Aufzählungselemente neu anordnen. Ein Kommentar informiert die Wartungsmannschaft darüber, dass diese miteinander zusammenhängen und synchron gehalten werden müssen.
Um es zu verwenden, konvertieren Sie einfach zuerst in den Code:
Wenn Sie es dann noch komfortabler machen möchten, können Sie eine Erweiterungsfunktion hinzufügen, die nur für diese Art von Aufzählung funktioniert:
und Sie können dann einfach tun:
quelle
enum
eine beabsichtigte Wertänderung in einer die andere unbeabsichtigt durcheinander bringen.Ich suchte im Grunde nach der Reflection-Antwort von @ArthurC
Um seine Antwort ein wenig zu erweitern, können Sie sie noch besser machen, indem Sie eine generische Funktion haben:
Dann können Sie einfach alles einwickeln, was Sie haben
oder
quelle
Entnommen aus @EvenMien und in einigen Kommentaren hinzugefügt. (Auch für meinen eigenen Anwendungsfall)
quelle
Hinzufügen dieser Klasse
Diese Arbeit dient dazu
CallerMemberName
, die Codierung zu minimierenVerwenden von:
Probier es aus:
Ausgabe:
quelle
Aufgrund anderer Meinungen habe ich mir das ausgedacht. Durch diesen Ansatz wird vermieden, dass Sie .Value eingeben müssen, wenn Sie den konstanten Wert erhalten möchten.
Ich habe eine Basisklasse für alle String-Enums wie diese:
Der JsonConverter sieht folgendermaßen aus:
Und eine tatsächliche String-Aufzählung wird ungefähr so aussehen:
Und damit können Sie einfach Color.Red verwenden, um sogar in json zu serialisieren, ohne die Value-Eigenschaft zu verwenden
quelle
Ich brauchte nichts Robustes wie das Speichern der Zeichenfolge in Attributen. Ich musste nur so etwas wie
MyEnum.BillEveryWeek
"Rechnung jede Woche" oderMyEnum.UseLegacySystem
"Legacy-System verwenden" umwandeln - im Grunde die Aufzählung durch die Kamelhülle in einzelne Kleinbuchstaben aufteilen.MyEnum.UseLegacySystem.UnCamelCase()
Ausgänge "Legacy-System verwenden"Wenn Sie mehrere Flags gesetzt haben, wird dies in einfaches Englisch umgewandelt (durch Kommas getrennt, mit Ausnahme eines "und" anstelle des letzten Kommas).
quelle