Why should the temporary variable needed for foreach have to be included in the lambda expression?

I read C# 4 in a Nutshell and I came to this piece of code:

 IQueryable<Product> SearchProducts (params string[] keywords) { IQueryable<Product> query = dataContext.Products; foreach (string keyword in keywords) { string temp = keyword; query = query.Where (p => p.Description.Contains (temp)); } return query; } 

Immediately after the code, a warning appears that looks like this:

The temporary variable in the loop is required to avoid the outer variable trap, where the same variable is captured for each iteration of the foreach loop.

I don’t understand, I don’t understand why the temp variable is needed. What is outter variable trap ?

From: http://www.albahari.com/nutshell/predicatebuilder.aspx

Can someone clarify this?

+4
source share
2 answers

Because there is only one variable called keyword that closes. However, the temporary variable is different from each iteration.

Thus, without a temporary variable, when lambda is executed later, keyword evaluates the last value that was assigned in the loop.

Another solution, in some cases, is a forced evaluation (and ends with a List or such).

+5
source

The problem is that keyword changing. Delegate => closes the current value of the variable, not the value it had in the past when the delegate was created. There's a detailed explanation on Eric Lippert's blog .

This classic C error is the same error:

 #include <stdio.h> #include <pthread.h> void * MyThreadFunction(void *x) { printf("I am thread %d\n", * (int *) x); return NULL; } int main(void) { int i; pthread_t t[10]; void *ret; for(i=0; i<10; i++) pthread_create(&t[i], NULL, MyThreadFunction, (void *) &i); for(i=0; i<10; i++) pthread_join(t[i], &ret); } 

* (int *) x gets the current value of i , not the value when creating the stream.

+2
source

Source: https://habr.com/ru/post/1403273/


All Articles