Учитывая объект коллекции, хотел бы назначить локальную переменную определенного типа - PullRequest
0 голосов
/ 08 декабря 2011

Я бы хотел восстановить информацию о типах, используя отражение. У меня

public Foo(object coll, string tValue)
{
   var x = col1 as IList;
   if (x != null)
      x.Action();

   var y = col1 as IDictionary;
   if (y != null)
      y.Action();
}

Но хотелось бы иметь

public Foo(object coll, string tValue)
{
   var x = col1 as IList<TValue>;
   if (x != null)
      x.Action();

   var y = col1 as IDictionary<int, TValue>;
   if (y != null)
      y.Action();
}

Можно ли получить и использовать универсальные интерфейсы вместо неуниверсальных интерфейсов коллекции старой школы, учитывая только имя класса?

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

Другой пример, возможно, более понятный:

     var list = new Dictionary<int, MyObject>();
     list.Add(100, new MyObject());

     object listObject = list;

     var x = listObject as IDictionary<int, dynamic>;
     if (x != null)
     {
        foreach (var entry in x)
        {
           Console.WriteLine(entry.Key);
           Console.WriteLine(entry.Value);
        }
     }

х равен нулю ...

1 Ответ

2 голосов
/ 09 декабря 2011

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

Для вашего третьего блока кода выможет продолжать использовать неуниверсальный интерфейс и использовать перечислитель.

        var x = listObject as IDictionary;
        if (x != null)
        {
            var en = x.GetEnumerator();
            while(en.MoveNext())
            {
                Console.WriteLine(en.Key);
                Console.WriteLine(en.Value);
            }
        }

Если вы собираетесь вызывать метод, не зная точных универсальных типов для универсального IList или IDictionary, вам придется использоватьMethodInfo.Invoke.Кэшируйте MethodInfo вне цикла для небольшого повышения производительности.CreateDelegate будет быстрее, но вам нужно будет знать точные универсальные типы.Вы можете обойти это с деревьями выражений, но объем поддерживаемого кода может не стоить увеличения производительности.Проверьте MagicMethod в статье Джона Скитса Заставьте задуматься и исследуйте делегатов

...