在泛型 List<T> 中获取 T 的实际类型

5

如何使用反射在运行时获取泛型List中T的实际类型?


你的当前代码是什么样子?一些上下文会有所帮助。 - Nick Craver
可能是C#泛型列表<T>如何获取T的类型?的重复问题。 - nawfal
4个回答

9

这要看你具体在问什么:

  • While writing code inside a generic type Blah<T>, how do I get the reflection type T?

    Answer: typeof(T)

  • I have an object which contains a List<T> for some type T. How do I retrieve the type T via reflection?

    Short answer: myList.GetType().GetGenericArguments()[0]

    Long answer:

    var objectType = myList.GetType();
    if (!objectType.IsGenericType() ||
        objectType.GetGenericTypeDefinition() != typeof(List<>))
    {
        throw new InvalidOperationException(
            "Object is not of type List<T> for any T");
    }
    var elementType = objectType.GetGenericArguments()[0];
    

顺便提一下 - 如果"myList"不是一个泛型类型,此操作将抛出GetGenericTypeDefinition()异常...如果你要加入错误检查,也应该包括对IsGenericType的检查。 - Reed Copsey

2
您可以使用Type.GetGenericArguments方法来返回 List<T> 中的类型T。
例如,对于传递作为参数的任何List<T>,此方法将返回其类型。
Type GetListType(object list)
{
    Type type = list.GetType();
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
        return type.GetGenericArguments()[0];
    else
        throw new ArgumentException("list is not a List<T>", "list");
}

并不是很有用:你只能传递一个在编译时已知类型的对象。 - Timwi
@Timwi:虽然我只是将其作为一个非常简单的使用场景 - 它也可以完全从反射中工作。通过反射,GetGenericArguments调用是主要的方式来提取它。当然,在这种情况下,我可以返回typeof(T)并完成它 - 但我不知道OP首先如何获得“List <T>”... 话虽如此,在像这样的通用方法中对通用参数进行反射在某些情况下可能很有用... - Reed Copsey
@Nick,@Reed:你们能提供一些示例代码(例如通过pastebin.com),以便说明它实际上有用吗?在我看来,无论你在哪里编写GetGenericType(list)list的类型在编译时必须是List<X>,其中X在编译时已知,因此无论X是什么,你都可以轻松地编写typeof(X) - Timwi
@Timwi:这样你会更开心吗?现在它通过反射获取了完整的类型...包括适当的检查,以查看它是否是List<T>,通过IsGenericType + TypeDefinition检查... - Reed Copsey
@Timwi:除了我在你的评论上添加的额外注释之外 ;) - Reed Copsey
显示剩余2条评论

1
typeof (T)

或者

typeof (T).UnderlyingSystemType

0

通过动态实现新的解决方案旧问题

void Foo(){
   Type type GetTypeT(data as dynamic);
}

private static Type GetTypeT<T>(IEnumerable<T> data)
{
    return typeof(T);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接