Question

Assume I have a class A, and B which derives from A:

class A : ICloneable
{
    public object Clone() {...}
}

class B : A, ICloneable
{
    public object Clone() {...}
}

which gives

'B.Clone()' hides inherited member 'A.Clone()'. Use the new keyword if hiding was intended.

warning.

(1) What is the suggested way? using new or declaring A.Clone() as virtual and override in B?

(2) If there are some members in A and properly cloned in A.Clone(), is there an easy way to clone them in B.Clone() or do I have to explicitly clone them in B.Clone() also?

Was it helpful?

Solution

If you have access to your source (which I'm guessing is the case here) then absolutely declare it as virtual and override it. If hide the base Clone with new might be a bad idea. If any code doesn't know that it's working with a B, then it will fire the wrong clone method and not return a proper clone.

Regarding the assignment of properties, perhaps consider implementing copy constructors and each level can handle its own cloning:

    public class A : ICloneable
    {
        public int PropertyA { get; private set; }

        public A()
        {

        }

        protected A(A copy)
        {
            this.PropertyA = copy.PropertyA;
        }

        public virtual object Clone()
        {
            return new A(this);
        }
    }

    public class B : A, ICloneable
    {
        public int PropertyB { get; private set; }

        public B()
        {

        }

        protected B(B copy)
            : base(copy)
        {
            this.PropertyB = this.PropertyB;
        }

        public override object Clone()
        {
            return new B(this);
        }
    }

Each copy constructor calls the base copy constructor passing itself down the chain. Each inheritance level copies the properties belonging to it directly.

EDIT: If you use the new keyword to hide the base implementation, here's an example of what might happen. With a sample implementation (which on the face of it looks fine)

public class A : ICloneable
{
    public int PropertyA { get; protected set; }

    public object Clone()
    {
        Console.WriteLine("Clone A called");
        A copy = new A();
        copy.PropertyA = this.PropertyA;
        return copy;
    }
}

public class B : A, ICloneable
{
    public int PropertyB { get; protected set; }

    public new object Clone()
    {
        Console.WriteLine("Clone B called");
        B copy = new B();
        copy.PropertyA = this.PropertyA;
        copy.PropertyB = this.PropertyB;
        return copy;
    }
}

But when you use it:

B b = new B();
A a = b;
B bCopy = (B)a.Clone();
//"Clone A called" Throws InvalidCastException! We have an A!
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top