65.9K
CodeProject 正在变化。 阅读更多。
Home

为枚举添加描述

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.41/5 (19投票s)

2006 年 4 月 17 日

CPOL

1分钟阅读

viewsIcon

125629

描述如何使用枚举上的 [Description] 属性

引言

你是否曾经希望为你的 enum 添加更具描述性的属性? 这里有一种方法。 让我们以一个非常简单的基于颜色的枚举 MyColors 为例。

using System;
using System.ComponentModel;
using System.Reflection;

public enum MyColors{
   White,
   Red,
   Green
}

如你所知,枚举由数字表示(请参阅此处的文档)。

如果你想关联文本,我们可以通过使用 System.ComponentModel.DescriptionAttribute 来实现。

using System;
using System.ComponentModel;
using System.Reflection;

public enum MyColors{
   [Description("The Color of my skin")]
   White,
   [Description("Bulls like this color")]
   Red,
   [Description("The color of slime")]
   Green
}

但是仅仅将此属性与我们的 enum 关联并没有帮助。 我们还需要一种访问该信息的方式。 通过使用反射,我们可以访问枚举的所有属性。 下面的代码描述了一个简单的访问器,它将检索每个枚举的描述。

public static string GetDescription(object enumValue, string defDesc){
        FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());
        
        if (null != fi)
        {
            object[] attrs = fi.GetCustomAttributes(typeof(DescriptionAttribute), true);
            if (attrs != null && attrs.Length > 0)
                return ((DescriptionAttribute)attrs[0]).Description;
        }

        return defDesc;
}

就这样了。 现在我们可以调用...

GetDescription(MyColor.Green)

...我们将从描述中获取文本。 就这么简单。

为了好玩,让我们编写一个方法来根据该 string 获取我们的 enum 。 注意:这可能对大多数人有用,但想象一下,我们定义了一个名为 [AssociatedUriAttribute] 的新属性,我们希望将一个唯一的 URI 与我们的 enum 关联。 这将打开很多可能性。 注意:这次我们将将其嵌入到基于泛型的类中。

public class EnumUtils<T>
{
    public static T FromDescription(string description){
        Type t = typeof(T);
        foreach (FieldInfo fi in t.GetFields())
        {
            object[] attrs = 
		fi.GetCustomAttributes(typeof(DescriptionAttribute), true);
            if (attrs != null && attrs.Length > 0)
            {
                foreach (DescriptionAttribute attr in attrs)
                {
                    if (attr.Description.Equals(description))
                        return (T)fi.GetValue(null);
                }
            }
        }
        return default(T);
}

最终,我们得到一个非常简单的类,如下所示

using System;
using System.ComponentModel;
using System.Reflection;

/// <summary>
/// enum utilities. 
/// - converts from a [Description(&quot;&quot;)] to an enum value
/// - grabs the [Description(&quot;&quot;)] from an enum value
/// 
/// </summary>
public class EnumUtils<T>
{
    public static string GetDescription(T enumValue, string defDesc){
        
        FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());
        
        if (null != fi)
        {
            object[] attrs = fi.GetCustomAttributes
					(typeof(DescriptionAttribute), true);
            if (attrs != null && attrs.Length > 0)
                return ((DescriptionAttribute)attrs[0]).Description;
        }

        return defDesc;
    }
    
    public static string GetDescription(T enumValue)
    {
        return GetDescription(enumValue, string.Empty);
    }

    public static T FromDescription(string description){
        Type t = typeof(T);
        foreach (FieldInfo fi in t.GetFields())
        {
            object[] attrs = fi.GetCustomAttributes
					(typeof(DescriptionAttribute), true);
            if (attrs != null && attrs.Length > 0)
            {
                foreach (DescriptionAttribute attr in attrs)
                {
                    if (attr.Description.Equals(description))
                        return (T)fi.GetValue(null);
                }
            }
        }
        return default(T);
    }
}

历史

  • 2006年4月17日:初始发布
© . All rights reserved.