最近有一位朋友问我为什么C#中没有克隆功能。但我真的不明白为什么要使用克隆,除此之外:
SomeClass cls = new SomeClass();
SomeClass cls2 = cls;
为什么要使用= cls.clone();,就像这样:
SomeClass cls = new SomeClass();
SomeClass cls2 = (SomeClass) cls.clone();
我从未理解过这种差异。任何人都可以解释哪一个更好,有什么区别?
答案 0 :(得分:7)
你在这里做了什么
SomeClass cls = new SomeClass();
SomeClass cls2 = cls;
创建了一个同一个对象的两个引用。图片(可能有点难看,因为我自己画了;)):
但是在这段代码中:
SomeClass cls = new SomeClass();
SomeClass cls2 = (SomeClass) cls.clone();
您创建了具有两个引用的TWO对象,其中第二个对象是第一个对象的副本。 cls指向第一个对象,而cls2指向第二个对象。 Jvm必须为两个不同的对象预留空间而不是一个。图片:
答案 1 :(得分:3)
如果你想要改变一个影响另一个(对于可变对象),问题总是存在。例如
SomeClass cls = new SomeClass();
SomeClass cls2 = cls; //copies the reference, not the object
cls2.doubleEverything();
在上面的示例中,只有一个对象,所以在cls2
引用的对象中,所有内容都加倍,这是cls1
引用的同一个对象,所以他们都看到了改变。
SomeClass cls = new SomeClass();
SomeClass cls2 = (SomeClass) cls.clone();
cls2.doubleEverything();
两个变量引用了两个对象,对(引用的对象)cls2的更改不会影响cls。
所有这一切都假设clone
正确实施,“正确”的定义根据具体情况而变化。它可能只是一个浅层副本,总是要警惕.clone()
答案 2 :(得分:2)
SomeClass cls = new SomeClass();
这是对象SomeClass的引用。
SomeClass cls2 = cls;
这是对相同对象的引用。
SomeClass cls3 = (SomeClass) cls.clone();
这是对从原始对象克隆的其他对象的引用。考虑下一个案例
cls2.setState(newState)
在这种情况下,您将更改原始对象(由cls
和cls2
引用)。
cls3.setState(newState)
在这种情况下,只会更改cls3
。原始对象(cls
和cls2
)不会更改。
答案 3 :(得分:0)
clone()
为您提供原始对象的浅表副本。变量的状态与原始状态的状态相同。 new MyClassObject()
返回一个新的Object,而不是克隆或复制的。