【问题标题】:Why does the compiler have to know the type of one lambda?为什么编译器必须知道一个 lambda 的类型?
【发布时间】:2017-05-10 12:59:45
【问题描述】:

这段代码不容易阅读,很抱歉,但出于我的兴趣,为什么编译器必须知道 lambda 的类型。让我们看看代码,不用担心,这不是真正的代码。

bool b1 = true, b2, b3;
Action action = () => Console.WriteLine("Hello");
(b1 ? () => 
  {
    b2 = true;
    b3 = false;
  } : action)();

这行得通。但是……

为什么我不能这样做?

bool b1 = true, b2, b3;
(b1 ? () => 
  {
    b2 = true;
    b3 = false;
  } : () => Console.WriteLine("Hello"))();

您能否解释一下,在哪些情况下编译器必须知道函数的显式类型(在这种情况下为Action)?

VS2017 告诉我......

CS0173 无法确定条件表达式的类型,因为 'lambda 表达式'和之间没有隐式转换 'lambda 表达式'

【问题讨论】:

  • 结果是什么?如果是编译器错误,您应该提及它
  • 我错了还是()=>{} 也可以是Func<>? (我认为可能是什么原因)

标签: c# lambda action


【解决方案1】:

因为 .NET 中没有委托等价性:您可以拥有两个具有相同签名的委托,例如

delegate void MyDelegate1()

delegate void MyDelegate2()

但您不能将一位代表分配给另一位代表.​​..您不能:

MyDelegate1 del1 = null;
MyDelegate2 del2 = del1;

它们是不同且不兼容的委托类型。它们仅从“人类”的角度来看是“相似的”,而不是从编译器/.NET 的角度来看。

很明显,如果委托的确切“类型”(不仅是其签名)在 .NET 中很重要,那么 .NET 就不能“取消”它。在您的第一个示例中,编译器可以看到委托类型是Action,因此它可以推断出() => { ... }Action。在第二个例子中,编译器没有这个“提示”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 2019-08-28
    • 2014-03-07
    相关资源
    最近更新 更多