为什么不能使用带动态参数的匿名函数?

Why can you not use anon function with a dynamic parameter?

今天就运行进入这个

An anonymous function or method group cannot be used as a constituent value of a dynamically bound operation.

尝试做的时候

static R ifNotNull<R>(dynamic o, Func<dynamic, R> returnFunc, R otherwise) {
    return ReferenceEquals(null, o) ? otherwise : returnFunc(o);
}

并与

一起使用
dynamic firstAddress = ...;
return ifNotNull<string>(firstAddress, (a) => a.address_1, null)

现在对动态的大部分限制对我来说都很有意义 - 你不能使用扩展方法,因为编译器应该如何决定将它编译成哪个静态?但我不明白这一点。混乱从何而来?具体限制是什么?

lambaa => a.address_1的静态类型是什么?您可能会想说它是 Func<dynamic, dynamic>。但请记住:

A lambda expression is an anonymous function that you can use to create delegates or expression tree types.

所以可能是 Expression<Func<dynamic, dynamic>>。 lamda 本身没有单一的静态类型。

现在通常类型推断会发现您正在将 lamba 传递给接受 Func 的函数,并且它将在编译时转换为委托。但是,当您使用动态参数调用时 the method call is dispatched dynamically.

If you have a method call with a dynamic argument, it is dispatched dynamically, period. During the runtime binding, all the static types of your arguments are known (emphasis mine), and types are picked for the dynamic arguments based on their actual values.

所以您的方法采用 Func 的事实没有被考虑在内,因为 the actual method call isn't determined until runtime 所以没有类型推断。

要编译它,你必须将你的 lamba 转换为 Func<dynamic, string>,如下所示:

return ifNotNull<string>(firstAddress, new Func<dynamic, string>((a) => a.address_1), null);

现在你的 lamda 的静态类型是已知的。

我的意思是您需要将 lambda 方法转换为您想要的期望表达式。然后就可以正常工作了。

像这样:

return ifNotNull(firstAddress, (Func<dynamic, string>)((a) => a.address_1), null);