我想知道之間的不同,如果我有一類名爲Test,什麼是低於什麼是克隆方法和實例分配給另一個直接
Test test = new Test();
Test newTest = test;
Test newTest2 = test.Clone();
的區別是什麼newTest和newTest2之間有什麼不同? 任何人都可以提供幫助嗎? 在此先感謝!
我想知道之間的不同,如果我有一類名爲Test,什麼是低於什麼是克隆方法和實例分配給另一個直接
Test test = new Test();
Test newTest = test;
Test newTest2 = test.Clone();
的區別是什麼newTest和newTest2之間有什麼不同? 任何人都可以提供幫助嗎? 在此先感謝!
分配實例時,如果Test
是一個類,則實際上是複製引用,但test
和newTest
都將指向內存中的同一實例。
這意味着兩個變量指向相同的對象:
Test test = new Test();
test.Foo = 24;
Test newTest = test;
newTest.Foo = 42;
Console.WriteLine(test.Foo); // Prints 42!
Clone()
,在另一方面,典型地用於指示對象本身,這意味着test
和newTest2
將指向的副本,以不同的對象,所以上述不會發生。
請注意,如果測試是struct
(值類型),則直接賦值實際上是對象的完整(淺)副本(按值)。
Test newTest = test;
由於測試是引用類型(類),newTest
現在引用相同的對象test
。如果更改對象test
引用,那麼將反映在newTest
中,因爲它們都引用同一個對象。
Test newTest2 = test.Clone();
假設Clone()
返回一個新實例,並做了深拷貝(它確實取決於你的實現),newTest2
指的是一個完全獨立的對象,在test
的任何變化都不會影響它。
新測試實際上指向內存中與測試相同的對象,因此修改newTest將更改測試。 newTest2實際上是測試的副本。
作業只複製參考,而不是對象本身。
如果你的類實現IClonable.Clone
,它可以寫入執行深拷貝操作,也就是返回相同類型的新分配的對象,它的領域是原始的副本。當一個字段是一個引用類型時,該做什麼是一個有趣的問題:複製引用,或者深入複製引用的對象?例如,Object.MemberwiseClone
僅拷貝參考(這稱爲淺拷貝),但如果您選擇實施IClonable.Clone
,則可以自行決定。
要理解這種區別,必須先了解對象引用是什麼。由於術語「參考」用於指代許多不同的概念,所以我喜歡術語「對象ID」。要使用汽車類比,對象ID是帶有汽車VIN的紙條。如果您在油漆車間上面寫上一張寫有「VIN ZX357」的紙並要求商店將其塗成藍色,那麼商店不會將紙條塗成藍色,而是他們會找到具有該VIN號碼的汽車並將該車漆成藍色。
如果一個人Car
類型(這是引用類型)恰好保持「VIN ZX357」的變量Wuzzle
,和另一個變量Fuzzle
,和一個表示Fuzzle = Wuzzle
,然後將Fuzzle
- 像Wuzzle
保持「VIN ZX357」 。仍然會有一輛車。一張紙只有兩張紙,兩張紙都保持相同的VIN,因此是指同一輛車。像Wuzzle.Color=Purple
這樣的陳述將導致VIN爲ZX357的汽車被塗成紫色。檢查Fuzzle.Color
的請求將查看ZX357並報告它是紫色的。
如果不是說Fuzzle = Wuzzle
,一個曾表示Fuzzle = (Car)(Wuzzle.Clone())
,效果會創建一個新的汽車,這是就像VIN ZX357,除了它會有不同的VIN號碼(例如QL793)和Fuzzle
將持有新VIN,而不是3941QXY5)。說Wuzzle.Color = Orange
然後將車漆3941QXY5橙色,但它不會影響汽車QL793。
接口類型的變量被視爲與任何其他引用類型一樣。可以用IColorizable
代替Car
,其行爲將完全相同。
重要的是要注意,ICloneable
不是一個非常好的接口;一個更好的接口是ICloneable<T>
,它返回一個T
類型的對象。有兩個大的優勢,以這個接口:
ICloneable
,有必要強制轉換返回類型人願意對象的類型。這有點難看。 ICloneable<T>
消除了這個要求。ICloneable
,對於對象內的哪些對象引用應該原樣複製到克隆以及哪些對象本身應該被克隆,可能存在一些歧義。這種含糊不清的程度並不像一些人所認爲的那樣糟糕,但通用的ICloneable<T>
可以使它更清晰一些。例如,如果有一個對象CloneableSortedList<T>
,那麼在該列表上調用ICloneable<CloneableSortedList<T>.Clone()
應返回一個新的CloneableSortedList
,其中包含與原始類型相同的T型引用。相比之下,如果有一個CloneableSortedUserList
,調用ICloneable<CloneableSortedUserList>
應該返回一個新的CloneableSortedUserList
,它將用戶的屬性而不是用戶對象引用視爲值(因此如果它們是可變的,則複製它們)。
請告訴我 車C =新車的區別 和 d =(CAR)(c.Clone()) – Charlie 2017-02-11 20:54:58