将对象属性(包括具有私有设置器的属性)深层复制到相同类型的另一个对象

时间:2018-12-10 18:49:57

标签: c# properties copy

我做过一些研究,只发现了实际上将您的属性从一个对象复制到另一个对象的“表面”方法,例如:

public static void CopyPropertiesTo<T, TU>(this T source, TU dest)
{
    var sourceProps = typeof(T).GetProperties().Where(x => x.CanRead).ToList();
    var destProps = typeof(TU).GetProperties()
        .Where(x => x.CanWrite)
        .ToList();
    foreach (var sourceProp in sourceProps)
    {
        if (destProps.Any(x => x.Name == sourceProp.Name))
        {
            var p = destProps.First(x => x.Name == sourceProp.Name);
            if (p.CanWrite)
            { // check if the property can be set or no.
                p.SetValue(dest, sourceProp.GetValue(source, null), null);
            }
        }
    }
}

上述方法的问题在于,它也不会复制私有字段

我有一个这样的班级:

class myType{
    public object prop1;
    private bool flag;
    private otherType prop2; //recursive deep property copy loop needed on this object.

    myType(bool flag){
        this.flag = flag;
    }
}

现在让我们假设我将在这两个类上运行上述方法:

myType obj1 = new myType(false);
myType obj2 = new myType(true);
obj1.CopyPropertiesTo(obj2);

结果将是obj2.flag的值将保持不变`。

我正在寻找一种实际上 deep 复制所有属性的方法,包括具有私有设置器的属性。

1 个答案:

答案 0 :(得分:0)

这是因为Type.GetProperties仅返回属性。您要搜索的基本上与上面的CopyPropertiesTo相同,但是您想用GetProperties替换GetFields。您还需要在方法的参数中指定BindingFlags以获得私有成员。

尝试一下:

public static void CopyFieldsTo<T, TU>(this T source, TU dest)
{
    var sourceFields = typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).ToList();
    var destFields = typeof(TU).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).ToList();
    foreach (var sourceField in sourceFields)
    {
        if (destFields.Any(x => x.Name == sourceField.Name))
        {
            var f = destFields.First(x => x.Name == sourceField.Name);
            f.SetValue(dest, sourceField.GetValue(source));
        }
    }
}