I am currently building an object model for HL7 messages. Without diving into those, the basic structure that we have looks similar to this:
- Base Object
- Intermediary Object
- DeepMessage1
- DeepMessage2
 
- Message1
- Message2
 
- Intermediary Object
I want to have a deep copy/clone that will copy all of the similar properties from DeepMessage1 to DeepMessage2 or Message1 or Message2.
public class BaseObject
{
    PersonName Name; //A personName includes a first name and last name.
}
public class IntermediaryObject : BaseObject
{
    Accident accident; //An accident codes and a description.
}
public class Message1 : BaseObject
{
    //this class doesn't actually contain any special handling, just used for 
    //easy understanding for the API
}
public class Message2 : BaseObject
{
    DateTime AdmissionDate; //Note the admission date is also contained in
                            //DeepMessage1, but not DeepMessage2
}
public class DeepMessage1 : IntermediaryObject
{
    DateTime AdmissionDate; //Note this property is also contained in Message2 and 
                            //needs to be copied
}
public class DeepMessage2 : IntermediaryObject
{
    DateTime DischargeDate;
}
With that structure in mind, I want to be able to create a deep copy of every property that one object shares with another. This other question was a really good start, but ultimately I couldn't use reflection as that was shallow cloning, and serialization requires the exact same object.
I ended up with this code, but it only performs a shallow copy.
public T Copy<T>() where T : new()
{
    T destination = new T();
    if (destination is HL7Message)
    {
        foreach (var destinationProperty in destination.GetType().GetProperties())
        {
            foreach (var sourceProperty in this.GetType().GetProperties())
            {
                if (destinationProperty.Name.Equals(sourceProperty.Name))
                {
                    destinationProperty.SetValue(destination, destinationProperty.GetValue(this, null), null);
                }
            }
        }
        return destination;
    }
    else
    {
        throw new InvalidOperationException("The destination copy type is not an HL7Message object");
    }
}
I was hoping that in my if (destinationProperty.Name.Equals(sourceProperty.Name)) block I could attempt to call Copy on any properties that are of a specific base type (which all of the objects in my library extend). However, I couldn't get the Copy in that section to work as I can't determine the T at runtime.
Do I just need to have a separate type of Copy for the specific objects and have the Messages use the Copy or is there a way to do this that is so damn crazy?
 
     
    