C# – 获取通用列表的项类型

获取通用列表包含的项类型的最佳方法是什么? 抓取集合中的第一个项目并调用.GetType()很容易,但我不能总是确定集合中会有一个项目。

希望有道理。

谢谢,
桑尼

您可以使用Type.GetGenericArguments方法来实现此目的。

 List myList = ... Type myListElementType = myList.GetType().GetGenericArguments().Single(); 

对于更强大的方法:

 public static Type GetListType(object someList) { if (someList == null) throw new ArgumentNullException("someList"); var type = someList.GetType(); if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(List<>)) throw new ArgumentException("someList", "Type must be List<>, but was " + type.FullName); return type.GetGenericArguments()[0]; } 

但是如果您的变量是Type List那么您可以使用typeof(T) 。 例如:

 public static Type GetListType(List someList) { return typeof(T); } 

请注意,您甚至不需要someList参数。 如果您已经在generics方法中,此方法只是如何使用typeof的示例。 如果您无权访问T标记,则只需使用reflection方法(该列表存储在非generics类型变量中,例如一个类型化的IListobject等)。

 list.GetType().GetGenericArguments()[0] 

这是另一种适用于非generics集合的方法:

 static Type GetItemType(Type collectionType) { return collectionType.GetMethod("get_Item").ReturnType; } 

也就是说,获取foo[x]的返回类型,其中foo是指定类型。

例子:

 // Generic type; prints System.Int32 Console.WriteLine(GetItemType(typeof(List))); // Non-generic type; prints System.String Console.WriteLine(GetItemType(typeof(System.Collections.Specialized.StringCollection))); 

上面的GetItemType方法有几个问题,但是:

  • 如果类型没有索引运算符,则抛出NullReferenceException

  • 如果类型具有索引运算符的多个重载(例如this[string]this[int] ),则抛出AmbiguousMatchException

这是一个更精致的版本:

 public static Type GetItemType(this Type collectionType) { var types = (from method in collectionType.GetMethods() where method.Name == "get_Item" select method.ReturnType ).Distinct().ToArray(); if (types.Length == 0) return null; if (types.Length != 1) throw new Exception(string.Format("{0} has multiple item types", collectionType.FullName)); return types[0]; } 

那么这个,它的全部是静态的(例如没有实例需要),快速(没有循环,没有使用linq),而且很简单:)这些工作集合:

  [System.Diagnostics.DebuggerHidden] public static Type GetIndexedType(this ICollection poICollection) { PropertyInfo oPropertyInfo = poICollection == null ? null : poICollection.GetType().GetProperty("Item"); return oPropertyInfo == null ? null : oPropertyInfo.PropertyType; } [System.Diagnostics.DebuggerHidden] public static Type GetEnumeratedType(this ICollection poICollection) { PropertyInfo oPropertyInfo = poICollection == null ? null : poICollection.GetType().GetMethod("GetEnumerator").ReturnType.GetProperty("Current"); return oPropertyInfo == null ? null : oPropertyInfo.PropertyType; } 

还有一些简单的unit testing:

  [Test] public void GetIndexedType() { Assert.AreEqual(null, ((ICollection)null).GetIndexedType()); Assert.AreEqual(typeof(int), (new List()).GetIndexedType()); Assert.AreEqual(typeof(bool), (new SortedList()).GetIndexedType()); } [Test] public void GetEnumeratedType() { Assert.AreEqual(null, ((ICollection)null).GetEnumeratedType()); Assert.AreEqual(typeof(int), (new List()).GetEnumeratedType()); Assert.AreEqual(typeof(KeyValuePair), (new SortedList()).GetEnumeratedType()); } 

请注意,有两种方法可以查看它,索引器可以返回一种类型,枚举器可以返回另一种类型。 unit testing确实显示了两者。

玩得开心,弗兰斯。

Ps对于可枚举:

  [System.Diagnostics.DebuggerHidden] public static Type GetEnumeratedType(this System.Collections.IEnumerable poIEnumerable) { PropertyInfo oPropertyInfo = poIEnumerable == null ? null : poIEnumerable.GetType().GetMethod("GetEnumerator").ReturnType.GetProperty("Current"); return oPropertyInfo == null ? null : oPropertyInfo.PropertyType; } 

对于调查员:

  [System.Diagnostics.DebuggerHidden] public static Type GetEnumeratedType(this System.Collections.IEnumerator poIEnumerator) { PropertyInfo oPropertyInfo = poIEnumerator == null ? null : poIEnumerator.GetType().GetProperty("Current"); return oPropertyInfo == null ? null : oPropertyInfo.PropertyType; } 
 Public Shared Function ListItemType(ListType As System.Type) As System.Type If Not ListType.IsGenericType Then If ListType.BaseType IsNot Nothing AndAlso ListType.BaseType.IsGenericType Then Return ListItemType(ListType.BaseType) End If Else Return ListType.GetGenericArguments.Single End If End Function 

旧问题dynamic新方法

 void Foo(){ Type type GetTypeT(data as dynamic); } private static Type GetTypeT(IEnumerable data) { return typeof(T); } 
  public Type GetType(IEnumerable resultList) { return resultList.GetType().GetElementType(); }