C#generics列表<T>如何获取T的types?

我正在做一个reflection项目,现在我卡住了。 如果我有一个可以容纳一个List的“myclass”对象,如果属性myclass.SomList是空的,任何人都知道如何获得下面的代码中的types?

List<myclass> myList = dataGenerator.getMyClasses(); lbxObjects.ItemsSource = myList; lbxObjects.SelectionChanged += lbxObjects_SelectionChanged; private void lbxObjects_SelectionChanged(object sender, SelectionChangedEventArgs e) { Reflect(); } Private void Reflect() { foreach (PropertyInfo pi in lbxObjects.SelectedItem.GetType().GetProperties()) { switch (pi.PropertyType.Name.ToLower()) { case "list`1": { // This works if the List<T> contains one or more elements. Type tTemp = GetGenericType(pi.GetValue(lbxObjects.SelectedItem, null)); // but how is it possible to get the Type if the value is null? // I need to be able to create a new object of the type the generic list expect. // Type type = pi.getType?? // how to get the Type of the class inside List<T>? break; } } } } private Type GetGenericType(object obj) { if (obj != null) { Type t = obj.GetType(); if (t.IsGenericType) { Type[] at = t.GetGenericArguments(); t = at.First<Type>(); } return t; } else { return null; } } 
 Type type = pi.PropertyType.PropertyType; if(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) { Type itemType = type.GetGenericArguments()[0]; // use this... } 

更一般地说,要支持任何IList<T> ,您需要检查接口:

 foreach (Type interfaceType in type.GetInterfaces()) { if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IList<>)) { Type itemType = type.GetGenericArguments()[0]; // do something... break; } } 

给定一个我怀疑是某种IList<>的对象,我怎么能确定它是什么 IList<>

这是勇敢的解决scheme。 它假定你有实际的对象来testing(而不是一个Type )。

 public static Type ListOfWhat(Object list) { return ListOfWhat2((dynamic)list); } private static Type ListOfWhat2<T>(IList<T> list) { return typeof(T); } 

用法示例:

 object value = new ObservableCollection<DateTime>(); ListOfWhat(value).Dump(); 

打印

 typeof(DateTime) 

Marc的答案是我为此使用的方法,但为了简单(和更友好的API?),您可以在集合基类中定义一个属性,如果您有一个如:

 public abstract class CollectionBase<T> : IList<T> { ... public Type ElementType { get { return typeof(T); } } } 

我发现这种方法很有用,并且对于任何新来的generics客户来说都很容易理解。

给定一个我怀疑是某种IList<>的对象,我怎么能确定它是什么 IList<>

这是一个可靠的解决scheme。 我对长度表示歉意–C#的内省API令人惊讶地困难。

 /// <summary> /// Test if a type implements IList of T, and if so, determine T. /// </summary> public static bool TryListOfWhat(Type type, out Type innerType) { Contract.Requires(type != null); var interfaceTest = new Func<Type, Type>(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>) ? i.GetGenericArguments().Single() : null); innerType = interfaceTest(type); if (innerType != null) { return true; } foreach (var i in type.GetInterfaces()) { innerType = interfaceTest(i); if (innerType != null) { return true; } } return false; } 

用法示例:

  object value = new ObservableCollection<int>(); Type innerType; TryListOfWhat(value.GetType(), out innerType).Dump(); innerType.Dump(); 

返回

 True typeof(Int32)