example - switch enum c#




Obtener el atributo enum from enum (4)

Tengo

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

con

public class StringValueAttribute : Attribute
{
    private string _value;

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

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

Y me gustaría poner el valor del ítem que seleccioné de un combobox en un int:

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

¿Es posible? y si lo es, cómo? ( StringValue coincide con el valor seleccionado del cuadro combinado).


Aquí hay un método de ayuda que debe apuntar en la dirección correcta.

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

Y para llamarlo, solo haz lo siguiente:

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

Probablemente esta no sea la mejor solución, ya que está vinculada a Als y es probable que desee volver a utilizar este código. Lo que probablemente quiera es quitar el código de mi solución para devolverle el valor del atributo y luego simplemente usar Enum.Parse como lo hace en su pregunta.


Aquí hay un par de métodos de extensión que utilizo para este propósito exacto, los reescribí para usar su StringValueAttribute , pero como Oliver , uso el DescriptionAttribute en mi código.

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

Esto se puede hacer un poco más simple en .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);
    }

Y para llamarlo, solo haz lo siguiente:

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

Por el contrario , aquí hay una función para obtener la cadena a partir de un valor enum:

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

Y para llamarlo:

string description = Als.NietBeantwoord.StringValue()

No estoy seguro de si me falta algo aquí, no puedes hacer esto,

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

Viniendo aquí de los enlaces duplicados de esta pregunta y respuesta muy votada , este es un método que funciona con la nueva restricción de tipo Enum C # 7.3. Tenga en cuenta que también necesita especificar que también es una struct para que pueda convertirlo en el TEnum? o de lo contrario obtendrás un 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;
}






custom-attributes