1
votes

I am using below class to do the Deep cloning with out serialization.

  public class AbstractClone
{

    public AbstractClone Clone()
    {
        Type typeSource = this.GetType();
        AbstractClone tObject = (AbstractClone)FormatterServices.GetUninitializedObject(typeSource);

        PropertyInfo[] propertyInfo = typeSource.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

        foreach (PropertyInfo property in propertyInfo)
        {
            if (property.CanWrite)
            {

                if (property.PropertyType.IsValueType || property.PropertyType.IsEnum || property.PropertyType.Equals(typeof(System.String)))
                {
                    property.SetValue(tObject, property.GetValue(this, null), null);
                }
                else
                {
                    object objPropertyValue = property.GetValue(this, null);

                     if (objPropertyValue == null)
                    {
                        property.SetValue(tObject, null, null);
                    }
                    else
                    {
                        property.SetValue(tObject, ((AbstractClone)objPropertyValue).Clone(), null);
                    }
                }
            }

        }
        return tObject;
    }
}

I am inheriting all the classes from this which needs to be cloned.

This works fine with all the objects except key Value Pairs or collections like SortedList,Dictionary etc

Could anyone suggest a way to clone the KeyValue pairs like SortedList of Dictionary.

2

2 Answers

0
votes

Deep copying is a serious task. First of all, your solution maybe simply impossible to use since it requires to inherit from your type, and you can not inherit 3rd party classes. Second problem is that it is not truly deep: you will copy all the references:

class Employee
{
  public string Name {get; set;}
  public Position Position {get; set;}
}
class Position
{
  public string Name {get;set;}
  public int ID {get;set;}
}

If you change Name property of Position property in original object, you'll see those changes in your copy. And if you try to upgrade your solution to run through properties recursively, you'll have to deal with cycle references.

However, this job is already done and you just have to look for a ready solution, for example, this one.

0
votes

Since you are already enforcing inheritance rule here, that only classes derived from AbstractClone will be deep cloned, you may instead stick a [Serializable] on it and get rid of enforcing inheritance. Serialization, followed by, deserialization is a guaranteed deep cloning technique.

[Serializable]
class T
{
    public int F1 { get; set; }
    public int F2 { get; set; }
}

T CloneT(T obj)
{
    var ms = new MemoryStream();

    var formatter = new BinaryFormatter();
    formatter.Serialize(ms, o);

    ms.Position = 0;

    var clone = (T)formatter.Deserialize(ms);

    return clone;
}

var o = new T { F1 = 5, F2 = 12 };
CloneT(o);