【问题标题】:typeof generic and casted type [duplicate]typeof 泛型和强制类型 [重复]
【发布时间】:2019-07-16 13:41:30
【问题描述】:

假设我们有通用方法:

public void GenericMethod<T>(T item)
{
    var typeOf = typeof(T);
    var getType = item.GetType();
}

我们使用以下参数调用它:

GenericMethod(1)
GenericMethod((object) 1)

结果是:

typeOf = System.Int32
getType = System.Int32

typeOf = System.Object
getType = System.Int32

谁能解释一下为什么 typeof 整数转换为对象返回 System.Object,但 .GetType() 返回 System.Int32?

【问题讨论】:

  • typeof takes 类型名称(您在编译时指定),GetType 获取实例的运行时类型。
  • 另外,如果您发现自己在泛型中进行任何类型的测试,请问问自己是否为这项工作选择了正确的工具。因为这可能意味着您无法在 runtime 正常工作,而您在编译时“承诺”您可以做的事情(通过说您可以为任何类型工作,受该类型的任何泛型类型约束参数)

标签: c# generics


【解决方案1】:

typeof 返回泛型参数T静态(编译时) 类型。

GetType 返回变量item 中包含的动态(运行时) 类型。


如果您将方法设为非泛型,则更容易看出差异。假设BA 的子类型:

public void NonGenericMethod(A item)
{
    var typeOf = typeof(A);
    var getType = item.GetType();
}

在这种情况下,调用NonGenericMethod(new B()) 会产生

A
B

推荐阅读:


现在,您可能会问:为什么在您的示例中使用 NonGenericMethod(A item) 而不是 NonGenericMethod(B item) 这是一个非常好的问题!考虑以下(非通用)示例代码:

public static void NonGenericMethod(A item)
{
    Console.WriteLine("Method A");
    var typeOf = typeof(A);
    var getType = item.GetType();
}
public static void NonGenericMethod(B item)
{
    Console.WriteLine("Method B");
    var typeOf = typeof(B);
    var getType = item.GetType();
}

当您调用NonGenericMethod((A) new B()) 时会得到什么(类似于您示例中的参数(object) 1)?

Method A
A
B

为什么?因为重载决议是在编译时完成的,而不是在运行时。在编译时,表达式(A) new B() 的类型是A,就像(object) 1 的编译时类型是object

推荐阅读:

【讨论】:

  • 虽然typeOf 将在第一次使用特定T 执行函数之前得到解决,但它可能会在程序开始执行之后发生。与 C++ 不同,C# 使程序可以根据输入创建无限数量的不同类型,即使不使用反射也是如此。在这种情况下,可能无法生成可以调用函数的每种类型 T 的列表,因此无法在程序执行之前确定 T 将是什么。
【解决方案2】:

GenericMethod((object) 1) 中,T 将是object。 typeof 反映了这一点。

item.GetType(); 是一个虚方法,将在运行时在 Int32 上执行。

【讨论】:

    【解决方案3】:

    对 GetType 的调用在运行时被解析,而 typeof 在编译时被解析。 这就是为什么它给出不同的结果。 你可以在这里查看 - When and where to use GetType() or typeof()?

    【讨论】:

      【解决方案4】:

      This Tells me Typeof 为您提供编译时间类型,而 GetType 为您提供 Exact Run time 类型。

      【讨论】:

        【解决方案5】:

        当你忽略类型干扰时,很多事情都会变得清晰:

        GenericMethod(1) 实际上是GenericMethod&lt;int&gt;(1)

        GenericMethod((object) 1) 被推断为GenericMethod&lt;object&gt;((object) 1)

        当您询问typeof(T) 时,它会返回您在方法调用中指定的T。您也可以使用GenericMethod&lt;object&gt;("a"),这将在typeof(T) 上返回object

        GetType 返回所提供实例的实际运行时类型。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-04
          • 1970-01-01
          • 2018-08-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多