我有以下Select
不起作用的 LINQ。
Data.Select(d => d.Value.IsDirty = true); //-- Not working
我更长的解决方法可以。
foreach (var d in Data)
d.Value.IsDirty = true;
为什么我的第一个代码不起作用?
Select
像,等投影函数Where
定义查询。在评估查询之前,简单的调用Select
实际上并没有做foreach
任何事情(几乎可以肯定,在某些时候,通过 a )。
如果您要执行某些操作来强制执行查询(Count
例如调用 ),您会看到它生效。
然而,这有点滥用。这些函数并非专门用于状态更改操作。
Select()
返回 an IEnumerable<…>
,它能够遍历输入并调用有问题的代码,但实际上在您以某种方式枚举它之前不会这样做:
Data.Select(d => d.Value.IsDirty = true).ToList();
或者
foreach (var _ in Data.Select(d => d.Value.IsDirty = true))
; // Do nothing
但是,鉴于它们会产生副作用(显然是这里的意图),以上两者都是恶业。不要使用它们。您的原件foreach
是唯一明智的选择。
即使您通过迭代元素来强制执行,调用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.
}
}