Lambda compilation throws "variable '' of type '' referenced from scope '', but it is not defined"

c# expression-trees runtime-compilation

Question

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?

Accepted Answer

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.



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why