2014-01-17 2 views
0

я могу получить вид непустым списка:C# типа пустого списка

private Type GetListType(IEnumerable list) 
{ 
    return list.GetType().GetGenericArguments()[0]; 
} 

Как я могу получить вид пустого списка?

private Type GetListType(IEnumerable list) 
{ 
... 
} 
+0

Это же, если список инициализирован. Если вы спрашиваете, как получить тип, когда list == null, то у вас нет типа. – paqogomez

+1

Обратите внимание, что ваш код багги: попробуйте 'GetListType (новый ArrayList());' –

ответ

5

Ваш код также работает для пустых списков. [0] является указателем на массив аргументов типа, возвращаемых вызовом GetGenericArguments, а не содержимым вашего списка.

+7

Если бы у него был способ проверить его, прежде чем спрашивать ... :) – tnw

4

Код, который у вас есть, например, в

GetListType(new List<string>()); // typeof(string) 

Он не будет работать, если тип выполнения не имеет общего параметра, например.

public class MyList : List<SomeObject> { } 
GetListType(new MyList()); // there is no 0'th generic argument! 

Или это не может вернуть то, что вы ожидаете:

GetListType(new Dictionary<string, int>()); // typeof(string) 
// even though it ought to be KeyValuePair<string, int> 

Может быть, вы должны использовать это вместо того, чтобы:

private Type GetListType<T>(IEnumerable<T> list) 
{ 
    return typeof(T); 
} 

Самым большим недостатком этого является то, что ваш тип должен реализовывать IEnumerable<T>, а не только IEnumerable (но если вы хотите получить полезный тип из пустого списка, ему все равно придется это сделать или иначе объявить его тип).

0

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

class IntList : List<int> { } 

GetListType(new List<int>()) // Works 
GetListType(new IntList()) // Fails 

Тип IntList не имеют общих параметров, следовательно, операция индекса [0] потерпит неудачу.

Чтобы сделать реализацию более общего назначения, вы должны выбрать конкретный интерфейс или тип класса, в котором запрашивается общий параметр. Я бы порекомендовал IEnumerable<T>.

static Type GetListType(IEnumerable enumerable) 
{ 
    var type = enumerable.GetType(); 
    var enumerableType = type 
     .GetInterfaces() 
     .Where(x => x.GetGenericTypeDefinition() == typeof(IEnumerable<>)) 
     .First(); 
    return enumerableType.GetGenericArguments()[0]; 
} 
Смежные вопросы