[英]Given this lambda, how can I write it manually with expression trees?
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 的部分不感兴趣,这只是为了完整性。 我在尝试导航表达式树时完全迷失了方向,这可能会教我如何钓鱼。
我现在没有时间翻译完整的树,但是您可以做的一件事是编译您的代码,然后使用 ildasm(或反射器等)来查看编译器在做什么。 您不能总是在自己的代码中执行完全相同的操作,但它可以让您了解所需的表达式类型。 特别是,在这种情况下,您需要:
Expression.Parameter
创建参数 ( a
)Expression.New
创建新实例Expression.Bind
创建一个属性赋值Expression.MemberInit
分配新对象中的属性Expression.ArrayIndex
( a[0]
等)Expression.Constant
(0, 1, 2)Expression.Lambda
为整个事物创建一个Expression<TDelegate>
如果我以后有时间,我会尝试构建一个完整的工作示例。
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.