【问题标题】:Why the type is System.Object here?为什么这里的类型是 System.Object?
【发布时间】:2015-11-06 11:29:58
【问题描述】:

这是一段代码:

Func<dynamic> f1 = new Func<dynamic>(() => 10);
Func<int> f2 = () => 10;

Console.Write(f1.Method.ReturnType);
Console.Write(" and " + f2.Method.ReturnType );

输出:System.Object and System.Int32

我的问题是:

为什么 DLR 推断的 dynamic 类型(用于 dynamic 的类型)在这里是 System.Object 而不是 System.Int32 ?这不是很合乎逻辑,因为它还涉及将 Int32 结构装箱为对象。

据我了解,当我们在这里检查类型时,我们会在执行时动态地进行检查,因为我们使用了反射。所以到那时 DLR 知道它是 int,但由于某种原因,它把它装箱到 Object... 为什么?

我试图在 SO 上找到与此相关的任何内容并搜索了它,但我找不到任何可以解释这一切的答案。

【问题讨论】:

  • 不确定f1.GetType().GetGenericArguments().First() 是什么,但获得返回类型的更好方法是f1.Method.ReturnType
  • @M.kazemAkhgary 你是对的,我们可以两种方式都这样做,它会产生相同的输出对象和 Int32...我不明白为什么它是对象...
  • 正如 Patrick Hofman 所说,编译器不知道类型,因为函数 () =&gt; 10 尚未执行。
  • 没有。为了更好地理解尝试投射,(Func&lt;int&gt;)(() =&gt; 10)。这不能分配给Func&lt;dynamic&gt;。这意味着Func&lt;int&gt;Func&lt;dynamic&gt; 是完全不同的东西。因为Func&lt;dynamic&gt; 没有被执行,所以即使在运行时返回类型也是未知的。如果你执行它,你会得到正确的结果。试试f1().GetType(),你会看到它打印 System.Int32。方法信息保存在Method 属性中。那应该是编译时间。所以f1.Method.ReturnType 是动态的对象,它的 Int 是 int
  • @M.kazemAkhgary 感谢您提供有用的 cmets。我似乎忘记了静态编译器在动态时无法推断 lambda 表达式的类型

标签: c# dynamic lambda delegates boxing


【解决方案1】:

这里没有任何推断。它只是在执行之前不知道类型,这就是为什么给出的类型是object。 (static) 编译器不知道类型,因为您还不知道它。它以object 的形式传递,而在调用方又是dynamic

这与常规方法相同:

Console.Write(typeof(Program).GetMethod("F1").ReturnType);

public static dynamic F1()
{
    return 10;
}

输出:

系统对象

【讨论】:

  • 谢谢 Partick,你的观点很好。我似乎对dynamic 如何以“正常方式”与结构类型一起使用以及它如何与委托一起使用感到困惑
  • @Fabjan - 请记住,dynamic 不是类型 - 它只是声明在编译时类型未知。编译器将来可以用来表示任何类型的唯一类型是object。就是这么简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-17
  • 2021-01-07
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多