質問: 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 f = ()=>Q(n : N(), m: M()); Expression> x = ()=>Q(n : N(), m: M()); Func fx = x.Compile(); Console.WriteLine(f()); Console.WriteLine(fx()); ``` あなたは最後の2つの行がまったく同じことをしなければならないと思います。 `NM3`が印刷されます。 さて、どのような式ツリーライブラリが呼び出すと、これを確実にする式ツリー変換が生成されますか?誰もいません!したがって、我々は以下の選択に直面している。 1. 式ツリーライブラリにその機能を実装します。名前付き引数の実行順序を保持する変換を式ツリーの下限エンジンに追加します。実行順序を考慮に入れた`Compile`メソッドでコードを実装します。 2. `x = ()=>Q(n : N(), m: M());`実際には`x = ()=>Q(M(), N());`として実装される`x = ()=>Q(M(), N());`非発現木版と互換性がない。 3. 式ツリーで名前付き引数を使用できないようにします。その旨のエラーメッセージを実装します。 (1)いいですが、高価です。 (2)はスターターではない。私たちは良心的にこのような「落ち着き」を導入することはできません。 (3)は安いが刺激的である。 我々は(3)を選んだ。