Reputation: 24759
I have the following LINQ Select
which does not work.
Data.Select(d => d.Value.IsDirty = true); //-- Not working
My longer workaround does.
foreach (var d in Data)
d.Value.IsDirty = true;
Why does my first code not work?
Upvotes: 2
Views: 561
Reputation: 186118
Select()
returns an IEnumerable<…>
, which has the ability to iterate over the input and invoke the code in question, but doesn't actually do so until you enumerate it in some manner:
Data.Select(d => d.Value.IsDirty = true).ToList();
or
foreach (var _ in Data.Select(d => d.Value.IsDirty = true))
; // Do nothing
However, given that they perform side effects (obviously the intent here), both of the above are bad karma. Don't use them. Your original foreach
is the only sensible choice.
Upvotes: 5
Reputation: 488
Calling Select
does not cause the side effect you need, even if you force execution by iterating over the elements.
If you want the side effect you have to do foreach
.
For example:
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.
}
}
Upvotes: -3
Reputation: 185703
Projection functions like Select
, Where
, etc. define queries. Simply calling Select
does not actually do anything until the query is evaluated (almost certainly, at some point, by a foreach
).
If you were to do something to force execution of the query (calling Count
, for instance), you'd see it take effect.
It is, however, a bit of an abuse. These functions aren't specifically intended for state-altering operations.
Upvotes: 9