为什么表达式树不能包含命名参数规范
本文关键字:参数 包含命 表达式 不能 为什么 | 更新日期: 2023-09-27 18:30:50
使用AutoMapper,我遇到了一个命名参数非常适合的地方:
.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, isAdvanced: false)))
但是编译器对我大喊大叫:
表达式树不能包含命名参数规范
所以我不得不恢复到:
.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, false)))
有谁知道为什么编译器在这种情况下不允许命名参数?
请考虑以下事项:
static int M() { Console.Write("M"); return 1; }
static int N() { Console.Write("N"); return 2; }
static int Q(int m, int n) { return m + n; }
...
Func<int> f = ()=>Q(n : N(), m: M());
Expression<Func<int>> x = ()=>Q(n : N(), m: M());
Func<int> fx = x.Compile();
Console.WriteLine(f());
Console.WriteLine(fx());
你同意我希望最后两行必须做完全相同的事情,对吧?这是打印NM3
.
现在,您希望表达式树转换生成哪些表达式树库调用来确保这一点?没有!因此,我们面临以下选择:
- 在表达式树库中实现该功能。在表达式树降低引擎中添加一个转换,以保留命名参数的执行顺序。在考虑执行顺序的
Compile
方法中实现代码。 - 使
x = ()=>Q(n : N(), m: M());
实际实现为x = ()=>Q(M(), N());
,并且与非表达式树版本不兼容。 - 不允许表达式树中的命名参数。实现一条错误消息来达到此效果。
(1)不错,但价格昂贵。(2)是非启动器;我们不能凭良心介绍这种"陷阱"。(3)便宜但刺激。
我们选择了(3)。