2009-03-27 3 views
4

sagen, ich habe folgende Erklärungen akzeptiert:C# Funktion, die ein Enum Element und gibt den ENUM-Wert (der Index)

public enum Complexity { Low = 0, Normal = 1, Medium = 2, High = 3 } 
public enum Priority { Normal = 1, Medium = 2, High = 3, Urgent = 4 } 

und ich möchte es codieren, so dass ich den ENUM-Wert bekommen konnte (nicht der Index, wie ich bereits erwähnte):

//should store the value of the Complexity enum member Normal, which is 1 
int complexityValueToStore = EnumHelper.GetEnumMemberValue(Complexity.Normal); 
//should store the value 4 
int priorityValueToStore = EnumHelper.GetEnumMemberValue(Priority.Urgent); 

Wie sollte diese wiederverwendbare Funktion aussehen?

tia! -ren

Antwort

15

Überarbeitete Antwort (nach Klärung Frage)

Nein, es gibt nichts sauberer als Gips. Es ist informativer als ein Methodenaufruf, billiger, kürzer usw. Es ist ungefähr so ​​wenig, wie Sie nur hoffen können.

Beachten Sie, dass Sie, wenn Sie eine generische Methode schreiben möchten, um die Konvertierung durchzuführen, müssen Sie angeben, was es auch zu konvertieren: die Enumeration könnte auf byte oder long zum Beispiel basieren. Wenn Sie den Cast einfügen, sagen Sie explizit, in was Sie ihn konvertieren möchten, und es tut es einfach.

Ursprüngliche Antwort

Was meinst du mit "index" genau? Meinst du den numerischen Wert? Einfach auf int werfen. Wenn Sie „Position innerhalb Enum“ bedeuten würden Sie die Werte in numerischer Reihenfolge sicherstellen müssen, dass (wie das ist, was Enum.GetValues gibt - nicht die Deklaration Reihenfolge), und dann tun:

public static int GetEnumMemberIndex<T>(T element) 
    where T : struct 
{ 
    T[] values = (T[]) Enum.GetValues(typeof(T)); 
    return Array.IndexOf(values, element); 
} 
+0

ich meine den numerischen Wert. Ich weiß, dass ich zu int casten kann, aber ich hatte gehofft, ich könnte es sauberer kodieren –

+1

Sie haben Recht. Es war eine dumme Idee. Ich wurde beim Aufbau einer EnumHelper-Klasse davongetragen. –

8

Sie können den ganzzahligen Wert eines Aufzählungs durch Gießen finden:

int complexityValueToStore = (int)Complexity.Normal; 
0

Wenn Sie den Wert wollen Sie können die Enumeration einfach in int umwandeln. Das wäre gesetzt complexityValueToStore == 1 und priorityValueToStore == 4.

Wenn Sie den Index (dh: Priority.Urgent == 3) erhalten möchten, können Sie Enum.GetValues verwenden, dann nur den Index der aktuellen Enum finden in diese Liste. Die Reihenfolge der Enumeration in der zurückgegebenen Liste stimmt jedoch möglicherweise nicht mit der in Ihrem Code überein.

Die zweite Option Art besiegt jedoch den Zweck von Enum in erster Linie - Sie versuchen, diskrete Werte anstelle von Listen und Indizes zu haben. Ich würde deine Bedürfnisse überdenken, wenn es das ist, was du willst.

2

Ich weiß, das ist nicht das, was Sie gefragt haben, aber es ist etwas, das Sie schätzen könnten.

Ich entdeckte, dass Sie den ganzzahligen Wert eines Aufzählungs ohne Guss finden können, wenn Sie wissen, was den minimalen Wert des Enum ist:

public enum Complexity { Low = 0, Normal = 1, Medium = 2, High = 3 } 

int valueOfHigh = Complexity.High - Complexity.Low; 

Dies würde mit Priorität nicht funktionieren, es sei denn, Sie einige minimale hinzugefügt

public enum Priority { Normal = 1, Medium = 2, High = 3, Urgent = 4 } 

int valueOfUrgent = Priority.Urgent - Priority.Normal + 1; 

ich diese Technik viel mehr ästhetisch ansprechend auf int als Gießen finden: Wert von 0 oder 1 zurück gegeben.

Ich bin nicht sicher von der Spitze meines Kopfes, was passiert, wenn Sie eine enum basierend auf Byte oder lang haben - ich vermute, dass Sie Byte oder lange Differenzwerte erhalten würden.

+0

+1 das ist der Punkt !! – Perpetualcoder

+0

Dies setzt auch voraus, dass die Enum-Werte zusammenhängend sind (ist das das Wort?) Und beginnen bei einem bekannten Wert und sind in der richtigen Reihenfolge. Versuchen Sie 'enum DealBreaker {First = 3, Second = 1, Third = 19}'. Oh, und das Enum hat nicht das Attribut [Flags]. – Benjol

4

Die allgemeinste Art, die ich kenne, ist, das Feld value__ mit Reflexion zu lesen. Dieser Ansatz macht keine Annahmen über den zugrundeliegenden Typ des Enum, so dass es auf Enums funktioniert, die nicht auf Int32 basieren.

public static object GetValue(Enum e) 
{ 
    return e.GetType().GetField("value__").GetValue(e); 
} 

Debug.Assert(Equals(GetValue(DayOfWeek.Wednesday), 3));    //Int32 
Debug.Assert(Equals(GetValue(AceFlags.InheritOnly), (byte) 8));  //Byte 
Debug.Assert(Equals(GetValue(IOControlCode.ReceiveAll), 2550136833L)); //Int64 

Hinweis: Ich habe dies nur mit dem Microsoft C# -Compiler getestet. Es ist eine Schande, dass es keine eingebaute Möglichkeit dafür zu geben scheint.

0

Dies ist der einfachste Weg, um Ihr Problem zu lösen:

public static void GetEnumMemberValue<T>(T enumItem) where T : struct 
{ 
    return (int) Enum.Parse(typeof(T), enumItem.ToString()); 
} 

Es funktioniert für mich.

Verwandte Themen