2

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) ?

4
  • 2
    Because it's in local scope and you're assigning it with &= . Commented Mar 17, 2014 at 15:37
  • 1
    Might be worth reading this: stackoverflow.com/questions/5438307/… Commented Mar 17, 2014 at 15:40
  • What did you expect to happen? Lambdas capture local variables, so they store a reference to them and are thus able to change them. Commented Mar 17, 2014 at 15:40
  • @AdamHouldsworth Thank you, that's what I didn't understand. Now it's clear. Commented Mar 17, 2014 at 15:48

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

While this is true and really very good information, the majority of it does not apply to this question because foreach is not deferred. This answer is very valuable - I'd just suggest making a note of that.
@Magus You are right - the part that is relevant to the OP's question is in the very first sentence. However, I wanted to make sure that whoever reads this answer does not get too carried away by the new exciting possibilities, because they need to be handled with care.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.