4
foreach(var category in categories) {
    a.AddRange(_db.Articles.Where(c => c.Categories.Contains(category)));
}

The code runs fine, yet I get a warning about "access to modified closure" in reference to category used in the lambda expression.

Question: Is the warning of any consequence in this circumstance?

one.beat.consumer
  • 9,414
  • 11
  • 55
  • 98
  • see [this related question](http://stackoverflow.com/questions/8898925/is-there-a-reason-for-cs-reuse-of-the-variable-in-a-foreach). it might help too. – J. Holmes Feb 08 '12 at 00:32
  • 1
    Um, there's a dozen hits in SO for "[Access to Modified Closure](http://stackoverflow.com/questions/235455/access-to-modified-closure)", any one of which answers this question. – Raymond Chen Feb 08 '12 at 00:42
  • @RaymondChen There are, but they didn't address the lambda context is the only reason I asked. I understand the idea of closure, just wanted to see if it meant something more specific in the context of LINQ in this odd case. – one.beat.consumer Feb 08 '12 at 00:46
  • c# 5 changes this behavior to make the category variable have the value in the current iteration and not the last value. iomagazine.com/Articles/2012/11/01/More-Than-Just-Async.aspx?Page=1 – Marcos Meli Nov 01 '12 at 15:42

2 Answers2

6

The warning here is because you are accessing the variable category inside the closure for the Where lambda. The value category changes with every iteration and Where is delay executed hence it will see the current value of category vs. the value at the time the lambda was created.

In this case you are likely fine. Even though Where is delay evaluated the AddRange method is prompt and will force the evaluation of Where to completion. Hence the Where method will see the value of category it expects.

If you'd like to remove the warning though simply declare a local copy of the iteration variable and capture that instead.

foreach(var category in categories) {
  var localCategory = category;
  a.AddRange(_db.Articles.Where(c => c.Categories.Contains(localCategory)));
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • I think this was me forgetting something about foreach loops - the iteration variable `category` is technically outside the loop right? much like this pseudo code `int i; for (i <= 10) { i++; }`? if that's the case, I understand - `Where` could be evaluated after `category` had changed? Am I understanding correctly? – one.beat.consumer Feb 08 '12 at 01:57
0

It tells you that the "category" variable lives in closure and can be modified outside your LINQ expression.

Look at the question here for some explanation.

Community
  • 1
  • 1
Alexey Raga
  • 7,457
  • 1
  • 31
  • 40