Получить строго типизированный тип данных элемента списка?

#list #generics #.net-4.0

#Список #generics #.net-4.0

Вопрос:

Допустим, у меня есть List<object> , который передается в класс в качестве аргумента, этот список должен содержать кучу моделей для моего приложения, все одного типа. Возможно ли мне каким-то образом получить тип списка, который был передан? (без вызова GetType() элемента в списке).

Например, я передаю List<User> который хранится как List<object> , могу ли я теперь извлечь тип User из списка, не выполняя что-то вроде:

 List<object> aList;
aList[0].GetType();
  

Ответ №1:

Ну, вы можете использовать:

 Type elementType = aList.GetType().GetGenericArguments[0];
  

Однако это приведет к сбою, если вы передадите, например, FooList который является производным от List<Foo> . Вы могли бы обойти иерархию типов и соответствующим образом разобраться таким образом, но это было бы затруднительно.

Если это вообще возможно, было бы лучше вместо этого использовать дженерики во всем вашем коде, потенциально делая существующие методы универсальными — например, вместо:

 public void Foo(List<object> list)
  

у вас было бы

 public void Foo<T>(List<T> list)
  

или даже

 public void Foo<T>(IList<T> list)
  

Если вам это просто нужно для очень конкретного случая, когда тип времени выполнения всегда будет точно List<T> для некоторого списка, тогда использование GetGenericArguments сработает … но это не очень приятно.

Ответ №2:

Насколько я понимаю, цель generics — не выполнять проверку типа вручную. Компилятор гарантирует, что элементы в списке соответствуют типу, за который они себя выдают, и, следовательно, получаемые элементы будут именно такого типа.

Если у вас есть List<object> , вы вообще лишаете смысла использовать generics. List<object> — это список, в котором может храниться объект любого типа, независимо от того, какие типы вы в него фактически ввели. Следовательно, на вас лежит ответственность за определение фактического типа извлекаемого вами объекта.

Короче говоря: вы должны использовать GetType .