Get enum from enum attribute
Solution 1
Here's a helper method that should point you in the right direction.
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.");
}
And to call it, just do the following:
Als result = this.GetEnumByStringValueAttribute<Als>(ComboBox.SelectedValue);
This probably isn't the best solution though as it's tied to Als
and you'll probably want to make this code re-usable. What you'll probably want to strip out the code from my solution to return you the attribute value and then just use Enum.Parse
as you are doing in your question.
Solution 2
I'm using the DescriptionAttribute from Microsoft and the following extension method:
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;
}
Solution 3
Here are a couple extension methods that I use for this exact purpose, I've rewritten these to use your StringValueAttribute
, but like Oliver I use the DescriptionAttribute in my 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);
}
This can be made slightly more simple in .NET 4.5:
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);
}
And to call it, just do the following:
Als result = ComboBox.SelectedValue.FromEnumStringValue<Als>();
Conversely, here's a function to get the string from an enum value:
public static string StringValue(this Enum enumItem) {
return enumItem
.GetType()
.GetField(enumItem.ToString())
.GetCustomAttributes<StringValueAttribute>()
.Select(a => a.Value)
.FirstOrDefault() ?? enumItem.ToString();
}
And to call it:
string description = Als.NietBeantwoord.StringValue()
Solution 4
Coming here from duplicate links of this highly upvoted question and answer, here is a method that works with C# 7.3's new Enum
type constraint. Note that you also need to specify that it is also a struct
so that you can make it the nullable TEnum?
or else you will get an error.
public static TEnum? GetEnumFromDescription<TEnum>(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;
}
Solution 5
Not sure if I am missing something here, can you not do this,
Als temp = (Als)combo1.SelectedItem;
int t = (int)temp;
RubenHerman
Updated on August 13, 2021Comments
-
RubenHerman almost 3 years
I've got
public enum Als { [StringValue("Beantwoord")] Beantwoord = 0, [StringValue("Niet beantwoord")] NietBeantwoord = 1, [StringValue("Geselecteerd")] Geselecteerd = 2, [StringValue("Niet geselecteerd")] NietGeselecteerd = 3, }
with
public class StringValueAttribute : Attribute { private string _value; public StringValueAttribute(string value) { _value = value; } public string Value { get { return _value; } } }
And I would like to put the value from the item I selected of a combobox into a int:
int i = (int)(Als)Enum.Parse(typeof(Als), (string)cboAls.SelectedValue); //<- WRONG
Is this possible, and if so, how? (the
StringValue
matches the value selected from the combobox). -
Daniel Hilgarth over 12 yearsThis solution can easily be changed to be generic. Simply change all occurrences of
Als
toT
and add a type argument namedT
to the method. -
psycho about 11 yearsOpposite of what OP asked since he wants enum from string and not string from enum, but that helped me a lot, thanks!
-
Ulysses Alves over 6 years@DanielHilgarth I tryied to do it but got error saying
"The type parameter cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint"
on the return line of the method. Would you have a practical example on how this could be solved?