Lambda转换具有不明确的返回类型和重载决策

svi*_*ick 10 c# lambda overload-resolution

如果我有一个像() => { throw new Exception(); }这样的lambda ,则不清楚它是否有返回类型.因此,它可以(隐式)转换为ActionFunc<object>(或任何其他Func<T>).这是因为,根据§6.5C #4规范的匿名函数转换:

[A]委托类型D与提供的匿名功能兼容F:

  • ...

  • 如果D有一个void返回类型且body F是一个语句块,当[...]的主体F是一个有效的语句块时,其中没有return语句指定一个表达式.

  • 如果D具有非void返回类型且body F是一个语句块,则当[...]主体F是具有不可到达端点的有效语句块时,其中每个return语句指定一个可隐式转换为返回的表达式的类型D.

但是如果我有一个方法的两个重载,其中一个具有类型的参数Action和另一个Func<object>,并且我从上面传递lambda,Func<object>则使用重载.为什么?规范的哪一部分说Func<object>Action这种情况更好?

我已经看过§7.5.3.2 更好的函数成员,但这并没有解释它.

svi*_*ick 11

我应该看一个较低的部分:§7.5.3.3 从表达式转换更好解释了:

给定的隐式转换,从一个表达式转换到类型,以及隐式转换,从一个表达式转换到类型,比更好的转换如果下列中的至少一个成立:C1ET1C2ET2C1C2

  • ...

  • E是一个匿名函数,是委托类型或表达式树类型,是委托类型或表达式树类型,并且具有以下之一:T1D1Expression<D1>T2D2Expression<D2>

    • ...

    • D1并具有相同的参数列表,并具有以下之一:D2

      • ...

      • D1有一个返回类型Y,并返回无效D2

  • 是的,在我写这个问题时,我注意到了规范中的答案.所以我不想浪费任何人的时间研究这个.但与此同时,我认为它可能对其他人有用. (6认同)