Клонируемый в производных классах

Предположим, у меня есть класс A, а также B который вытекает из A:

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

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

который дает

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

предупреждение.

(1) Каков предлагаемый способ? с помощью new или объявив A.Clone() как virtual а также override в B?

(2) Если в A и правильно клонируется в A.Clone()Есть ли простой способ клонировать их в B.Clone() или я должен явно клонировать их в B.Clone() также?

1 ответ

Решение

Если у вас есть доступ к вашему источнику (который, как я предполагаю, имеет место здесь), тогда абсолютно объявите его как virtual и переопределить это. Если скрыть базу Clone с new может быть плохая идея Если какой-либо код не знает, что он работает с Bтогда он запустит неправильный метод клонирования и не вернет правильный клон.

Что касается присвоения свойств, возможно, рассмотрите возможность реализации конструкторов копирования, и каждый уровень может обрабатывать свое собственное клонирование:

    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);
        }
    }

Каждый конструктор копирования вызывает базовый конструктор копирования, передавая себя по цепочке. Каждый уровень наследования копирует принадлежащие ему свойства напрямую.

РЕДАКТИРОВАТЬ: Если вы используете new Ключевое слово, чтобы скрыть базовую реализацию, вот пример того, что может произойти. С примером реализации (который на первый взгляд выглядит нормально)

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;
    }
}

Но когда вы используете это:

B b = new B();
A a = b;
B bCopy = (B)a.Clone();
//"Clone A called" Throws InvalidCastException! We have an A!
Другие вопросы по тегам