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

本文关键字:局部变量 表达式 编译 运行时 | 更新日期: 2023-09-27 18:25:59

在这段代码中,我将ColumnInfo添加到列表中,在我看来,传递给ColumnInfo的getter表达式在我的行上被调用。除了在我的lambda表达式中使用的局部变量"childt.Naam"之外,这一切都很好。

运行时评估导致childt。Naam永远是最后一个在前臂上通过的孩子。

如何确保这些"局部变量"正确传递到表达式

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

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

这是因为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

您正在关闭循环变量-只需制作本地副本:

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

另请参阅"关闭被认为有害的循环变量"

这个问题被称为"访问修改的闭包"。要修复它,请在循环体中创建一个局部变量,将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));
}