2013-10-16 66 views
2

在我開始之前,我知道還有其他幾個問題「回答」了這個問題,但不是我能夠理解的方式。這裏就是我指的是: Deep copying in C#C#對象複製說明?

Why Copying in C# is a terrible idea

我所做的研究公平一點,我希望有人能向我解釋如何將對象設置爲另一個對象的值。

例如,讓我們說:

myObject bob; 
bob = new myObject(); 
myObject joe 
joe = bob 

據我研究,joe現在指向的bob bob的實例。這些物體是否仍然獨立運作?

我將如何創建兩個對象,將一個對象的內容複製到另一個對象,並將它們設爲兩個單獨的對象,它們的字段,方法和事件是分開發生的?

我很抱歉再次問這個問題,但我似乎無法找到一個對我來說在其他地方有意義的解釋。

+0

上述分配後,bob和joe指向內存中的同一實例。鮑勃和喬可以被認爲是指針變量。要創建副本,請創建一個新實例,然後複製每個成員。當然,這可以用一種方法進行編碼。 –

+0

我會問自己的第一個問題是'爲什麼我需要這個對象的確切副本?'如果您發現需要大量相互獨立的對象的相似/相同副本,則可以考慮查看對象工廠樣式模式。 – Vassi

+0

你能詳細說明一下哪些具體的答案不適合你嗎?似乎沒有任何其他問題,這些答案缺乏。看起來好像你只是在說「我不明白答案」,這不是一個真正的問題,如果它被解釋爲一個問題,就不可能回答。 –

回答

3

讓我們通過各行:

myObject bob; // Creates a variable of type myObject, but it doesn't point anywhere 
bob = new myObject(); // bob now points to a newly created myObject instance 
myObject joe; // Creates a variable of type myObject, but it doesn't point anywhere 
joe = bob; // joe now refers to the same object as bob 

要記住的重要一點是,最後一行拷貝超過參考本身的價值。如果bob指向地址1000,那麼joe也將指向那裏。因此,如果您更改此地址上的任何數據,joebob都將指向相同的數據。

但是,歡迎您將joe設置爲在其他地方,它不會影響bob。換句話說:

joe = null; // This will not null out bob 

如果你想創建的myObject一個全新例如,你必須這樣做:

joe = new myObject(); // This will also not affect bob 

現在,如果你想創建一個在內存myObject拷貝過來所有現有實例的屬性的新實例,你必須這樣做你自己:

joe = new myObject(); 
joe.X = bob.X; // Assuming X is not a reference itself 
joe.Y = bob.Y; // ...or you'd have to do this recursively 

.NET不提供爲您執行此複製的方法。一個常見的模式是讓爲myObject()一個構造函數的myObject並複製其所有屬性的實例:

joe = new myObject(bob); 
6

它們都指向相同的實例。如果您希望兩個單獨的實例使用new運算符創建第二個實例。

2

是,bobjoe將兩者指向完全相同的對象那裏。

複製對象確實需要在每個類的基礎上完成。假設你有一個只有值類型的類(可能有一些整數和字符串)。複製每個字段都可以正常工作。

但是現在想象一下,如果你的類持有對其他對象的引用(可能),如果你只是複製這個對象字段,你現在將有兩個不同的實例共享一些數據(打開文件,網絡插座等)。因此,爲了可靠地複製對象,應該讓該對象創建自己的副本,因爲它知道它擁有哪種類型的數據。

所以答案是沒有安全的通用方式複製C#中的對象。

2

您在這裏混淆了數據與方法。數據定義了一個對象是什麼。例如:circleradius 2.方法對該數據起作用,例如IncreaseRadius()當您複製時,此數據被複制,而不是方法。方法僅對類數據進行操作,並生成特定於類數據的輸出。

不,他們都指向同一個對象。 bobjoe只是2個變量,它們持有對內存中同一對象的引用。如果您通過bob更改數據並從joe讀取數據,您將獲得新的價值。

標準的方法是實現ICloneable接口並使用它來創建深層副本。由此我的意思是你必須在Clone方法中創建一個新對象,並將每個數據成員複製到新創建的對象。如果數據是另一種參考類型,那麼您也必須克隆它。