C #, используйте отражение, чтобы получить каждое имя дела в switch

1

Здесь надуманный пример оператора строкового литерала:

static string GetStuff(string key)
{
    switch (key)
    {
        case "thing1": return "oh no";
        case "thing2": return "oh yes";
        case "cat": return "in a hat";
        case "wocket": return "in my pocket";
        case "redFish": return "blue fish";
        case "oneFish": return "two fish";
        default: throw new NotImplementedException("The key '" + key + "'  does not exist, go ask your Dad");
    }
}

Вы поняли эту идею.

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

Я не сделал достаточно с размышлениями, чтобы знать, как сделать это интуитивно. Я, честно говоря, не уверен, что рефлексия может вообще что-то делать.

Это можно сделать? Если да, то как?

  • 1
    Reflection предназначен для просмотра информации об объектах, то есть классах, свойствах, методах и т. Д. Код внутри этих вещей не может быть отражен. Посмотрите на Шаблон посетителя: en.wikipedia.org/wiki/Visitor_pattern
  • 1
    К сожалению, связанные вопросы и ответы здесь не уточняются. Это до сих пор не ясно , что вы имеете в виду под «инициализируется во время компиляции», и ответ дан в этой ссылке конкретно указывает на то , что я упоминал ранее, что в том , что если у вас есть достаточное количество case меток (IIRC, порог семь или более) код просто превращается в словарь в любом случае. Чего вы пытаетесь достичь здесь, чего не можете достичь с помощью реального словаря?
Показать ещё 2 комментария
Теги:
reflection
switch-statement

2 ответа

5
Лучший ответ

Нет, вы не можете читать IL (именно это и ищете) с помощью Reflection API.

Ближайший вы можете прийти в MethodInfo.GetMethodBody (MethodBody класс), который даст вам байтовый массив с IL. Чтобы получить детали реализации метода, вам нужна библиотека, которая читает IL как cecil.

switch для string реализуется с использованием if или Dictionary на основе количества вариантов - см. Операторы switch.Net, хэшированные или индексированные? , Поэтому, если вы читаете IL, учтите это. *

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

* информация о реализации switch найденная Mad Sorcerer.

  • 0
    Это то, что мне было интересно. Я согласен, что другой метод - лучший способ хранения информации. Но это не то, что я спрашивал.
  • 1
    @colepanike Не самая простая задача. Обратитесь к этому, чтобы увидеть некоторые детали реализации switch IL. Я бы использовал Dictionary вместо синтаксического анализа тела метода.
Показать ещё 1 комментарий
2

Как насчет использования Dictionary

  Dictionary<string, string> dict = new Dictionary<string, string>();
  dict.Add("thing1", "oh no");
  dict.Add("thing2", "oh yes");
  //and on and on

  string GetStuff(string key)
  {
    if (dict.ContainsKey(key))
      return dict[key];
    else
      return null; //or throw exception
  }

Для вашего меню:

 void addToMenu()
 {
   foreach (string key in dict.Keys)
   {
     //add "key" to menu
   }

 }
  • 0
    Вы могли бы даже использовать более короткий синтаксис инициализатора: new Dictionary<string, string> { { "thing1", "oh no" }, { "thing2", "oh yes" } } и TryGetValue
  • 0
    Причиной, по которой я не использую словарь, является ограничение времени компиляции. Я выбрал этот по общему признанию довольно уродливый синтаксис, потому что Dictionary не может быть сделан во время компиляции.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню