Создание атрибута Description в поле перечисления с помощью System.Reflection.Emit - PullRequest
0 голосов
/ 22 мая 2010

У меня есть список строк, которые являются кандидатами для значений перечислений.Это

  • Не отправлять различий
  • 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
}

Затем, используя код, я получу реальную строку, связанную со значением перечисления,чтобы правильная строка могла быть отправлена ​​обратно в веб-сервис для получения правильного ресурса.

Я хочу знать, как создать DescriptionAttribute с использованием System.Reflection.Emit

По существу, вопросгде и как хранить исходную строку, чтобы при выборе значения перечисления можно было получить соответствующее значение.

Мне также интересно узнать, как получить доступ к DescriptionAttribute при необходимости.

Ответы [ 2 ]

2 голосов
/ 22 мая 2010

Хорошо, если вы действительно хотите использовать отражение:

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

Платформа TypeDescritor позволяет вам динамически предоставлять информацию о типе, а не фактически динамически декорировать типы напрямую - это слой косвенности.

Возможно, вы сможете изменить этот механизм для поддержки того, что вы хотите сделать, но в конце дня вам нужно будет выполнить поиск для ваших членов enum, чтобы предоставить строки описания. Использование структуры поиска для поддержания соответствия между членами enum и строкой описания было моим первым ответом и первым ответом на этот вопрос ...

0 голосов
/ 22 мая 2010

Вы можете написать общий метод, подобный этому:

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