【发布时间】:2016-03-30 22:25:22
【问题描述】:
试图创建一个表达式树来做一个对象映射器类型的事情。
Type ts = typeof(Source);
Type td = typeof(Dest);
ParameterExpression val = Expression.Parameter(ts);
ParameterExpression ret = Expression.Parameter(td);
PropertyInfo[] propsS = ts.GetProperties();
PropertyInfo[] propsD = td.GetProperties();
List<Expression> lst = new List<Expression>();
foreach (PropertyInfo pi in propsS)
{
PropertyInfo piD = propsD.Where(x => x.Name == pi.Name).FirstOrDefault();
if (piD != null)
{
MethodInfo ge = pi.GetGetMethod();
MethodInfo se = piD.GetSetMethod();
var v1 = Expression.Call(val, ge);
var v2 = Expression.Call(ret, se, v1);
lst.Add(v2);
}
}
lst.Add(Expression.Return(Expression.Label(td), ret));
BlockExpression block = Expression.Block(
new[] { ret },
lst.ToArray()
);
//Func<Source, Dest> v = Expression.Lambda<Func<Source, Dest>>(block, val).Compile();
var v = Expression.Lambda(block, val);
这就是我现在所拥有的......它非常接近,但看不出我错过了什么......
v出来:
.Lambda #Lambda1<System.Action`1[ConsoleApplication2.Source]>(ConsoleApplication2.Source $var1) {
.Block(ConsoleApplication2.Dest $var2) {
.Call $var2.set_S1(.Call $var1.get_S1());
.Call $var2.set_S2(.Call $var1.get_S2());
.Call $var2.set_I1(.Call $var1.get_I1());
.Call $var2.set_I2(.Call $var1.get_I2());
.Call $var2.set_S3(.Call $var1.get_S3());
.Call $var2.set_S4(.Call $var1.get_S4());
.Call $var2.set_S5(.Call $var1.get_S5());
.Return #Label1 { $var2 }
}
}
- 我需要在某处更新 $var2 吗?
- 有没有更好的方法来做分配?
- lambda 似乎看不到返回值...
- 我需要做块吗?还是有更好的方法?
【问题讨论】:
-
返回的 lambda 需要为
Action<Source, Dest>以便您传递两个对象,或者需要创建Dest并使用Func<Source,Dest>。您当前正在为var2定义一个局部变量,但从未构造(或传入)var2 -
@Rob -- 我想要 Func
结果,但编译器认为它仍然是一个动作,即使我有一个返回......我需要如何将代码修改为新的里面有 $var2 吗?
标签: c# tree expression