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

时间:2015-07-30 17:43:07

标签: c# dynamic anonymous-function

今天刚遇到这个

  

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

尝试时

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)

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

2 个答案:

答案 0 :(得分:13)

lamba sum((LD.RegHrs + abs(LD.RegHrs) + (LD.OvtHrs + abs(LD.OvtHrs) + (LD.SpecialOvtHrs + abs(LD.SpecialOvtHrs)) / 2 的静态类型是什么?你可能会想说它是a => a.address_1。但请记住:

  

lambda表达式是您可以使用的匿名函数   创建委托或表达式树类型。

所以也许它是Func<dynamic, dynamic>。 lamda本身并不具有单一的静态类型。

现在通常类型推断会发现你将lamba传递给一个带Expression<Func<dynamic, dynamic>>的函数,它将在编译时转换为委托。但是,当您使用动态参数the method call is dispatched dynamically进行调用时。

  

如果您使用动态参数进行方法调用,则会调度它   动态,周期。在运行时绑定期间,所有静态类型   您的参数已知(强调我的),并为动态选择类型   基于实际价值的论据。

因为the actual method call isn't determined until runtime所以没有类型推断,因此您的方法需要Func这一事实不会被考虑在内。

为了让你编译,你必须将你的lamba转换为Func,如下所示:

Func<dynamic, string>

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

答案 1 :(得分:1)

我的意思是你需要将lambda方法转换为你想要的expect表达式。然后它会工作得很好。

像这样:

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