尝试创建表达式树以执行对象映射器类型。
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 }
}
}
答案 0 :(得分:4)
你可以这样写:
Type sourceType = typeof(Source);
ParameterExpression source = Expression.Parameter(sourceType);
var createModel = Expression.New(typeof(Dest));
var bindings = new List<MemberAssignment>();
foreach (var prop in sourceType.GetProperties())
{
var v1 = Expression.Call(source, prop.GetGetMethod());
var destinationProperty = typeof(Dest).GetProperty(prop.Name);
bindings.Add(Expression.Bind(destinationProperty, v1));
}
var init = Expression.MemberInit(createModel, bindings);
var lambdaExpression = Expression.Lambda<Func<Source, Dest>>(init, source);
将生成以下内容:
Param_0 => new Dest()
{
A = Param_0.get_A(),
B = Param_0.get_B()
}
测试它:
var s = new Source { A = 5, B = "TEST" };
var res = lambdaExpression.Compile()(s);
产生Dest
的对象:
A 5
B TEST