为什么foreach中需要一个临时变量才能包含在lambda表达式中



我正在阅读C# 4 in a Nutshell,我得到了这段代码:

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;
}

代码后面有一个"警告",如下所示:

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.

我不明白,我不明白为什么temp变量是必要的。什么是outter variable trap

发件人:http://www.albahari.com/nutshell/predicatebuilder.aspx

有人能澄清一下吗?

因为只有一个变量keyword是封闭的。然而,临时变量在每次迭代中都是不同的。

因此,在没有临时变量的情况下,当lambda在之后执行时,keyword计算为循环中分配的最后一个值。

在某些情况下,另一种解决方案是强制进行评估(最终得到List或类似的结果)。

问题是keyword正在更改。=>委托关闭变量的当前值,而不是它在创建委托时的值。Eric Lippert的博客文章中有详细的解释。

这个经典的C错误是相同的错误:

#include <stdio.h> 
#include <pthread.h>
void * MyThreadFunction(void *x)
{
   printf("I am thread %dn", * (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获取i当前值,而不是创建线程时的值。

最新更新