2012-02-27 31 views
0

在这段代码中,我将ColumnInfo添加到列表中, 在我看来,传递给ColumnInfo get的getter表达式被调用到我的行上。 这一切工作正常,除了在我的lambda表达式中使用的局部变量“childt.Naam”。运行时编译表达式中的局部变量

运行时评估会导致childt.Naam始终是在foreach中传递的最后一个childt中的一个。

我如何确保这些“局部变量”被正确传递到表达式

foreach (var childt in itemt.ItemTemplates) 
      {     

        columns.Add(new ColumnInfo<Item>(model => level(model).GetV(childt.Naam, model.Taal) + childt.Naam, childt.Naam, new TextPropertyRenderer(), editable)); 



      } 

这里的ColumnInfo类的构造函数中的相关部分

public ColumnInfo(Expression<Func<TModel, object>> getter, string title, IPropertyRenderer renderer, bool editable = false) 
      { 
       this.renderer = renderer; 
       this.Editable = editable; 
       this.Getter = getter.Compile(); 
} 

回答

2

这是因为推迟因此您需要为值创建单独的空间。

foreach (var childt in itemt.ItemTemplates) 
{     
     var naam = childt.Naam; 
     columns.Add(new ColumnInfo<Item>(model => 
      level(model).GetV(naam, model.Taal) + naam, 
      naam, 
      new TextPropertyRenderer(), 
      editable)); 

} 

http://msdn.microsoft.com/en-us/library/bb882641.aspx

+0

大,似乎这样的伎俩! ,当定时器启动时会接受:) – 2012-02-27 13:28:29

1

这个问题被称为'access to modified closure'。 要修复它,创建循环体中的局部变量分配childt它,并在lambda表达式中使用它:

foreach (var childt in itemt.ItemTemplates) 
{     
    var c = childt; 
    columns.Add(new ColumnInfo<Item>(model => level(model).GetV(c.Naam, model.Taal) + c, c.Naam, new TextPropertyRenderer(), editable)); 
} 
2

您关闭了循环变量 - 只是让本地副本:

foreach (var childt in itemt.ItemTemplates) 
{     
    var localChildt = childt; 
    columns.Add(new ColumnInfo<Item>(model => level(model).GetV(localChildt.Naam, model.Taal) + localChildt.Naam, localChildt.Naam, new TextPropertyRenderer(), editable)); 
} 

另见"Closing over the loop variable considered harmful"

相关问题