Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 表达式树复制对象_C#_Tree_Expression - Fatal编程技术网

C# 表达式树复制对象

C# 表达式树复制对象,c#,tree,expression,C#,Tree,Expression,尝试创建表达式树以执行对象映射器类型的操作 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.G

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

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);
Type ts=typeof(源代码);
类型td=类型(目的地);
ParameterExpression val=表达式参数(ts);
ParameterExpression ret=表达式参数(td);
PropertyInfo[]propsS=ts.GetProperties();
PropertyInfo[]propsD=td.GetProperties();
List lst=新列表();
foreach(PropertyInfo pi in propsS)
{
PropertyInfo piD=propsD.Where(x=>x.Name==pi.Name).FirstOrDefault();
如果(piD!=null)
{
MethodInfo ge=pi.getMethod();
MethodInfo se=piD.GetSetMethod();
var v1=表达式调用(val,ge);
var v2=表达式调用(ret、se、v1);
第一次增补(v2);
}
}
lst.Add(Expression.Return(Expression.Label(td)、ret));
BlockExpression block=Expression.block(
新[]{ret},
1.ToArray()
);
//Func v=Expression.Lambda(block,val).Compile();
var v=表达式λ(块,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 }
    }
}
.Lambda#Lambda1(ConsoleApplication2.Source$var1){
.Block(控制台应用程序2.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());
.调用$var2.set_S5(.Call$var1.get_S5());
.Return#Label1{$var2}
}
}
  • 我需要在某处新增加$var2吗
  • 有没有更好的方法来完成任务
  • lambda似乎看不到返回值
  • 我需要做这个街区吗?还是有更好的办法

  • 你可以这样写:

    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);
    
    并对其进行测试:

    var s = new Source { A = 5, B = "TEST" };
    var res = lambdaExpression.Compile()(s);
    
    生成
    Dest
    的对象:

    A    5   
    B    TEST 
    

    返回的lambda需要是
    Action
    以便传递两个对象,或者需要创建
    Dest
    并使用
    Func
    。您当前正在为
    var2
    定义一个局部变量,但是
    var2
    从未构造(或传入)@Rob--我想要Func结果,但编译器认为这仍然是一个操作,即使我有一个返回。。。我需要如何将代码修改为新的$var2?哈哈。。。是的,这很有效。。。比我尝试的方式简单多了。谢谢。我真的很感谢关于生成、测试和实际结果的后续章节,干杯
    A    5   
    B    TEST