Lambda compilation throws “variable '' of

2019-07-21 11:48发布

When I attempt to compile the lambda shown below, it throws:

variable 'model' of type 'System.Collections.Generic.IEnumerable`1[WheelEndCatalogKendo.Models.SapBasicData]' referenced from scope '', but it is not defined

public static GridBoundColumnBuilder<TModel> BuildColumnString<TModel>(this GridBoundColumnBuilder<TModel> column, WebViewPage<IEnumerable<TModel>> webViewPage, int width) where TModel : class {
    var modelParameter = Expression.Parameter(typeof(IEnumerable<TModel>), "model");
    Expression<Func<IEnumerable<TModel>, TModel>> firstItem = (model) => model.FirstOrDefault();
    var member = MemberExpression.Property(firstItem.Body, column.Column.Member);
    var lambda = Expression.Lambda<Func<IEnumerable<TModel>, string>>(member, modelParameter);
    var title = webViewPage.Html.DisplayNameFor(lambda).ToHtmlString();
    var header = webViewPage.Html.ShortLabelFor(lambda).ToHtmlString().FixUpNewLinesAsHtml();
    var compiled = lambda.Compile(); //Throws here with "variable '...' of type '...' referenced from scope '', but it is not defined"
....
}

I see several similar posts; but so far they haven't clued me in to the problem with my code. It seems like I am supplying the lambda variable (as the 2nd parameter argument). I have however almost no experience authoring expression trees.

Any ideas?

1条回答
老娘就宠你
2楼-- · 2019-07-21 11:59

The problem is that the model parameter from the firstItem expression is not the same as modelParameter. In expression trees, parameters are not compared by name, but by reference.

This means that the simplest solution is to reuse the model parameter from firstItem, instead of creating your own parameter:

var modelParameter = firstItem.Parameters.Single();

With this modification, your code will work.

查看更多
登录 后发表回答