4

假设我有一个类AB它派生自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()asvirtualoverridein B?

(2) 如果有一些成员 inA并正确克隆 in A.Clone(),是否有一种简单的方法可以克隆它们,B.Clone()或者我是否也必须显式克隆它们B.Clone()

4

1 回答 1

9

如果您可以访问您的源(我猜这里就是这种情况),那么绝对将其声明为virtual并覆盖它。如果隐藏基地可能是个坏主意Clonenew如果任何代码不知道它正在使用 a 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!
于 2012-12-31T16:16:26.987 回答