Локальные переменные в скомпилированных выражениях времени выполнения - PullRequest
0 голосов
/ 27 февраля 2012

В этом фрагменте кода я добавляю ColumnInfo в список. На мой взгляд, выражение getter, переданное в метод ColumnInfo, вызывается для моих строк.Это все прекрасно работает, за исключением локальной переменной "childt.Naam", которая используется get в моем лямбда-выражении.

Оценка во время выполнения заставляет childt.Naam всегда быть последним из потомков, переданных в foreach.

Как я могу убедиться, что эти "локальные переменные" правильно переданы в выражение

 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 ]

2 голосов
/ 27 февраля 2012

Вы закрываете переменную цикла - просто создайте локальную копию:

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

Также см. «Закрытие переменной цикла, считающейся вредной»

2 голосов
/ 27 февраля 2012

Это из-за отложенного аспекта 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 голос
/ 27 февраля 2012

Эта проблема известна как 'доступ к измененному закрытию' . Чтобы исправить это, создайте локальную переменную в теле цикла, присвойте ей childt и используйте ее в лямбда-выражениях:

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));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...