0

我有一个字符串列表,这些字符串是枚举值的候选者。他们是

  • 不要发送差异
  • 500行
  • 1000 行
  • 5000 行
  • 发送整个差异

问题是空格、特殊字符不是标识符的一部分,甚至不能以数字开头,所以我会将这些值清理为仅字符、数字和 _

为了保留原始值,我想将这些字符串放在 DescriptionAttribute 中,这样最终的值Enum应该像

public enum DiffBehvaiour
{ 
    [Description("Don't send diffs")]
    Dont_send_diffs,
    [Description("500 lines")]
    Diff_500_lines,
    [Description("1000 lines")]
    Diff_1000_lines,
    [Description("5000 lines")]
    Diff_5000_lines,
    [Description("Send entire diff")]
    Send_entire_diff
}

然后稍后使用代码我将检索与枚举值关联的真实字符串,以便可以将正确的字符串发送回 Web 服务以获取正确的资源。

我想知道如何创建DescriptionAttribute使用 System.Reflection.Emit

基本上问题是在哪里以及如何存储原始字符串,以便在选择 Enumeration 值时,可以检索相应的值。

我也有兴趣知道如何DescriptionAttribute 在需要时访问。

4

2 回答 2

2

好的,如果你真的想使用反射:

DiffBehvaiour value = DiffBehvaiour.Dont_send_diffs;

FieldInfo enumField = value.GetType().GetField(value.ToString());

DescriptionAttribute attribute = (DescriptionAttribute)enumField.
    GetCustomAttributes(typeof(DescriptionAttribute), true)[0];

Console.WriteLine(attribute.Description);

$> 不发送差异

显然没有错误处理等,但基本思想是有的。

更新

我现在想我明白了你的问题的重点,我自己和其他回答的人实际上都错过了。

您想在运行时用属性装饰枚举,即在运行时向类型添加属性。无法在运行时向类型添加属性。

但是,这些是 .Net 中对类型元数据引擎的支持,方法是:TypeDescritor

MSDN http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptor.aspx

示例http://geekswithblogs.net/abhijeetp/archive/2009/01/10/dynamic-attributes-in-c.aspx

TypeDecritor 框架允许您动态地提供类型信息,而不是直接动态地装饰类型——它是一个间接层。

您可能可以弯曲此机制以支持您想要做的事情,但最终您需要维护枚举成员的查找以提供描述字符串。使用查找结构来维护枚举成员和描述字符串之间的映射是我的第一个答案,也是这个问题的第一个答案......

于 2010-05-22T17:19:34.680 回答
0

您可以编写这样的通用方法:

class EnumExtensions
{
     public static string GetDescription<TEnum>(TEnum value)
         // inexpressible generic constraint TEnum : System.Enum
     {
         // reflection lookup of this value per @chibacity answer
     }

     public static IDictionary<TEnum,string> GetDescriptions<TEnum>()
         // inexpressible generic constraint TEnum : System.Enum
     {
         // do the reflection lookups once and build a dictionary
         var result = new Dictionary<TEnum, string>();

         foreach(string name in Enum.GetNames(typeof(TEnum))
         {
             var value = (TEnum)Enum.Parse(typeof(TEnum), name);
             var description = GetDescription(value);

             result.Add(value, description);
         }

         return result;
     }
}
于 2010-05-22T18:01:46.040 回答