gpt4 book ai didi

c# - 表达式树复制对象

转载 作者:太空宇宙 更新时间:2023-11-03 21:13:13 26 4
gpt4 key购买 nike

尝试创建表达式树来执行对象映射器类型的操作。

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 }
}
}
  1. 我需要在某个地方新建 $var2 吗?
  2. 有没有更好的分配方式?
  3. lambda 似乎没有看到返回值...
  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

关于c# - 表达式树复制对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36320831/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com