避免闭包中的转义值

时间:2014-01-16 11:46:58

标签: c# closures lazy-evaluation linq-expressions

假设我有以下代码:

for(int i=0;i<10;i++)
{
    //"i" is captured in the closure passed to LazyCreate
    MyApi.AddLazyCreate(() => new foo(/*other params*/ i)); 
}

这将导致无意识的行为,因为对于所有添加的闭包,“i”将为10。

有没有一种安全的方法可以避免这种情况? 例如如果我使用Expression<func<foo>>设计我的api 如果每个“AddLazyCreate”检查传递的表达式并存储这些值的副本,那么应该可以实现预期的行为,对吧? 也就是说,我必须从表达式编译每个参数并获取参数的时间值,并使用评估的args重新创建新表达式。 (表达式将永远是“新”表达式)

或者我错过了一些基本的东西? 我是否还会获得奇怪的行为呢?

1 个答案:

答案 0 :(得分:4)

你可以这样做:

for(int i=0; i<10; i++)
{
    int number = i;
    MyApi.AddLazyCreate(() => new foo(/*other params*/ number)); 
}

这将导致它在循环的每次迭代中捕获不同的数字。