我想知道如何在表达式树中代表c#代码。
var list = new List<CustomClass>();
list.add(new CustomClass());
其中CustomClass是一些复杂的类型。
类似于如何使用Expression.NewArrayInit
初始化数组由于
答案 0 :(得分:5)
您提出的代码是:
// List<CustomClass> foo;
var listV = Expression.Variable(typeof(List<CustomClass>), "foo");
// new List<CustomClass>()
var newL = Expression.New(typeof(List<CustomClass>));
// foo = new List<CustomClass>()
var assV = Expression.Assign(listV, newL);
// new CustomClass()
var newEl = Expression.New(typeof(CustomClass));
// foo.Add(new CustomClass())
var addEl = Expression.Call(listV, "Add", null, newEl);
var be = Expression.Block(new[] { listV }, assV, addEl);
请注意,我正在给你一个块表达式......你可以将它放在一个更大的表达式中(或者基于它创建一个lambda),但它不能直接运行(因为它不是一个lambda表达式) )
lambda表达式的一个例子:
var be = Expression.Block(new[] { listV }, assV, addEl, listV);
var lambda = Expression.Lambda<Func<List<CustomClass>>>(be);
var func = lambda.Compile();
List<CustomClass> res = func();
(请注意,我正在更改be
变量)
答案 1 :(得分:3)
我建议使用集合初始化程序,而不是使用两个单独的语句。此时,您可以让编译器为您构建表达式树,因为它只是一个表达式:
Expression<Func<List<CustomClass>>> expr =
() => new List<CustomClass> { new CustomClass() };
使用表达式树的工具(例如LINQ提供程序)也更有可能理解树。
生成的树使用Expression.ListInitExpression
作为Expression.NewArrayInit
的等效列表。
手动编写等效代码有点痛苦,但如果你真的需要,你可以反编译编译器使用lambda表达式做的事情。