键值对作为枚举

时间:2011-02-08 10:41:35

标签: c# .net enums

我可以使用作为键值对的枚举。

public enum infringementCategory
{ 
    Infringement,
    OFN
}

如果我选择Infringement我应该获得“INF0001”,如果我选择OFN我应该获得“INF0002”

有可能吗?

6 个答案:

答案 0 :(得分:7)

这些扩展如何:

public static class EnumExtension
{
    /// <summary>
    /// Gets the string of an DescriptionAttribute of an Enum.
    /// </summary>
    /// <param name="value">The Enum value for which the description is needed.</param>
    /// <returns>If a DescriptionAttribute is set it return the content of it.
    /// Otherwise just the raw name as string.</returns>
    public static string Description(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;
    }

    /// <summary>
    /// Creates an List with all keys and values of a given Enum class
    /// </summary>
    /// <typeparam name="T">Must be derived from class Enum!</typeparam>
    /// <returns>A list of KeyValuePair&lt;Enum, string&gt; with all available
    /// names and values of the given Enum.</returns>
    public static IList<KeyValuePair<Enum, string>> ToList<T>() where T : struct
    {
        var type = typeof(T);

        if (!type.IsEnum)
        {
            throw new ArgumentException("T must be an enum");
        }

        return (IList<KeyValuePair<Enum, string>>)
                Enum.GetValues(type)
                    .OfType<Enum>()
                    .Select(e => new KeyValuePair<Enum, string>(e, e.Description()))
                    .ToArray();
    }

    public static T GetValueFromDescription<T>(string description) where T : struct
    {
        var type = typeof(T);

        if(!type.IsEnum)
        {
            throw new ArgumentException("T must be an enum");
        }

        foreach(var field in type.GetFields())
        {
            var attribute = Attribute.GetCustomAttribute(field,
                typeof(DescriptionAttribute)) as DescriptionAttribute;

            if(attribute != null)
            {
                if(attribute.Description == description)
                {
                    return (T)field.GetValue(null);
                }
            }
            else
            {
                if(field.Name == description)
                {
                    return (T)field.GetValue(null);
                }
            }
        }

        throw new ArgumentOutOfRangeException("description");
        // or return default(T);
    }
}

有了这个,你可以像这样建立你的枚举:

public enum Foo
{
    [Description("Foo - Something")]
    Something,
    [Description("Foo - Anything")]
    Anything,
}

得到你的清单:

var list = EnumExtension.ToList<Foo>();

答案 1 :(得分:6)

您可以使用装饰器将字符串表示与您的枚举值相关联。请检查此问题:Enum ToString with user friendly strings

看起来像:

public enum infringementCategory
{ 
    [Description("INF0001")]
    Infringement,
    [Description("INF0002")]
    OFN
}

看起来比使用Dictionary更整洁,需要更少的维护。

答案 2 :(得分:2)

您可以将标题(INF0001)...存储在Dictionary<infringementCategory, string>

答案 3 :(得分:2)

<强>更新
感谢Oliver指出System.Component.DescriptionAttribute。这是如何做到的:

public enum infringementCategory
{
    [Description("INF0001")]
    Infringement,
    [Description("INF0002")]
    OFN
}

public static class DescriptionExtensions
{
    public static string GetDescriptionValue(this Enum value)
    {
        // Get the type
        Type type = value.GetType();

        // Get fieldinfo for this type
        FieldInfo fieldInfo = type.GetField(value.ToString());

        // Get the stringvalue attributes
        DescriptionAttribute[] attribs = fieldInfo.GetCustomAttributes(
            typeof(DescriptionAttribute), false) as DescriptionAttribute[];

        // Return the first if there was a match.
        return attribs.Length > 0 ? attribs[0].Description : null;
    }
}

public class Program
{
    static void Main(string[] args)
    {
        infringementCategory category = infringementCategory.OFN;
        string description = category.GetDescriptionValue();
    }
}

