Ich möchte eine generische Methode zum Konvertieren eines von System.Enum abgeleiteten Typs in seinen entsprechenden ganzzahligen Wert erstellen, ohne umzuwandeln und vorzugsweise ohne eine Zeichenfolge zu analysieren.
ZB was ich will ist so etwas:
// Trivial example, not actually what I'm doing.
class Converter
{
int ToInteger(System.Enum anEnum)
{
(int)anEnum;
}
}
Dies scheint jedoch nicht zu funktionieren. Resharper meldet, dass Sie den Ausdruck vom Typ 'System.Enum' nicht in den Typ 'int' umwandeln können.
Jetzt habe ich diese Lösung gefunden, aber ich hätte lieber etwas effizienteres.
class Converter
{
int ToInteger(System.Enum anEnum)
{
return int.Parse(anEnum.ToString("d"));
}
}
Irgendwelche Vorschläge?
c#
enums
type-conversion
orj
quelle
quelle
Antworten:
Wenn du nicht besetzen willst,
könnte den Trick machen.
Die direkte Besetzung (via
(int)enumValue
) ist nicht möglich. Beachten Sie, dass dies auch „gefährlich“ wäre da eine Enumeration verschiedene zugrunde liegende Typen haben kann (int
,long
,byte
...).Formaler:
System.Enum
Hat keine direkte Vererbungsbeziehung mitInt32
(obwohl beideValueType
s sind), so dass die explizite Umwandlung innerhalb des Typsystems nicht korrekt sein kannquelle
Converter.ToInteger(MyEnum.MyEnumConstant);
wird Ihnen hier keinen Fehler geben. Bitte bearbeiten Sie diesen Teil.int
long
enum.System.Enum
ist eine Klasse, also ein Referenztyp. Die Werte sind wahrscheinlich eingerahmt.Ich habe es zum Laufen gebracht, indem ich es auf ein Objekt und dann auf ein int geworfen habe:
Das ist hässlich und wahrscheinlich nicht der beste Weg. Ich werde weiter damit herumspielen, um zu sehen, ob ich mir etwas Besseres einfallen lassen kann ...
EDIT: Ich wollte gerade posten, dass Convert.ToInt32 (enumValue) auch funktioniert, und bemerkte, dass MartinStettner mich geschlagen hat.
Prüfung:
EDIT 2: In den Kommentaren sagte jemand, dass dies nur in C # 3.0 funktioniert. Ich habe das gerade in VS2005 so getestet und es hat funktioniert:
quelle
Wenn Sie eine Aufzählung in den zugrunde liegenden Typ konvertieren müssen (nicht alle Aufzählungen werden von unterstützt
int
), können Sie Folgendes verwenden:quelle
Convert.ChangeType
akzeptiertobject
für das erste Argument und gibt zurückobject
.Warum müssen Sie das Rad mit einer Hilfsmethode neu erfinden? Es ist völlig legal, einen
enum
Wert auf den zugrunde liegenden Typ zu setzen.Es ist weniger tippen und meiner Meinung nach besser lesbar, ...
... anstatt so etwas wie ...
quelle
Aus meiner Antwort hier :
Gegeben
e
wie in:Dann funktionieren diese:
Die letzten beiden sind einfach hässlich. Der erste sollte besser lesbar sein, der zweite ist jedoch viel schneller. Oder vielleicht ist eine Erweiterungsmethode das Beste, das Beste aus beiden Welten.
Jetzt können Sie anrufen:
quelle
e
Variable hat bereits die Box-Instanz des tatsächlichen Werttyps , dh Enum. Wenn Sie schreiben, istEnum e = Question.Role;
es bereits verpackt. Die Frage betrifft die Konvertierung des BoxedSystem.Enum
Backs in den zugrunde liegenden Int-Typ (Unboxing). Hier ist Unboxing also nur das Leistungsproblem.(int)(object)e
ist ein direkter Unbox-Anruf; Ja sollte schneller sein als andere Ansätze. Sehen Sie diesDas Casting von a
System.Enum
nach aint
funktioniert gut für mich (es ist auch auf dem MSDN ). Vielleicht ist es ein Resharper-Fehler.quelle
System.Enum
, nicht von sichSystem.Enum
selbst.Da Enums auf Byte, Sbyte, Short, Ushort, Int, Uint, Long und Ulong beschränkt sind, können wir einige Annahmen treffen.
Wir können Ausnahmen während der Konvertierung vermeiden, indem wir den größten verfügbaren Container verwenden. Leider ist nicht klar, welcher Container verwendet werden soll, da ulong für negative Zahlen und long für Zahlen zwischen long.MaxValue und ulong.MaxValue explodiert. Wir müssen zwischen diesen Auswahlmöglichkeiten basierend auf dem zugrunde liegenden Typ wechseln.
Natürlich müssen Sie immer noch entscheiden, was zu tun ist, wenn das Ergebnis nicht in ein int passt. Ich denke, Casting ist in Ordnung, aber es gibt noch einige Fallstricke:
Hier ist mein Vorschlag, ich überlasse es dem Leser zu entscheiden, wo diese Funktion verfügbar gemacht werden soll. als Helfer oder Erweiterung.
quelle
Vergessen Sie nicht, dass der Enum-Typ selbst eine Reihe statischer Hilfsfunktionen enthält. Wenn Sie lediglich eine Instanz der Enumeration in den entsprechenden Integer-Typ konvertieren möchten, ist das Casting wahrscheinlich der effizienteste Weg.
Ich denke, ReSharper beschwert sich, weil Enum keine Aufzählung eines bestimmten Typs ist und die Aufzählungen selbst von einem skalaren Werttyp abgeleitet sind, nicht von Enum. Wenn Sie generisch anpassbares Casting benötigen, würde ich sagen, dass dies gut zu Ihnen passt (beachten Sie, dass der Aufzählungstyp selbst auch im generischen enthalten ist:
Dies könnte dann folgendermaßen verwendet werden:
Ich kann es nicht mit Sicherheit sagen, aber der obige Code wird möglicherweise sogar durch die Typinferenz von C # unterstützt, was Folgendes ermöglicht:
quelle
EnumHelpers.Convert<int, StopLight>(StopLight.Red);
anstelle von verwenden(int)StopLight.Read;
? Auch die Frage sprichtSystem.Enum
.