为什么不能将anon函数与动态参数一起使用?

Geo*_*uer 16 c# dynamic anonymous-function

刚刚遇到这个问题

匿名函数或方法组不能用作动态绑定操作的组成值.

当试图做

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

并使用它

dynamic firstAddress = ...;
return ifNotNull<string>(firstAddress, (a) => a.address_1, null)
Run Code Online (Sandbox Code Playgroud)

现在大多数关于动态的限制对我来说都是有意义的 - 你不能使用扩展方法,因为编译器应该如何决定将哪个静态编译为?但我不知道这里.困惑在哪里?究竟是什么限制?

shf*_*301 14

兰巴 的静态类型是什么a => a.address_1?你可能很想说它是一个Func<dynamic, dynamic>.但要记住:

lambda表达式是一个匿名函数,可用于创建委托或表达式树类型.

所以也许这是一个Expression<Func<dynamic, dynamic>>.lamda本身没有单一的静态类型.

现在通常类型推断会发现你将lamba传递给一个带有a的函数,它将Func在编译时转换为委托.但是,当您使用动态参数调用时,将动态调度方法调用.

如果您使用动态参数进行方法调用,则会动态调度它,句点.在运行时绑定期间,参数的所有静态类型都是已知的(强调我的),并根据实际值为动态参数选择类型.

因此,Func不考虑您的方法采用a的事实,因为直到运行时才确定实际的方法调用,因此没有类型推断.

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

return ifNotNull<string>(firstAddress, new Func<dynamic, string>((a) => a.address_1), null);
Run Code Online (Sandbox Code Playgroud)

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