将对象属性(包括具有私有setter的属性)深度复制到同一类型的另一个对象



我做了一些研究,只发现了将属性从一个对象复制到另一个对象的"肤浅"方法,例如:

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复制所有属性,包括那些具有私有setter的属性。

这是因为Type.GetProperties只返回属性。您正在搜索的代码与上面的CopyPropertiesTo基本相同,但您希望用GetFields替换GetProperties。您还需要在方法的参数中指定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));
}
}
}

最新更新