Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
780 views
in Technique[技术] by (71.8m points)

c# - Proper way to implement ICloneable

What is the proper way of implementing ICloneable in a class hierarchy? Say I have an abstract class DrawingObject. Another abstract class RectangularObject inherits from DrawingObject. Then there are multiple concrete classes like Shape, Text, Circle etc. that all inherit from RectangularObject. I want to implement ICloneable on DrawingObject and then carry it down the hierarchy, copying available properties at each level and calling parent's Clone at the next level.

The problem however is that since the first two classes are abstract, I cannot create their objects in the Clone() method. Thus I must duplicate the property-copying procedure in each concrete class. Or is there a better way?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can easily create a superficial clone with object's protected method MemberwiseClone.

Example:

   public abstract class AbstractCloneable : ICloneable
   {
      public object Clone()
      {
         return this.MemberwiseClone();
      }
   }

If you don't need anything like a deep copy, you will not have to do anything in the child classes.

The MemberwiseClone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, the reference is copied but the referred object is not; therefore, the original object and its clone refer to the same object.

If you need more intelligence in the cloning logic, you can add a virtual method to handle references :

   public abstract class AbstractCloneable : ICloneable
   {
      public object Clone()
      {
         var clone = (AbstractCloneable) this.MemberwiseClone();
         HandleCloned(clone);
         return clone;
      }

      protected virtual void HandleCloned(AbstractCloneable clone)
      {
         //Nothing particular in the base class, but maybe useful for children.
         //Not abstract so children may not implement this if they don't need to.
      }
   }


   public class ConcreteCloneable : AbstractCloneable
   {
       protected override void HandleCloned(AbstractCloneable clone)
       {
           //Get whathever magic a base class could have implemented.
           base.HandleCloned(clone);

           //Clone is of the current type.
           ConcreteCloneable obj = (ConcreteCloneable) clone;

           //Here you have a superficial copy of "this". You can do whathever 
           //specific task you need to do.
           //e.g.:
           obj.SomeReferencedProperty = this.SomeReferencedProperty.Clone();
       }
   }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...