Question

I need to clone object (class, not struct) in .net 4.5 (c#).
I found two ways:

  1. Implement ICloneable Interface
  2. Create own clone mechanism like this famous SO answer

I like fist way - it's easier, but I also found Not Implpement ICloneable Interface, but it's very old post and on MSDN I can't find that this interface deprecated.

Could any says me, it is safety to use ICloneable in .net 4.5?

Was it helpful?

Solution 2

You should not use the IClonable interface.

Here's a blog from Brad Abrams discussing why not from several years ago. Basically, the reasons are outlined by Tim Schmelter's answer, but this blog is from the horse's mouth.

In relation to implementing cloning via serialization, there is a slightly better way available now because we can specify StreamingContextStates.Clone to allow the cloning to work better with things like unmanaged handles.

There's a canonical implementation in "CLR via C# 4th Edition" by Jeffrey Richter which goes like this:

public static object DeepClone(object original)
{
    using (var stream = new MemoryStream())
    {
        var formatter = new BinaryFormatter
        {
            Context = new StreamingContext(StreamingContextStates.Clone)
        };

        formatter.Serialize(stream, original);
        stream.Position = 0;

        return formatter.Deserialize(stream);
    }
}

Or the strongly typed variant:

public static T DeepClone<T>(T original)
{
    if (!typeof(T).IsSerializable)
    {
        throw new ArgumentException("The type must be serializable.", "original");
    }

    if (ReferenceEquals(original, null))
    {
        return default(T);
    }

    using (var stream = new MemoryStream())
    {
        var formatter = new BinaryFormatter
        {
            Context = new StreamingContext(StreamingContextStates.Clone)
        };

        formatter.Serialize(stream, original);
        stream.Position = 0;

        return (T) formatter.Deserialize(stream);
    }
}

I reckon you should use that (where possible) instead of implementing IClonable.

OTHER TIPS

IClonable is just an interface so it does nothing until you implement it. The post which suggests to not use IClonable mentions why: it is not clear if Clone is implemented as deep- or as shallow copy.

So just provide a Copy or DeepClone method and everyone knows what happens.

Quote to explain the two terms:

There are two general ways to implement ICloneable, either as a deep, or non-deep copy. Deep-copy copies the cloned object and all objects referenced by the object, recursively until all objects in the graph are copied. A non-deep copy (referred to as shallow if only the top level references are copied) may do none, or part of a deep copy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top