鉴于这个lambda,如何用表达式树手动编写它?

时间:2012-11-09 15:15:12

标签: c# lambda expression

class Program
{
    static void Main(string[] args)
    {
        Expression<Func<string[], Poco>> exp = a => new Poco { MyProperty1 = a[0], MyProperty2 = a[1], MyProperty3 = a[2] };
        var lambda = exp.Compile();

        var output = lambda(new[] {"one", "two", "three"});

        Console.WriteLine(output.MyProperty1);
    }
}

class Poco
{
    public string MyProperty1 { get; set; }
    public string MyProperty2 { get; set; }
    public string MyProperty3 { get; set; }
}

我对调用lambda的部分不感兴趣,这只是为了完整性。我完全迷失了试图导航表达树,这可能教会我如何钓鱼。

2 个答案:

答案 0 :(得分:1)

我现在没有时间翻译完整的树,但你可以做的一件事是编译你的代码,然后使用ildasm(或反射器等)来查看编译器正在做什么。您不能总是在自己的代码中完全相同,但它可以让您了解您想要的表达式。特别是,在这种情况下,你需要:

如果我稍后有时间,我会尝试构建一个完整的工作示例。

答案 1 :(得分:1)

private static Expression<Func<string[], Poco>> CreateExpr()
{
    ParameterExpression paramExpr = Expression.Parameter(typeof(string[]), "a");
    var newExpr = Expression.New(typeof(Poco));

    var memberExprs = Enumerable.Range(0, 3)
        .Select(i =>
        {
            string propertyName = "MyProperty" + (i + 1);
            var property = typeof(Poco).GetProperty(propertyName);
            Expression.Bind(property, Expression.ArrayIndex(paramExpr, Expression.Constant(i)));
        });

    var expr = Expression.MemberInit(newExpr, memberExprs);
    return Expression.Lambda<Func<string[], Poco>>(expr, paramExpr);
}