我有以下LINQ Select
,它不起作用。
Data.Select(d => d.Value.IsDirty = true); //-- Not working
我的解决方法更长。
foreach (var d in Data)
d.Value.IsDirty = true;
为什么我的第一个代码不起作用?
答案 0 :(得分:8)
Select
,Where
等投影功能定义查询。在评估查询之前,简单地调用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.
}
}