Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do local variable?

Tags:

c#

linq

filter

resharper offers me to make this a local variable, and writes "access to modified closure"

if (filter != null)
{
    if (filter.CityId != 0)
    {
        ads = ads.Where(x => x.Ad.CityId == filter.CityId);
    }
    if (filter.BusinesCategoryId != 0)
    {
        ads = ads.Where(x => x.BusinessCategoryId == filter.BusinesCategoryId);
    }
}

Why do local variable filter?

like image 742
Mediator Avatar asked Jan 17 '23 23:01

Mediator


2 Answers

Because your query(Where(...)) is not being executed. I assume filter is obtained from a loop?

Linq query are not executed until they are used. so if you looped though a bunch of filters then started executing them later, the filter value would be wrong in the query.

A similar question : Access to Modified Closure Also: http://devnet.jetbrains.net/thread/273042

would need to see more code to 100% sure.

like image 107
TheRealTy Avatar answered Jan 27 '23 20:01

TheRealTy


From how I understand this, Resharper will throw an error if you access a variable from a delegate (closure), and then modify the variable before you execute the delegate. This mostly happens if you access a for loop variable inside a delegate/lambda and execute it outside the loop. If your code is like:

foreach (filter in filters)
{
      if (filter != null)  {
            if (filter.CityId != 0)      {
                ads = ads.Where(x => x.Ad.CityId == filter.CityId);
            }
            if (filter.BusinesCategoryId != 0)      {
                ads = ads.Where(x => x.BusinessCategoryId == filter.BusinesCategoryId);
            }
      }
} 
return ads.ToList()

Then it will not behave like you'd expect it to. But if you execute the lambda expressions inside the loop scope then you would have no problem.

I wont explain why it behaves that way because a lot of people already explained it very well:

  • Eric Lippert's Blog

  • ReSharper Warning - Access to Modified Closure

  • Is there a reason for C#'s reuse of the variable in a foreach?

UPDATE: To answer "Why do local variable?" is because the fix to the above problem is using a local variable (i.e., inside the loop) and using that in your lambda. That way you are closing over the different instances of the variable for each instance of the lambda.

like image 42
Mel Avatar answered Jan 27 '23 19:01

Mel