Получить перечисление из атрибута enum

у меня есть

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

с

 public class StringValueAttribute : Attribute { private string _value; public StringValueAttribute(string value) { _value = value; } public string Value { get { return _value; } } } 

И я хотел бы поместить значение из элемента, который я выбрал из combobox, в int:

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

Возможно ли это, и если да, то как? ( StringValue соответствует значению, выбранному из StringValue ).

Вот вспомогательный метод, который должен указывать на вас в правильном направлении.

 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."); } 

И чтобы назвать это, просто выполните следующее:

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

Это, вероятно, не лучшее решение, хотя, поскольку оно связано с Als и вы, вероятно, захотите сделать этот код повторно используемым. Что вы, вероятно, захотите удалить из моего решения код, чтобы вернуть вам значение атрибута, а затем просто используйте Enum.Parse как вы делаете в своем вопросе.

Я использую DescriptionAttribute от Microsoft и следующий метод расширения:

 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; } 

Вот несколько методов расширения, которые я использую для этой конкретной цели, я переписал их, чтобы использовать свой StringValueAttribute , но, как Оливер, я использую DescriptionAttribute в своем коде.

  public static T FromEnumStringValue(this string description) where T : struct { Debug.Assert(typeof(T).IsEnum); return (T)typeof(T) .GetFields() .First(f => f.GetCustomAttributes(typeof(StringValueAttribute), false) .Cast() .Any(a => a.Value.Equals(description, StringComparison.OrdinalIgnoreCase)) ) .GetValue(null); } 

Это можно сделать несколько проще в .NET 4.5:

  public static T FromEnumStringValue(this string description) where T : struct { Debug.Assert(typeof(T).IsEnum); return (T)typeof(T) .GetFields() .First(f => f.GetCustomAttributes() .Any(a => a.Value.Equals(description, StringComparison.OrdinalIgnoreCase)) ) .GetValue(null); } 

И чтобы назвать это, просто выполните следующее:

 Als result = ComboBox.SelectedValue.FromEnumStringValue(); 

И наоборот , вот функция, чтобы получить строку из значения enums:

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

И назвать это:

 string description = Als.NietBeantwoord.StringValue() 

Не уверен, что я здесь что-то не хватает, не можете ли вы этого сделать,

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

Перейдя сюда из повторяющихся ссылок этого высокоподнятого вопроса и ответа , вот метод, который работает с новым ограничением типа C # 7.3. Обратите внимание, что вам также нужно указать, что это также struct чтобы вы могли сделать ее TEnum? или вы получите сообщение об ошибке.

 public static TEnum? GetEnumFromDescription(string description) where TEnum : struct, Enum { var comparison = StringComparison.OrdinalIgnoreCase; foreach (var field in typeof(TEnum).GetFields()) { var attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute; if (attribute != null) { if (string.Compare(attribute.Description, description, comparison) == 0) return (TEnum)field.GetValue(null); } if (string.Compare(field.Name, description, comparison) == 0) return (TEnum)field.GetValue(null); } return null; } 
Давайте будем гением компьютера.