简体   繁体   English

使用System.Reflection.Emit在枚举字段上创建DescriptionAttribute

[英]Creating DescriptionAttribute on Enumeration Field using System.Reflection.Emit

I have a list of strings which are candidates for Enumerations values. 我有一个字符串列表,这些字符串是Enumerations值的候选者。 They are 他们是

  • Don't send diffs 不要发送差异
  • 500 lines 500线
  • 1000 lines 1000线
  • 5000 lines 5000线
  • Send entire diff 发送整个差异

The problem is that spaces, special characters are not a part of identifiers and even cannot start with a number, so I would be sanitizing these values to only chars, numbers and _ 问题是空格,特殊字符不是标识符的一部分,甚至不能以数字开头,因此我将把这些值消毒为仅char,数字和_

To keep the original values I thought of putting these strings in the DescriptionAttribute, such that the final Enum should look like 为了保留原始值,我想到了将这些字符串放入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
}

Then later using code I will retrieve the real string associated with the enumeration value, so that the correct string can be sent back the web service to get the correct resource. 然后,稍后使用代码,我将检索与枚举值关联的实际字符串,以便可以将正确的字符串发送回Web服务以获得正确的资源。

I want to know how to create the DescriptionAttribute using System.Reflection.Emit 我想知道如何使用System.Reflection.Emit创建DescriptionAttribute

Basically the question is where and how to store the original string so that when the Enumeration value is chosen, the corresponding value can be retrieved. 基本上,问题是在何处以及如何存储原始字符串,以便在选择Enumeration值时可以检索到相应的值。

I am also interested in knowing how to access DescriptionAttribute when needed. 我也想知道如何在需要时访问DescriptionAttribute

Ok, if you really want to use reflection: 好的,如果您真的想使用反射:

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

$> Don't send diffs $>不要发送差异

Obviously there is no error handling, etc, but the basic idea is there. 显然没有错误处理等,但是基本思想就在那里。

Update 更新

I now think I see the point of your question, which myself and the other people that answered actually missed. 我现在认为我明白了您的问题的要点,我本人和其他回答者实际上都没有理会。

You want to decorate an enum with attributes at runtime ie add attributes to a type at runtime. 您想在运行时用属性修饰枚举,即在运行时将属性添加到类型。 Adding attributes to a type at runtime is not possible. 无法在运行时将属性添加到类型。

However these is support in the .Net for a type metadata engine via : TypeDescritor : 但是,.Net通过以下类型为类型元数据引擎提供以下支持: TypeDescritor

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

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

The TypeDescritor framework allows you to dynamically provide type information rather than actually dynamically decorating types directly - it is a layer of indirection. TypeDescritor框架允许您动态提供类型信息,而不是实际直接动态修饰类型-它是一个间接层。

You may be able to bend this mechanism to support what you want to do, but at the end of the day you will need to maintain a lookup for your enum members to provide the description strings. 您也许可以改变这种机制来支持您想要做的事情,但是最终,您将需要维护枚举成员的查找以提供描述字符串。 Using a lookup structure to maintain a mapping between your enum members and description string was my first answer and the first answer to this question... 使用查找结构维护枚举成员和描述字符串之间的映射是我的第一个答案,也是对此问题的第一个答案...

You could write a generic method like this: 您可以编写这样的通用方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM