2010-05-07 13 views
30

IGet Enum von ENUM Attribut

public enum Als 
{ 
    [StringValue("Beantwoord")] Beantwoord = 0, 
    [StringValue("Niet beantwoord")] NietBeantwoord = 1, 
    [StringValue("Geselecteerd")] Geselecteerd = 2, 
    [StringValue("Niet geselecteerd")] NietGeselecteerd = 3, 
} 

mit

public class StringValueAttribute : Attribute 
{ 
    private string _value; 

    public StringValueAttribute(string value) 
    { 
     _value = value; 
    } 

    public string Value 
    { 
     get { return _value; } 
    } 
} 

haben Und ich möchte den Wert von dem Punkt habe ich eine Combobox in einen int ausgewählt:

int i = (int)(Als)Enum.Parse(typeof(Als), (string)cboAls.SelectedValue); //<- WRONG 

Ist das möglich, und wenn ja, wie? (StringValue entspricht dem aus der Combobox ausgewählten Wert).

+2

Das sollte funktionieren. Was ist das Problem? –

+1

Random Tipp: Sie können Auto-Eigenschaften dafür verwenden. benutze "public string Wert {get; private set;} und du kannst die klebrige _value-Variable vermeiden. – Rubys

+0

@Kent Boogaart:" Niet beantwoord "! =" NietBeantwoord " – bniwredyc

Antwort

19

Hier ist eine Hilfsmethode, die Sie in die richtige Richtung weisen sollte.

protected Als GetEnumByStringValueAttribute(string value) 
{ 
    Type enumType = typeof(Als); 
    foreach (Enum val in Enum.GetValues(enumType)) 
    { 
     FieldInfo fi = enumType.GetField(val.ToString()); 
     StringValueAttribute[] attributes = (StringValueAttribute[])fi.GetCustomAttributes(
      typeof(StringValueAttribute), false); 
     StringValueAttribute attr = attributes[0]; 
     if (attr.Value == value) 
     { 
      return (Als)val; 
     } 
    } 
    throw new ArgumentException("The value '" + value + "' is not supported."); 
} 

Und es zu nennen, tun nur die folgenden:

Als result = this.GetEnumByStringValueAttribute<Als>(ComboBox.SelectedValue); 

Dies ist wahrscheinlich nicht die beste Lösung, obwohl, wie es Als gebunden ist, und Sie werden wahrscheinlich wollen diesen Code Wieder- machen verwendbar. Was Sie wahrscheinlich den Code aus meiner Lösung entfernen möchten, um Ihnen den Attributwert zurückzugeben und dann einfach Enum.Parse zu verwenden, wie Sie in Ihrer Frage tun.

+8

Diese Lösung kann leicht geändert werden, um generisch zu sein. Ändern Sie einfach alle Vorkommen von "Als" in "T" und fügen Sie der Methode ein Typargument namens "T" hinzu. –

+1

rette mich Tag, danke für alle Bro. – caras

+0

@DanielHilgarth Ich habe versucht, es zu tun, bekam aber einen Fehler und sagte '" Der Typparameter kann nicht mit dem 'as' -Operator verwendet werden, da er keine Klassentypbeschränkung oder eine 'Klassen'-Einschränkung' 'auf der Rückleitung der Methode hat . Hättest du ein praktisches Beispiel dafür, wie das gelöst werden könnte? –

11

ich die DescriptionAttribute von Microsoft und die folgende Erweiterung Methode:

public static string GetDescription(this Enum value) 
{ 
    if (value == null) 
    { 
     throw new ArgumentNullException("value"); 
    } 

    string description = value.ToString(); 
    FieldInfo fieldInfo = value.GetType().GetField(description); 
    DescriptionAttribute[] attributes = 
     (DescriptionAttribute[]) 
    fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); 

    if (attributes != null && attributes.Length > 0) 
    { 
     description = attributes[0].Description; 
    } 
    return description; 
} 
+7

Gegenüber von dem, was OP fragte, da er Enum von String und nicht String von Enum will, aber das hat mir sehr geholfen, danke! – psycho

0

nicht sicher, ob ich etwas fehlt hier, können Sie dies nicht tun,

Als temp = (Als)combo1.SelectedItem; 
int t = (int)temp; 
5

Hier sind ein Paar Erweiterungsmethoden, die ich für diesen genauen Zweck verwenden, habe ich diese umgeschrieben, um Ihre StringValueAttribute zu verwenden, aber wie Oliver Ich verwende die DescriptionAttribute in meinem Code.

public static T FromEnumStringValue<T>(this string description) where T : struct { 
     Debug.Assert(typeof(T).IsEnum); 

     return (T)typeof(T) 
      .GetFields() 
      .First(f => f.GetCustomAttributes(typeof(StringValueAttribute), false) 
         .Cast<StringValueAttribute>() 
         .Any(a => a.Value.Equals(description, StringComparison.OrdinalIgnoreCase)) 
      ) 
      .GetValue(null); 
    } 

Dies kann etwas einfacher in .NET 4.5 hergestellt werden:

public static T FromEnumStringValue<T>(this string description) where T : struct { 
     Debug.Assert(typeof(T).IsEnum); 

     return (T)typeof(T) 
      .GetFields() 
      .First(f => f.GetCustomAttributes<StringValueAttribute>() 
         .Any(a => a.Value.Equals(description, StringComparison.OrdinalIgnoreCase)) 
      ) 
      .GetValue(null); 
    } 

Und es zu nennen, nur Folgendes tun: eine Funktion

Als result = ComboBox.SelectedValue.FromEnumStringValue<Als>(); 

Umgekehrt, hier ist Um die Zeichenkette von einem Enum-Wert zu erhalten:

public static string StringValue(this Enum enumItem) { 
     return enumItem 
      .GetType() 
      .GetField(enumItem.ToString()) 
      .GetCustomAttributes<StringValueAttribute>() 
      .Select(a => a.Value) 
      .FirstOrDefault() ?? enumItem.ToString(); 
    } 

Und es nennen:

string description = Als.NietBeantwoord.StringValue()