Недавно друг спросил меня, почему в С# нет такой функции, как функция clone. Но я действительно не понимаю, почему использовать клон, кроме этого:
SomeClass cls = new SomeClass();
SomeClass cls2 = cls;
Зачем вам использовать = cls.clone() ;, так вот так:
SomeClass cls = new SomeClass();
SomeClass cls2 = (SomeClass) cls.clone();
Я никогда не понимал разницы. Может ли кто-нибудь объяснить, какой из них лучше, и какая разница?
Что вы здесь сделали?
SomeClass cls = new SomeClass();
SomeClass cls2 = cls;
Создавал TWO referencec для ONE, одного и того же объекта. Картинка (может быть немного уродливой, потому что я сам ее нарисовал;)):
Однако в этом коде:
SomeClass cls = new SomeClass();
SomeClass cls2 = (SomeClass) cls.clone();
Вы создали TWO-объекты с двумя ссылками, где второй объект является копией первого объекта. cls указывает на первый объект, а cls2 указывает на второй объект. Jvm придется зарезервировать место для двух разных объектов, а не только для одного. Картина:
Вопрос всегда, если вы хотите, чтобы изменения в них влияли на другие (для изменяемых объектов). Например
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()
SomeClass cls = new SomeClass();
Это ссылка на объект SomeClass.
SomeClass cls2 = cls;
Это ссылка на тот же объект.
SomeClass cls3 = (SomeClass) cls.clone();
Это ссылка на другой объект, который был клонирован из исходного. Рассмотрим следующие случаи
cls2.setState(newState)
в этом случае вы измените исходный объект (на который ссылаются cls
и cls2
).
cls3.setState(newState)
В этом случае только cls3
будет изменен. Исходный объект (cls
и cls2
) не будет изменен.
clone()
дает вам мелкую копию исходного объекта. Состояние переменных будет таким же, как и у оригинала. new MyClassObject()
возвращает новый объект, а не клонированный или скопированный.