从IEnumerable <T>获取类型T.

Usm*_*ood 98 c# generics reflection

有没有一种方法来检索类型TIEnumerable<T>通过反射?

例如

我有一个可变IEnumerable<Child>信息; 我想通过反射检索Child的类型

jas*_*son 133

IEnumerable<T> myEnumerable;
Type type = myEnumerable.GetType().GetGenericArguments()[0]; 
Run Code Online (Sandbox Code Playgroud)

正是如此,

IEnumerable<string> strings = new List<string>();
Console.WriteLine(strings.GetType().GetGenericArguments()[0]);
Run Code Online (Sandbox Code Playgroud)

打印System.String.

请参阅MSDNType.GetGenericArguments.

编辑:我相信这将解决评论中的问题:

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

有些对象实现了多个泛型,IEnumerable因此必须返回它们的枚举.

编辑:虽然,我不得不说,一个班级实施IEnumerable<T>不止一个课程是一个糟糕的主意T.

  • 当您使用数组时,这会失败,该数组会强制转换为 IEnumerable (2认同)

小智 38

我只是做一个扩展方法.这适用于我投入的一切.

public static Type GetItemType<T>(this IEnumerable<T> enumerable)
{
    return typeof(T);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您的编译时引用只是类型对象,它将无法工作. (4认同)

Eli*_*nti 24

我遇到了类似的问题.所选答案适用于实际实例.就我而言,我只有一种类型(来自a PropertyInfo).

当类型本身typeof(IEnumerable<T>)不是实现时,所选答案将失败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;
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 19

如果你知道IEnumerable<T>(通过泛型),那么就typeof(T)应该工作.否则(for object或non-generic IEnumerable),检查实现的接口:

        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);
Run Code Online (Sandbox Code Playgroud)

  • @Jason - 在这种情况下,"找到T"的问题已经是一个可疑的问题; 我对此无能为力...... (5认同)
  • 一些对象实现了多个通用的IEnumerable. (3认同)

小智 7

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

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