1

Select動作しない次の LINQがあります。

Data.Select(d => d.Value.IsDirty = true); //-- Not working

私のより長い回避策はそうです。

foreach (var d in Data)
    d.Value.IsDirty = true;

最初のコードが機能しないのはなぜですか?

4

3 に答える 3

8

Select、 などの射影関数はクエリWhereを定義します。単に呼び出すだけでは、クエリが評価されるまで実際には何もしません(ほぼ確実に、ある時点で a によって)。Selectforeach

クエリの実行を強制するために何かを行う場合 (Countたとえば、 を呼び出す)、それが有効になることがわかります。

ただし、これは少し乱用です。これらの関数は、状態変更操作を特に意図したものではありません。

于 2012-04-11T00:12:29.900 に答える
5

Select()を返しますIEnumerable<…&gt;。これには、入力を反復処理して問題のコードを呼び出す機能がありますが、何らかの方法で列挙するまで実際にはそうしません。

Data.Select(d => d.Value.IsDirty = true).ToList();

また

foreach (var _ in Data.Select(d => d.Value.IsDirty = true))
    ; // Do nothing

ただし、副作用を実行することを考えると (明らかにここでの意図)、上記の両方が悪いカルマです。それらを使用しないでください。あなたのオリジナルforeachが唯一の賢明な選択です。

于 2012-04-11T00:12:38.800 に答える
-3

要素を繰り返し処理して実行を強制しても、呼び出しSelectによって必要な副作用は発生しません。副作用が必要な場合は、実行する必要がありますforeach

例えば:

class MyValue
{
    public MyValue(bool flag) { Flag = flag; }

    public bool Flag { get; set; }
}

class MyValueContainer
{
    public MyValueContainer(MyValue val) { MyVal = val; }

    public MyValue MyVal { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var someList = new List<MyValueContainer>();
        someList.Add(new MyValueContainer(new MyValue(true)));
        someList.Add(new MyValueContainer(new MyValue(true)));
        someList.Add(new MyValueContainer(new MyValue(false)));
        someList.Add(new MyValueContainer(new MyValue(true)));

        var trueCount = someList.Count(x => x.MyVal.Flag); // 3
        var falseCount = someList.Count(x => !x.MyVal.Flag); // 1

        // try causing side effect by calling Select
        someList.Select(x => x.MyVal.Flag = false);

        // force execution. call Count
        trueCount = someList.Count(x => x.MyVal.Flag); // still 3... no side effect.
        falseCount = someList.Count(x => !x.MyVal.Flag); // still 1... no side effect.

        foreach (var x in someList)
            x.MyVal.Flag = false;

        trueCount = someList.Count(x => x.MyVal.Flag); // 0... side effect seen.
        falseCount = someList.Count(x => !x.MyVal.Flag); // 4...  side effect seen.
    }
}
于 2012-04-11T00:56:44.267 に答える