答案 4 :(得分:2)

请参阅:

public enum InfringementCategory
{
    [EnumNamedConstant(Description = "INF0001")]
    Infringement,

    [EnumNamedConstant(Description = "INF0002")]
    OFN
}

public class Test{
    public void Test()
    {
        String result = InfringementCategory.Infringement.GetDescription();
    }
}

这里有扩展方法......

#region [ EnumNamedConstantAttribute ]
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class EnumNamedConstantAttribute : Attribute
{
    public string Description { get; set; }
    public string Value { get; set; }
}
#endregion


#region EnumUtilities
public static class EnumUtilities
{
    #region [ + Extension Methods ]

    #region [ GetDescription ]

    public static string GetDescription(this Enum constant)
    {
        return EnumUtilities.GetEnumNamedConstantAttribute(constant).Description;
    }
    #endregion

    #region [ GetStringValue ]

    public static string GetStringValue(this Enum constant)
    {
        return GetEnumNamedConstantValue(constant);
    }
    #endregion

    #endregion

    #region [ + Static Methods ]

    #region [ GetEnumerable ]

    public static IEnumerable<EnumNamedConstantAttribute> GetEnumerable<T>()
    {
        T instancia = Activator.CreateInstance<T>();

        FieldInfo[] objInfos = instancia.GetType().GetFields(BindingFlags.Public | BindingFlags.Static);
        foreach (FieldInfo objFileInfo in objInfos)
        {
            Enum constant = (Enum)objFileInfo.GetValue(objFileInfo);
            if (objFileInfo.GetCustomAttributes(typeof(EnumNamedConstantAttribute), false).Length != 0)
            {
                yield return new EnumNamedConstantAttribute()
                {
                    Description = EnumUtilities.GetEnumNamedConstantAttribute(constant).Description,
                    Value = GetEnumNamedConstantValue(constant)
                };
            }
        }
    }
    #endregion

    #endregion

    #region [ + Privates ]

    #region [ GetEnumNamedConstantAttribute ]
    private static EnumNamedConstantAttribute GetEnumNamedConstantAttribute(Enum constant)
    {
        FieldInfo[] objInfos = constant.GetType().GetFields(BindingFlags.Public | BindingFlags.Static);
        foreach (FieldInfo objFileInfo in objInfos)
        {
            Enum constantItem = (Enum)objFileInfo.GetValue(objFileInfo);
            if (constantItem.GetHashCode().Equals(constant.GetHashCode()))
            {
                object[] attributes = objFileInfo.GetCustomAttributes(typeof(EnumNamedConstantAttribute), false);

                if (attributes.Length > 0)
                    return (EnumNamedConstantAttribute)attributes[0];
            }
        }
        return null;
    }
    #endregion

    #region [ GetEnumNamedConstantValue ]
    private static string GetEnumNamedConstantValue(Enum constant)
    {
        string sValue = (constant.GetHashCode()).ToString();
        EnumNamedConstantAttribute objRet = EnumUtilities.GetEnumNamedConstantAttribute(constant);
        if (objRet != null)
        {
            String sAux = objRet.Value;
            if (!String.IsNullOrEmpty(sAux))
                sValue = objRet.Value;
        }
        return sValue;
    }
    #endregion

    #endregion
}
#endregion

答案 5 :(得分:-1)

您有多种选择:

  1. 建议使用vc74字典。这是有效的,并将您的枚举与财产分离。

  2. 转换声明

  3. 如果您想要唯一关联的是整数,则可以使用:

     public enum InfringementCategory
     { 
         Infringement = 1,
         OFN = 2
     }
    

    然后将(int)myEnum放入String.Format,将其转换为所需格式的字符串。

  4. 属性

    public enum InfringementCategory
    { 
        [InfID("INF0001")]Infringement,
        [InfID("INF0002")]OFN
    }
    

    为了提高性能,您可以使用反射一次填充字典。