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定义查询。在评估查询之前,简单的调用Select实际上并没有foreach任何事情(几乎可以肯定,在某些时候,通过 a )。

如果您要执行某些操作来强制执行查询(Count例如调用 ),您会看到它生效。

然而,这有点滥用。这些函数并非专门用于状态更改操作。

于 2012-04-11T00:12:29.900 回答
5

Select()返回 an 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 回答