Reputation: 172
I made an extension which adds ForEach() method on ObservableCollection :
public static void ForEach<T>(this ObservableCollection<T> enumerable, Action<T> action)
{
foreach (var item in enumerable)
action(item);
}
When I use it, like this :
private bool Bar(int i)
{
return i % 2 == 1;
}
private void Foo()
{
Boolean ok = true;
ObservableCollection<int> oc = new ObservableCollection<int> { 1, 2, 3, 4 };
oc.ForEach(i => ok &= Bar(i));
//ok is now false
}
I don't understand how does the ok
Boolean take the value returned by the Bar()
method which is executed by action(item)
?
Upvotes: 2
Views: 1300
Reputation: 14672
You are applying &= which will and each result with the previos value of ok (as ok is not local to a single loop iteration, it is declared outside of the loop). In other words,
as the condition is only true for two values (1 and 3)
ok = true && false && true && false
which is false.
Upvotes: 0
Reputation: 726489
Lambdas are allowed to modify variables that are in the scope of the code inside their bodies. You need to be very careful with this sort of code, because you do not always have full control over the timing of executing the lambdas.
For example, if you add an assignment to a lambda that you pass to a method with deferred execution, the side effect of that lambda (i.e. the assignment) would not be visible until the code of that lambda has actually executed.
Here is an example:
bool ok = true;
IEnumerable<int> res = new[] {1, 2, 3}.Where(i => ok &= (i == 2));
// ok is true here
IList<int> listRes = res.ToList();
// ok is false here
If you run this code, ok
would remain true
, even though the very first item of the source list would trigger an assignment of false
to the ok
variable. This wouldn't happen, however, until you enumerate res
.
Upvotes: 2