And hopefully, with minimal fuss... (now would be a good time to read about reflection)
It is a simplistic approach, but what we want to do is to copy the properties in one object to another object that may or may not have said properties. Maybe we can use the property name as a match...
Lets try that approach.
This is what we want to do:
AnotherPerson anotherPerson = person.Copy<Person,AnotherPerson>();And this is one of the ways we can do it:
public static TTo Copy<TFrom,TTo>(this TFrom toCopyFrom) where TTo : new()
{
Type typeTo = typeof(TTo);
Type typeFrom = typeof(TFrom);
TTo instanceToCopyTo = new TTo();
//DeepClone the from object so you don't get reference copies.
//Came in handy, didn't it?
TFrom cloneOfFrom = toCopyFrom.DeepClone();
//For each property on the destination object.
PropertyInfo[] toProperties = typeTo.GetProperties();
foreach (PropertyInfo toProperty in toProperties.Where(toProperty => typeFrom.GetProperty(toProperty.Name) != null))
{
//set the value on the destination object.
toProperty.SetValue(
instanceToCopyTo,
typeFrom.GetProperty(toProperty.Name).GetValue(cloneOfFrom, null),
null);
}
return instanceToCopyTo;
}Create these classes on your Test class:
public class Person
{
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public List<Person> Siblings { get; set; }
}
public class AnotherPerson
{
public string Name { get; set; }
public List<Person> Siblings { get; set; }
public int ANonMatchingProperty { get; set; }
}And the Test:
[TestMethod]
public void CopyTest()
{
Person person =
new Person
{
Name = "Paulo Serra",
DateOfBirth = new DateTime(1972, 4, 2),
Siblings = new List<Person>
{
new Person
{
Name = "Andre Serra",
DateOfBirth = new DateTime(2002, 3, 27)
}
}
};
AnotherPerson anotherPerson = person.Copy<Person,AnotherPerson>();
Assert.AreEqual(person.Name, anotherPerson.Name);
Assert.AreNotSame(person.Siblings[0], anotherPerson.Siblings[0]);
Assert.AreEqual(person.Siblings[0].Name, anotherPerson.Siblings[0].Name);
}
For those that are paying attention, at the moment the copier only works because the AnotherPerson class defines the Siblings as Person, not AnotherPerson.
Well, guess we can solve that tomorrow, time to go for drinks.
