【问题标题】:Creating DescriptionAttribute on Enumeration Field using System.Reflection.Emit使用 System.Reflection.Emit 在枚举字段上创建 DescriptionAttribute
【发布时间】:2010-05-22 15:46:05
【问题描述】:

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

  • 不要发送差异
  • 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 服务以获取正确的资源。

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

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

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

【问题讨论】:

  • 你为什么要问关于使用 relection.emit 添加属性,即在运行时添加属性?在上面的示例中,您直接在代码中添加了属性。
  • 我的意思是,我想要这样的东西。如果您构建一个包含此代码部分的项目,它应该与使用 Reflection.Emit 创建的相同

标签: c# .net reflection enums reflection.emit


【解决方案1】:

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

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 中通过以下方式支持类型元数据引擎:TypeDecritor

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 框架允许您动态提供类型信息,而不是直接动态地装饰类型 - 它是一个间接层。

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

【讨论】:

  • 谢谢!这是用于访问属性,但仍然无法找到添加属性的方法。
  • 我想大家都误解了你的问题。问题中的枚举代码已经应用了属性。您想在运行时添加属性吗?
  • 另外,如果你喜欢目前的答案,投票可能会激励...... :)
  • 我的意思是这应该是我在问题中提出的最终输出。使用反射,应该创建枚举,将DescriptionAttribute 添加到每个条目,我应该能够使用这个枚举以及它的描述。
【解决方案2】:

你可以这样写一个通用方法:

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-10-22
    • 1970-01-01
    • 1970-01-01
    • 2013-11-25
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多