为什么表达式树不能包含命名参数规范?

时间:2012-04-12 21:01:45

标签: c# c#-4.0 expression-trees

使用AutoMapper,我找到了一个命名参数非常适合的地方:

.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, isAdvanced: false)))

但是编译器对我大吼:

  

表达式树可能不包含命名参数规范

所以我不得不回复:

.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, false)))

有谁知道为什么编译器在这种情况下不允许使用命名参数?

1 个答案:

答案 0 :(得分:31)

请考虑以下事项:

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

现在,您希望表达式树转换生成哪个表达式树库,以确保这一点?没有了!因此,我们面临以下选择:

  1. 在表达式树库中实现该功能。在表达式树降低引擎中添加转换,以保留命名参数的执行顺序。实现考虑执行顺序的Compile方法中的代码。
  2. 使x = ()=>Q(n : N(), m: M());实际上被实现为x = ()=>Q(M(), N());,并且与非表达式树版本不兼容。
  3. 禁止在表达式树中使用命名参数。实现相应的错误消息。
  4. (1)很好,但很贵。 (2)是非首发;我们不能凭良心介绍这种“陷阱”。 (3)便宜但刺激性。

    我们选择了(3)。