【问题标题】:Cloneable in Derived Classes在派生类中可克隆
【发布时间】:2012-12-15 17:40:42
【问题描述】:

假设我有一个类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 或在B 中将A.Clone() 声明为virtualoverride

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

【问题讨论】:

    标签: c# icloneable


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-16
      • 2010-11-23
      • 2016-07-11
      • 2017-07-25
      • 1970-01-01
      • 2012-05-06
      • 2017-12-04
      相关资源
      最近更新 更多