45

AutoMapperを使用して、名前付き引数が非常にうまく適合する場所を見つけました。

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

しかし、コンパイラは私に怒鳴りました:

式ツリーに名前付き引数の指定を含めることはできません

だから私はに戻らなければなりませんでした:

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

コンパイラがこの状況で名前付き引数を許可しない理由を誰かが知っていますか?

4

1 に答える 1

37

次のことを考慮してください。

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());

最後の2行がまったく同じことをしなければならないことを願っていますよね?どちらを印刷するかNM3

さて、これを確実にするために、どの式ツリーライブラリ呼び出しで式ツリー変換を生成しますか?ありません!したがって、次の選択肢に直面します。

  1. 式ツリーライブラリに機能を実装します。名前付き引数の実行順序を保持する変換を式ツリー下降エンジンに追加します。Compile実行順序を考慮したメソッドにコードを実装します。
  2. 実際には、非式ツリーバージョンx = ()=>Q(n : N(), m: M());として実装され、互換性がないようにします。x = ()=>Q(M(), N());
  3. 式ツリーで名前付き引数を禁止します。その旨のエラーメッセージを実装します。

(1)いいですが、高価です。(2)初心者ではありません。このような「落とし穴」を良心的に紹介することはできません。(3)安いですが、イライラします。

(3)を選びました。

于 2012-04-12T23:07:38.137 に答える