【问题标题】:Why is a temporary variable required in foreach to be included in lambda expression?为什么 foreach 中需要一个临时变量才能包含在 lambda 表达式中?
【发布时间】:2012-04-09 00:07:13
【问题描述】:

我正在阅读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

有人可以澄清一下吗?

【问题讨论】:

标签: linq c#-4.0 lambda iqueryable


【解决方案1】:

因为只有一个名为keyword 变量被关闭。然而,临时变量在每次迭代时不同

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

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

【讨论】:

  • later,这就是关键字!我没看到,谢谢!
【解决方案2】:

问题是keyword 正在改变。 =&gt; 委托关闭变量的 当前 值,而不是过去创建委托时的值。 Eric Lippert's blog post有详细说明。

这个经典的 C 错误也是同样的错误:

#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 获取i当前值,而不是创建线程时的值。

【讨论】:

  • 那是一篇不错的文章,但让我很恼火的是,其中没有一个简短的摘录/摘要可以在其中使用最少的上下文:(
猜你喜欢
  • 1970-01-01
  • 2015-06-30
  • 1970-01-01
  • 1970-01-01
  • 2018-09-24
  • 2014-06-21
  • 1970-01-01
  • 2014-08-13
  • 1970-01-01
相关资源
最近更新 更多