What’s the best way to implement the ICloneable interface in .NET? Don’t.

July 11, 2009 · 0 comments

in .net, Programming

When creating a .NET object that you need to be able to make copies of, it seems fairly intuitive, at least on the surface, that you would want to implement the ICloneable interface. Surprisingly enough, Microsoft actually recommends against implementing this interface:

Do not implement ICloneable

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.

Because the interface contract does not specify the type of clone performed, different classes have different implementations. A consumer cannot rely on ICloneable to let them know whether an object is deep-cloned or not.

If you need a cloning mechanism, define your own Clone, or Copy methodology, and ensure that you document clearly whether it is a deep or shallow copy.

My personal preference for handling my object copying needs is to define explicit ShallowCopy() and DeepCopy() methods, so that there is no question which type of object copy operation is going to be performed.

The other problem I have with the ICloneable interface is that the Clone() method returns a plain object, resulting in the need to perform a type cast on every call. Since there is no support for generics in the ICloneable interface, a developer is unable to explicitly define the return type of their Clone() method. However, if you choose to explicitly define your own ShallowCopy() and DeepCopy() methods, they can be strongly typed to your class, so that no type cast is required.

Why Microsoft hasn’t deprecated the ICloneable interface at this point is beyond me. They really should go beyond simply advising against its use, and officially deprecate the interface. This would allow them to define a much more explicit, and more importantly, an “opinionated” interface that would promote better programming practices.

Leave a Comment

Previous post:

Next post: