Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从枚举属性获取枚举_C#_.net_Enums_Attributes_Custom Attributes - Fatal编程技术网

C# 从枚举属性获取枚举

C# 从枚举属性获取枚举,c#,.net,enums,attributes,custom-attributes,C#,.net,Enums,Attributes,Custom Attributes,我有 public enum Als { [StringValue("Beantwoord")] Beantwoord = 0, [StringValue("Niet beantwoord")] NietBeantwoord = 1, [StringValue("Geselecteerd")] Geselecteerd = 2, [StringValue("Niet geselecteerd")] NietGeselecteerd = 3, } 与 我想把我从

我有

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

我想把我从组合框中选择的项目的值转换成int:

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

inti=(int)(Als)Enum.Parse(typeof(Als),(string)cboAls.SelectedValue)// 这里有一个助手方法,它应该为您指明正确的方向

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<Als>(ComboBox.SelectedValue);
Als result = ComboBox.SelectedValue.FromEnumStringValue<Als>();
Als result=this.getEnumByStringValue属性(ComboBox.SelectedValue);
但这可能不是最好的解决方案,因为它与
Als
有关,您可能希望使此代码可重用。您可能希望从我的解决方案中删除代码以返回属性值,然后像您在问题中所做的那样使用
Enum.Parse

我正在使用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;
}

不确定我是否遗漏了什么,你不能这样做吗

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

这里有几个扩展方法,我就是为了这个目的而使用的,我已经重写了这些方法来使用您的
StringValueAttribute
,但就像我在代码中使用的一样

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

来自的重复链接,这里有一个与C#7.3的新
Enum
type约束一起工作的方法。请注意,您还需要指定它也是一个
struct
,以便可以将其设置为可为null的
TEnum?
,否则将出现错误

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;
}
public static TEnum?GetEnumFromDescription(字符串描述)
其中TEnum:struct,Enum
{
var比较=StringComparison.OrdinalIgnoreCase;
foreach(typeof(TEnum).GetFields()中的变量字段)
{
var attribute=attribute.GetCustomAttribute(字段,typeof(DescriptionAttribute))作为DescriptionAttribute;
if(属性!=null)
{
if(string.Compare(attribute.Description,Description,comparison)==0)
返回(TEnum)字段。GetValue(null);
}
if(string.Compare(field.Name、description、comparison)==0)
返回(TEnum)字段。GetValue(null);
}
返回null;
}

要根据应用于枚举成员的属性值解析字符串值,我建议您使用我的开源库

对于像
StringValueAttribute
这样的自定义属性,您可以这样做

StringValueAttribute.Value
注册并存储自定义
EnumFormat

Format = Enums.RegisterCustomEnumFormat(m => m.Attributes.Get<StringValueAttribute>()?.Value);
如果改为使用内置属性(如),则可以这样做

Als result = Enums.Parse<Als>("Niet beantwoord", EnumFormat.Description);

我提出了一个更通用的解决方案。
您可以将它与任何属性一起使用,甚至与字符串以外的其他类型一起使用

using System;

namespace EnumTest
{
    public static class EnumExtensions
    {
        #region Get enum from Attribute
        /// <summary>
        /// Searches the enum element which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// Throws exception, if there is no enum element found which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// </summary>
        /// <param name="attributeType">the type of the attribute. e.g. typeof(System.ComponentModel.DescriptionAttribute)</param>
        /// <param name="attributePropertyName">the property of the attribute to search. At DescriptionAttribute, this is "Description"</param>
        /// <param name="searchValue">the value to search</param>
        public static TEnum FromAttributeValueToEnum<TEnum>(Type attributeType, string attributePropertyName, object searchValue)
        where TEnum : struct, Enum
        {
            TEnum? result = FromAttributeValueToNullableEnum<TEnum>(attributeType, attributePropertyName, searchValue);

            if (result.HasValue)
            {
                return result.Value;
            }

            Type enumType = typeof(TEnum);
            throw new ArgumentException($"The enum type {enumType.FullName} has no element with a {attributeType.FullName} with {attributePropertyName} property equivalent to '{searchValue}'");
        }

        /// <summary>
        /// Searches the enum element which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// Returns fallBackValue, if there is no enum element found which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// </summary>
        /// <param name="attributeType">the type of the attribute. e.g. typeof(System.ComponentModel.DescriptionAttribute)</param>
        /// <param name="attributePropertyName">the property of the attribute to search. At DescriptionAttribute, this is "Description"</param>
        /// <param name="searchValue">the value to search</param> 
        public static TEnum FromAttributeValueToEnum<TEnum>(Type attributeType, string attributePropertyName, object searchValue, TEnum fallBackValue)
        where TEnum : struct, Enum
        {
            TEnum? result = FromAttributeValueToNullableEnum<TEnum>(attributeType, attributePropertyName, searchValue);

            if (result.HasValue)
            {
                return result.Value;
            }

            return fallBackValue;
        }

        /// <summary>
        /// Searches the enum element which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// Returns null, if there is no enum element found which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// </summary>
        /// <param name="attributeType">the type of the attribute. e.g. typeof(System.ComponentModel.DescriptionAttribute)</param>
        /// <param name="attributePropertyName">the property of the attribute to search. At DescriptionAttribute, this is "Description"</param>
        /// <param name="searchValue">the value to search</param> 
        public static TEnum? FromAttributeValueToNullableEnum<TEnum>(Type attributeType, string attributePropertyName, object searchValue)
        where TEnum : struct, Enum
        {
            Type enumType = typeof(TEnum);
            if (!enumType.IsEnum)
            {
                throw new ArgumentException($"The type {enumType.FullName} is no Enum!");
            }

            if (attributeType == null)
            {
                throw new ArgumentNullException(nameof(attributeType));
            }

            if (!typeof(Attribute).IsAssignableFrom(attributeType))
            {
                throw new ArgumentException($"The type {attributeType.FullName} is no Attribute!", nameof(attributeType));
            }

            var propertyInfoAttributePropertyName = attributeType.GetProperty(attributePropertyName);

            if (propertyInfoAttributePropertyName == null)
            {
                throw new ArgumentException($"The type {attributeType.FullName} has no (public) property with name {attributePropertyName}", nameof(attributeType));
            }

            foreach (var field in enumType.GetFields())
            {
                var attribute = Attribute.GetCustomAttribute(field, attributeType);
                if (attribute == null)
                {
                    continue;
                }

                object attributePropertyValue = propertyInfoAttributePropertyName.GetValue(attribute);

                if (attributePropertyValue == null)
                {
                    continue;
                }

                if (attributePropertyValue.Equals(searchValue))
                {
                    return (TEnum)field.GetValue(null);
                }
            }

            return null;
        }
        #endregion
    }
}
使用系统;
命名空间枚举测试
{
公共静态类枚举扩展
{
#区域从属性获取枚举
/// 
///搜索具有[attributeType]属性且attributePropertyName等效于searchValue的枚举元素。
///如果未找到具有attributePropertyName等效于searchValue的[attributeType]属性的枚举元素,则引发异常。
/// 
///属性的类型,例如typeof(System.ComponentModel.DescriptionAttribute)
///要搜索的属性的属性。在DescriptionAttribute中,这是“Description”
///要搜索的值
公共静态TEnum FromAttributeValueToEnum(类型attributeType、字符串attributePropertyName、对象searchValue)
其中TEnum:struct,Enum
{
TEnum?结果=从AttributeValue到UllableEnum(attributeType、attributePropertyName、searchValue);
if(result.HasValue)
{
返回结果值;
}
类型enumType=typeof(TEnum);
抛出新的ArgumentException($“枚举类型{enumType.FullName}没有具有{attributeType.FullName}且{attributePropertyName}属性等于{searchValue}”的元素);
}
/// 
///搜索具有[attributeType]属性且attributePropertyName等效于searchValue的枚举元素。
///如果未找到具有attributePropertyName等效于searchValue的[attributeType]属性的枚举元素,则返回fallBackValue。
/// 
///属性的类型,例如typeof(System.ComponentModel.DescriptionAttribute)
///要搜索的属性的属性。在DescriptionAttribute中,这是“Description”
///要搜索的值
公共静态TEnum FromAttributeValueToEnum(类型attributeType、字符串attributePropertyName、对象searchValue、TEnum fallBackValue)
其中TEnum:struct,Enum
{
TEnum?结果=从AttributeValue到UllableEnum(attributeType、attributePropertyName、searchValue);
if(result.HasValue)
{
返回结果值;
}
返回回退值;
}
/// 
///搜索具有[attributeType]属性且attributePropertyName等效于searchValue的枚举元素。
///如果未找到具有attributePropertyName等效于searchValue的[attributeType]属性的枚举元素,则返回null。
/// 
///属性的类型,例如typeof(System.ComponentModel.DescriptionAttribute)
///要搜索的属性的属性。在DescriptionAttribute中,这是“Description”
///要搜索的值
公共静态TEnum?从AttributeValue到UllableEnum(类型attributeType、字符串attributePropertyName、对象searchValue)
其中TEnum:struct,Enum
{
类型enumType=typeof(TEnum);
如果(!enumType.IsEnum)
{
抛出新ArgumentException($“类型{enumType.FullName}不是枚举!”);
}
if(attributeType==null)
{
抛出新ArgumentNullException(nameof(attributeType));
}
如果(!typeof(Attribute).IsAssignableFrom(attributeType))
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;
}
Format = Enums.RegisterCustomEnumFormat(m => m.Attributes.Get<StringValueAttribute>()?.Value);
Als result = Enums.Parse<Als>("Niet beantwoord", Format); // result == Als.NietBeantwoord
Als result = Enums.Parse<Als>("Niet beantwoord", EnumFormat.Description);
string value = Als.NietBeantwoord.AsString(Format); // value == "Niet beantwoord"
using System;

namespace EnumTest
{
    public static class EnumExtensions
    {
        #region Get enum from Attribute
        /// <summary>
        /// Searches the enum element which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// Throws exception, if there is no enum element found which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// </summary>
        /// <param name="attributeType">the type of the attribute. e.g. typeof(System.ComponentModel.DescriptionAttribute)</param>
        /// <param name="attributePropertyName">the property of the attribute to search. At DescriptionAttribute, this is "Description"</param>
        /// <param name="searchValue">the value to search</param>
        public static TEnum FromAttributeValueToEnum<TEnum>(Type attributeType, string attributePropertyName, object searchValue)
        where TEnum : struct, Enum
        {
            TEnum? result = FromAttributeValueToNullableEnum<TEnum>(attributeType, attributePropertyName, searchValue);

            if (result.HasValue)
            {
                return result.Value;
            }

            Type enumType = typeof(TEnum);
            throw new ArgumentException($"The enum type {enumType.FullName} has no element with a {attributeType.FullName} with {attributePropertyName} property equivalent to '{searchValue}'");
        }

        /// <summary>
        /// Searches the enum element which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// Returns fallBackValue, if there is no enum element found which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// </summary>
        /// <param name="attributeType">the type of the attribute. e.g. typeof(System.ComponentModel.DescriptionAttribute)</param>
        /// <param name="attributePropertyName">the property of the attribute to search. At DescriptionAttribute, this is "Description"</param>
        /// <param name="searchValue">the value to search</param> 
        public static TEnum FromAttributeValueToEnum<TEnum>(Type attributeType, string attributePropertyName, object searchValue, TEnum fallBackValue)
        where TEnum : struct, Enum
        {
            TEnum? result = FromAttributeValueToNullableEnum<TEnum>(attributeType, attributePropertyName, searchValue);

            if (result.HasValue)
            {
                return result.Value;
            }

            return fallBackValue;
        }

        /// <summary>
        /// Searches the enum element which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// Returns null, if there is no enum element found which has a [attributeType] attribute with a attributePropertyName equivalent to searchValue.
        /// </summary>
        /// <param name="attributeType">the type of the attribute. e.g. typeof(System.ComponentModel.DescriptionAttribute)</param>
        /// <param name="attributePropertyName">the property of the attribute to search. At DescriptionAttribute, this is "Description"</param>
        /// <param name="searchValue">the value to search</param> 
        public static TEnum? FromAttributeValueToNullableEnum<TEnum>(Type attributeType, string attributePropertyName, object searchValue)
        where TEnum : struct, Enum
        {
            Type enumType = typeof(TEnum);
            if (!enumType.IsEnum)
            {
                throw new ArgumentException($"The type {enumType.FullName} is no Enum!");
            }

            if (attributeType == null)
            {
                throw new ArgumentNullException(nameof(attributeType));
            }

            if (!typeof(Attribute).IsAssignableFrom(attributeType))
            {
                throw new ArgumentException($"The type {attributeType.FullName} is no Attribute!", nameof(attributeType));
            }

            var propertyInfoAttributePropertyName = attributeType.GetProperty(attributePropertyName);

            if (propertyInfoAttributePropertyName == null)
            {
                throw new ArgumentException($"The type {attributeType.FullName} has no (public) property with name {attributePropertyName}", nameof(attributeType));
            }

            foreach (var field in enumType.GetFields())
            {
                var attribute = Attribute.GetCustomAttribute(field, attributeType);
                if (attribute == null)
                {
                    continue;
                }

                object attributePropertyValue = propertyInfoAttributePropertyName.GetValue(attribute);

                if (attributePropertyValue == null)
                {
                    continue;
                }

                if (attributePropertyValue.Equals(searchValue))
                {
                    return (TEnum)field.GetValue(null);
                }
            }

            return null;
        }
        #endregion
    }
}
Als Beantwoord = EnumExtensions.FromAttributeValueToEnum<Als>(typeof(StringValueAttribute), nameof(StringValueAttribute.Value), "Beantwoord");
public class IntValueAttribute : Attribute
{
    public IntValueAttribute(int value)
    {
        Value = value;
    }

    public int Value { get; private set; }
}

public enum EnumSample
{
    [Description("Eins")]
    [IntValue(1)]
    One,

    [Description("Zwei")]
    [IntValue(2)]
    Two,

    [Description("Drei")]
    [IntValue(3)]
    Three
}

EnumSample one = EnumExtensions.FromAttributeValueToEnum<EnumSample>(typeof(DescriptionAttribute), nameof(DescriptionAttribute.Description), "Eins");
EnumSample two = EnumExtensions.FromAttributeValueToEnum<EnumSample>(typeof(IntValueAttribute), nameof(IntValueAttribute.Value), 2);