【问题标题】:Get actual type of T in a generic List<T>在泛型 List<T> 中获取 T 的实际类型
【发布时间】:2015-11-30 05:51:49
【问题描述】:

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

【问题讨论】:

标签: c# generics reflection


【解决方案1】:

这取决于你到底要问什么:

  • 在泛型类型Blah&lt;T&gt; 中编写代码时,如何获取反射类型T

    回答:typeof(T)

  • 我有一个对象,其中包含某个类型 TList&lt;T&gt;。如何通过反射检索类型T

    简答:myList.GetType().GetGenericArguments()[0]

    长答案:

    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];
    

【讨论】:

  • BTW - 如果“myList”不是泛型类型,这将抛出 GetGenericTypeDefinition()...如果您要进行错误检查,您也应该检查 IsGenericType .
【解决方案2】:

您可以使用Type.GetGenericArgumentsList&lt;T&gt; 中返回类型T。

例如,这将返回作为参数传递的任何List&lt;T&gt; 的类型:

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 - 我能想到十几个有用的地方,仅仅因为你在编译时有一个T,并不意味着你知道它(例如通用约束)。有几种方法可以解决它,例如ElementType IQueryable&lt;T&gt;,但不要认为它没有用。
  • @Timwi:虽然我把它当作一个非常简单的使用场景——它也完全可以通过反射来工作。 GetGenericArguments 调用是通过反射将其拉出的主要方式。当然,在这种情况下,我本可以返回 typeof(T) 并完成它 - 但我不知道 OP 首先是如何获得“List”的......话虽如此,在像这样的泛型方法中对泛型参数进行反射在某些情况下可能很有用...
  • @Nick, @Reed:您能否提供一些实际有用的示例代码(例如通过 pastebin.com)?在我看来,无论你写GetGenericType(list)list 的类型在编译时必须是List&lt;X&gt;,而X 在编译时是已知的,所以无论X 是什么,你都可以就像轻松写 typeof(X) 一样。
  • @Timwi:这会让你更快乐吗?现在它通过反射获得完整类型...包括通过 IsGenericType + TypeDefinition 检查正确检查它是否是 List...
【解决方案3】:
typeof (T)

typeof (T).UnderlyingSystemType

【讨论】:

    【解决方案4】:

    dynamic新解决老问题

    void Foo(){
       Type type GetTypeT(data as dynamic);
    }
    
    private static Type GetTypeT<T>(IEnumerable<T> data)
    {
        return typeof(T);
    }
    

    【讨论】:

      猜你喜欢
      • 2018-07-02
      • 2016-08-24
      • 2022-12-17
      • 1970-01-01
      • 2012-11-28
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      相关资源
      最近更新 更多