从IEnumerable <T>获得typesT.

有没有办法通过reflection从IEnumerable<T>检索typesT

例如

我有一个variablesIEnumerable<Child>信息; 我想通过reflection来检索孩子的types

 IEnumerable<T> myEnumerable; Type type = myEnumerable.GetType().GetGenericArguments()[0]; 

正是如此,

 IEnumerable<string> strings = new List<string>(); Console.WriteLine(strings.GetType().GetGenericArguments()[0]); 

打印System.String

请参阅MSDN的Type.GetGenericArguments

编辑:我相信这将解决在评论中的关注:

 // returns an enumeration of T where o : IEnumerable<T> public IEnumerable<Type> GetGenericIEnumerables(object o) { return o.GetType() .GetInterfaces() .Where(t => t.IsGenericType == true && t.GetGenericTypeDefinition() == typeof(IEnumerable<>)) .Select(t => t.GetGenericArguments()[0]); } 

一些对象实现多个genericsIEnumerable因此有必要返回它们的枚举。

编辑:虽然,我不得不说,一个类实现多个IEnumerable<T>是一个可怕的想法。

我只是做一个扩展方法。 这一切与我扔在它的一切。

 public static Type GetItemType<T>(this IEnumerable<T> enumerable) { return typeof(T); } 

如果你知道IEnumerable<T> (通过generics),那么typeof(T)应该工作。 否则(对于object ,或非genericsIEnumerable ),请检查实现的接口:

  object obj = new string[] { "abc", "def" }; Type type = null; foreach (Type iType in obj.GetType().GetInterfaces()) { if (iType.IsGenericType && iType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { type = iType.GetGenericArguments()[0]; break; } } if (type != null) Console.WriteLine(type); 

我有一个类似的问题。 所选答案适用于实际情况。 在我的情况下,我只有一个types(来自PropertyInfo )。

当types本身是typeof(IEnumerable<T>)而不是typeof(IEnumerable<T>)的实现时,所选答案失败。

对于这种情况下面的工作:

 public static Type GetAnyElementType(Type type) { // Type is Array // short-circuit if you expect lots of arrays if (type.IsArray) return type.GetElementType(); // type is IEnumerable<T>; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof (IEnumerable<>)) return type.GetGenericArguments()[0]; // type implements/extends IEnumerable<T>; var enumType = type.GetInterfaces() .Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>)) .Select(t => t.GenericTypeArguments[0]).FirstOrDefault(); return enumType ?? type; } 

考虑对选定的答案进行投票,如果你觉得这个代码有用的话。

非常感谢您的讨论。 我用它作为下面的解决scheme的基础,这适用于我感兴趣的所有情况(IEnumerable,派生类等)。 以为我应该在这里分享以防万一任何人需要它也:

  Type GetItemType(object someCollection) { var type = someCollection.GetType(); var ienum = type.GetInterface(typeof(IEnumerable<>).Name); return ienum != null ? ienum.GetGenericArguments()[0] : null; } 

只要使用typeof(T)

编辑:或使用.GetType()。GetGenericParameter()对实例化的对象,如果你没有T.

对于更简单的情况来说,它可能是一个IEnumerable<T>T -note使用GenericTypeArguments而不是GetGenericArguments()

 Type inputType = o.GetType(); Type genericType; if ((inputType.Name.StartsWith("IEnumerable")) && ((genericType = inputType.GenericTypeArguments.FirstOrDefault()) != null)) { return genericType; } else { return inputType; } 

typeof(IEnumerable<Foo>)GetGenericArguments() [0]将返回第一个generics参数 – 在这种情况下, typeof(Foo)

这是对Eli Algranti的解决scheme的改进,因为它也可以在inheritance树中IEnumerable<>types的任何级别上工作。

此解决scheme将从任何Type获取元素Type 。 如果该types不是IEnumerable<> ,则它将返回传入的types。对于对象,请使用GetType 。 对于types,使用typeof ,然后在结果上调用这个扩展方法。

 public static Type GetGenericElementType(this Type type) { // Short-circuit for Array types if (typeof(Array).IsAssignableFrom(type)) { return type.GetElementType(); } while (true) { // Type is IEnumerable<T> if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { return type.GetGenericArguments().First(); } // Type implements/extends IEnumerable<T> Type elementType = (from subType in type.GetInterfaces() let retType = subType.GetGenericElementType() where retType != subType select retType).FirstOrDefault(); if (elementType != null) { return elementType; } if (type.BaseType == null) { return type; } type = type.BaseType; } }