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

2023-12-20

今天刚遇到这个

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

当试图做的时候

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)

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


什么是静态类型lamba https://msdn.microsoft.com/en-us/library/bb397687.aspx a => a.address_1?你可能会想说这是一个Func<dynamic, dynamic>。但要记住:

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

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

现在,通常类型推断会发现您正在将 lambda 传递给一个采用Func它会在编译时转换为委托。但是,当您使用动态参数调用时方法调用是动态调度的 http://blogs.msdn.com/b/cburrows/archive/2010/04/01/errata-dynamic-conversions-and-overload-resolution.aspx.

如果您有一个带有动态参数的方法调用,则会调度它 动态地,时期。在运行时绑定期间,所有静态类型 你的论点有多少是已知的(强调我的),并为动态选择类型 基于其实际值的参数。

所以事实上你的方法需要一个Func不考虑,因为实际的方法调用直到运行时才确定 http://ericlippert.com/2012/10/22/a-method-group-of-one/所以没有类型推断。

为了编译它,你必须将你的amba转换为Func<dynamic, string>如下:

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么不能使用带有动态参数的匿名函数? 的相关文章

随机推荐