我的linq选择不起作用,我的foreach确实如此

时间:2012-04-11 00:09:31

标签: c# linq

我有以下LINQ Select,它不起作用。

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

我的解决方法更长。

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

为什么我的第一个代码不起作用?

3 个答案:

答案 0 :(得分:8)

SelectWhere等投影功能定义查询。在评估查询之前,简单地调用Select实际上并不任何事情(几乎可以肯定,在某个时候,foreach)。

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

然而,这有点滥用。这些功能并非专门用于状态改变操作。

答案 1 :(得分:5)

Select()返回一个IEnumerable<…>,它具有 ability 来迭代输入并调用有问题的代码,但实际上并没有这样做,直到你枚举它为止以某种方式:

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

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

然而,鉴于他们表现出副作用(显然是这里的意图),上述两种都是不好的业力。不要使用它们。您原来的foreach是唯一明智的选择。

答案 2 :(得分:-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.
    }
}