Reputation: 465
I have done some research and only found "superficial" methods that actually copy your properties from one object to another, such as:
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);
}
}
}
}
The problem with the above method is that it doesn't copy the private fields too.
I have a class like this:
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;
}
}
Now let's suppose I will run the above method on these two classes:
myType obj1 = new myType(false);
myType obj2 = new myType(true);
obj1.CopyPropertiesTo(obj2);
The outcome will be that obj2.flag
value will remain unchanged`.
I am looking for a method that actually deep copies all properties including those with private setters.
Upvotes: 2
Views: 1338
Reputation: 463
This is because Type.GetProperties
only returns properties. What you are searching for is essentially the same code as the CopyPropertiesTo
above, but you want to replace GetProperties
with GetFields
. You also need to specify BindingFlags
in the parameters of the method to get private members.
Try this out:
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));
}
}
}
Upvotes: 1