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

时间:2015-05-09 21:09:12

标签: c# lambda

我正在尝试创建这个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 个答案:

答案 0 :(得分:8)

您想要使用已声明的项目和道具

创建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。

例如,如果您有一个名为MenuItem的{​​{1}}集合,并且您想要所有items

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

答案 1 :(得分:6)

请注意:如果你知道lambda表达式在设计时的样子(而不是在编译时根据变量计算),那么下面的代码应该是你需要的表达式树:

func round(x : Double, precision : Int) -> Double {
    return Darwin.round(pow(10.0, Double(precision)) * x) / pow(10.0, Double(precision))
}

如果碎片本身始终相同,则无需逐个构建表达式。 ;)