无法将lambda表达式转换为类型“System.Linq.Expressions.Expression”,因为它不是委托类型。

4

我正在尝试创建这个lambda表达式 (x => x.MenuItemId),但我不确定该如何操作。

var item = Expression.Parameter(typeof(MenuItem), "x");
var prop = Expression.Property(item, "MenuItemId");
var lambda = Expression.Lambda<Func<MenuItem, object>>(x => x.MenuItemId);
2个回答

9
您希望使用您已经声明的项和属性来创建lambda函数。
var lambda = Expression.Lambda<Func<MenuItem, object>>(prop, item);

你还可以选择将结果 lambda 强制转换为 x.MenuItemId 的类型 - 如果它是一个 string,那么就像这样:
var lambda = Expression.Lambda<Func<MenuItem, string>>(prop, item);

您可以使用Compile()来调用生成的lambda表达式,并在其他需要lambda的地方使用它。
例如,如果您有一个名为itemsMenuItem集合,并且想要获取所有MenuItemId
var compiled = lambda.Compiled(); 
var itemIds = items.Select(compiled); // roughly equivalent items.Select(x => x.MenuItemId);

我写了一个小型的实用程序类(啊,我知道),来包装这个功能:
static class Gen<TModel, TProp> {
    public static Func<TModel, TProp> SelectorExpr(string propertyName) {
        var pExpr = Expression.Parameter(typeof (TModel));
        var mExpr = Expression.Property(pExpr, propertyName);
        var lExpr = Expression.Lambda<Func<TModel, TProp>>(mExpr, pExpr);
        return lExpr.Compile();
    }
}

使用方法如下:
var results = items.Select(Gen<MenuItem, object>.SelectorExpr("MenuItemId"));

7

注意:如果您知道设计时lambda表达式的样子(而不是基于编译时变量计算),那么下面的代码应该生成您需要的表达式树:

Expression<Func<MenuItem, object>> lambda = x => x.MenuItemId;

如果这些部分本身总是相同的,那么就不需要逐个构建表达式。 ;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接