运行时编译表达式中的局部变量

时间:2012-02-27 13:17:46

标签: c# asp.net-mvc reflection

在这段代码中,我将ColumnInfo添加到列表中, 在我看来,传递给ColumnInfo的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();
}

3 个答案:

答案 0 :(得分:2)

由于LINQ的延迟方面,因此您需要为值创建单独的空间。

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

答案 1 :(得分: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"

答案 2 :(得分: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));
}