W kilku miejscach spotkałem się z błędną definicją CopyTo oraz Clone. W przeciwieństwie do niektórych opinii, obydwie metody wykonują shallow copy. Jak wiemy w c# mamy reference oraz value types. Podczas płytkiego kopiowania, typy value po prostu klonowane są bit po bicie. W przypadku typów referencyjnych, wyłącznie adres jest kopiowany, nie wartość. Zatem po skopiowaniu typu referencyjnego będziemy mieli dwa wskaźniki, wskazujące na te same dane. Przykład:
SampleClass[] array = new SampleClass[] {sampleClass1, sampleClass2}; SampleClass []shallowCopy1=new SampleClass[2]; array.CopyTo(shallowCopy1, 0); SampleClass[] shallowCopy2= (SampleClass[])array.Clone();
W przypadku zarówno CopyTo jak i Clone otrzymamy płytką kopie. Elementy kopi zatem wskazują na te same obiekty. Zmodyfikowanie shalloCopy1[0].Text, zmieni tekst zarówno w shallowcopy2 jak i array. W powyższym przykładzie, stworzyliśmy zatem nowy obiekt tablicy, ale poszczególne elementy wskazują wciąż na takie same obiekty.
Jedyna różnica w zachowaniu to interfejs dostępowy. Clone tworzy nowy obiekt a CopyTo wypełnia już istniejący. W CopyTo przekazujemy już aktualną tablice, wcześniej zainicjalizowaną. Jeśli chcemy zatem scalić kilka tablic w jedną, powinniśmy skorzystać z CopyTo. W przeciwnym wypadku, myślę, że Clone jest bardziej user-friendly.
Głęboka kopia (deep copy) kopiuje wszystkie obiekty, nawet te referencyjne. Implementacja deep copy jest zatem trudniejsza oraz wolniejsza w wykonaniu. Jednym z podejść jest serializacja a potem deserialziacja- o tym jednak kiedy indziej.