9

ここで見られるようにPredicateBuilderを使用していますhttp://www.albahari.com/nutshell/predicatebuilder.aspx、すべてがうまく機能し、動的LINQ to SQL式を生成できるようになりましたが、私が理解していないのは、このようなループで:

var inner = PredicateBuilder.False<MyType>();
foreach (var f in Filtermodel.InstrumentsFilterList.Where(s => s.isActive))
        {
          int temp = f.InstrumentID;
          inner = inner.Or(ud => ud.InstrumentId == temp);
        }

なぜその一時変数を使用する必要があるのですか?、「f」イテレータ変数を使用しようとしますが、参照によって渡されるように、各反復のリストの最後の値のみを取得します。

4

2 に答える 2

10

PredicateBuilderは、後で実行される式を作成しているためです。コンパイラーがデリゲートのクロージャーを生成しているとき、現在のスコープで作成された値を見つけて、それらをクロージャーにも取り込みます。InstrumentIDは値型(int)であるため、値を初期化してコピーすることは、各デリゲート/クロージャーがその値を保持することを意味します。毎回値のコピーを作成しない場合、式には、基になる値ではなく、f.InstrumentIDへのリテラル参照が含まれます。したがって、後で式が実際に実行されると、f.InstrumentIDが評価され、最後に設定されたもの、つまり最後の反復として出力されます。

于 2009-10-27T01:50:29.303 に答える
2

条件を評価するのではなく、単に式を作成するためです。式は、foreachで定義された変数にバインドされます。この変数は、ループ全体の実行全体を通じて参照を保持します。一時変数で再定義すると、各式で異なる変数が使用されます。これにより、すべての反復が単一の参照を参照し、最後の反復の値だけを持つのではなく、各反復の値を持つインスタンスを参照するようになります。

于 2009-10-27T01:50:51.863 に答える