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

刚刚遇到这个问题

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

当试图做

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

并使用它

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

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

lamba a => a.address_1的静态类型是什么? 你可能会想说它是一个Func 。 但要记住:

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

所以也许它是一个Expression> 。 lamda本身没有单一的静态类型。

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

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

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

要进行编译,你必须将lamba转换为Func ,如下所示:

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

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

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

像这样:

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