Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 派生类中可克隆的_C#_Icloneable - Fatal编程技术网

C# 派生类中可克隆的

C# 派生类中可克隆的,c#,icloneable,C#,Icloneable,假设我有一个类a,和从a派生的B: 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) 建议的方法是什么?在B

假设我有一个类
a
,和从
a
派生的
B

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) 建议的方法是什么?在
B
中使用
new
或将
A.Clone()
声明为
virtual
override


(2) 如果在
A
中有一些成员在
A.Clone()
中被正确克隆,那么在
B.Clone()
中有没有一种简单的方法来克隆他们,或者如果你有权访问你的源代码(我猜这里就是这种情况),我也必须在
B.Clone()
中显式克隆他们然后绝对地将其声明为
virtual
,并覆盖它。如果使用
new
隐藏基本
Clone
,可能是个坏主意。如果任何代码不知道它正在使用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
关键字隐藏基本实现,下面是一个可能发生的情况的示例。使用一个示例实现(表面上看起来不错)

但当你使用它时:

B b = new B();
A a = b;
B bCopy = (B)a.Clone();
//"Clone A called" Throws InvalidCastException! We have an A!
B b = new B();
A a = b;
B bCopy = (B)a.Clone();
//"Clone A called" Throws InvalidCastException! We have an A!