2010-03-21 124 views
3

我有這樣一個場景:對象分配

MyClass obj1 = new MyClass(); 
............//some operations on obj1; 
MyClass obj2 = new MyClass(); 
obj2 = obj1; 

我有以下問題:如果我修改任何參數,它在這兩個對象受到影響(既指同一位置) - 但是,當我修改obj2參數,它不應該修改obj1中的參數值(也就是說,兩者都不應該指向相同的位置)。我怎樣才能做到這一點?請幫幫我。 我不能在這裏克隆,因爲myclass沒有實現ICloneable,我不能修改myclass。 如果我通過序列化和反序列化克隆,它會是一個深度克隆嗎?

+0

「MyClass」的界面是什麼? – kennytm 2010-03-21 09:33:33

+0

MyClass正在實施ISerializable .. – sandhya 2010-03-21 10:22:34

+0

是的,它將是一個非常低效的深層克隆。 – kennytm 2010-03-21 10:22:55

回答

4

讓您myclass實施ICloneable,並使用

myclass obj1 = new myclass(); 
... 
myclass obj2 = obj1.Clone(); 

(順便說一句,該約定是使用CamelCase Pascal case來命名類,即MyClass這樣其他用戶就不會混淆爲一個變量。)


如果myclass不可克隆,則需要查找obj1中的所有特徵值並將它們複製到obj2,例如

myclass obj2 = new myclass(); 
obj2.color = obj1.color; // .Clone(); 
obj2.size = obj1.size; 
obj2.numberOfLimbs = obj1.numberOfLimbs; 
// etc. 
+0

一個尼特:MyClass是帕斯卡的情況。 camelCase是當初始字符是小寫字母並且裏面有大寫字母時。 – 2010-03-21 08:04:44

+0

我一直認爲CamelCase以大寫字母開頭(即使我知道這是錯誤的)。我想到一隻真正的駱駝,並將它長長的脖子和頭部算作顛簸之一。對我來說更有意義。 – 2010-03-21 08:37:47

+0

沒問題,但是你的camelCase的定義實際上是PascalCase,並不符合其他人認爲的駱駝套件。 – 2010-03-21 09:58:27

0

爲了增加KennyTM的回答,object Clone()方法使調用對象的副本。有兩種類型的副本可以製作。深拷貝和淺拷貝。在KennyTM的回答中,做了一個深層次的複製。在深層複製中,原始對象和複製對象完全相互獨立。欲瞭解更多信息,請閱讀文檔ICloneable

和克隆()聲明可能是這樣的:

public object Clone() 
{ 
Myclass obj=new Myclass(); 
return obj; 
} 
+0

這裏MYClass沒有實現ICloneable,我不能修改這個類。有沒有其他的選擇,而不是克隆()? – sandhya 2010-03-21 07:49:02

+0

@sandhya,在這種情況下,我認爲複製構造函數可能會有所幫助。 – Zaki 2010-03-21 08:08:26

+0

但無論如何,您需要訪問Myclass。 – Zaki 2010-03-21 08:11:26

3

與對象分配要記住的是變量和對象之間的區別。

在你的例子中,obj1obj2是變量。變量可以指向對象,但它們本身不是對象。

您的代碼所做的是在最後告訴obj1obj2指向同一個對象。

你想要做的是創造一個新的對象 - 正如其他人指出的那樣,通過接口最容易完成。

1

在myClass上有一個擴展方法:GetDeepCopy 手動獲取obj的副本,並在GetDeepCopy中返回。

因此,像:
myclass obj1 = new myclass();
...
myclass obj2 = obj1.etDeepCopy();

0

假定對象的類型很簡單,你能簡單地編寫執行一種MemberwiseClone例如函數

MyClass obj = new MyClass(); 
// do your thing 
MyClass objCopy = new MyClass(); 
objCopy.IamInt = obj.IamInt; 
objCopy.IamString = obj.IamString; 

此外更一般地說,我發現這篇文章在考慮引用時非常有幫助。

0

KennyTM的建議將是默認選擇。但是,由於您無法像在評論中提到的那樣修改源代碼,因此您可能需要編寫大量代碼,如果涉及私有成員,則可能會反射。

如果您可以使用開源庫,並且如果待克隆對象的對象圖中的所有類型都具有默認構造函數,那麼可以在我的庫中檢出實用程序:Fasterflect's DeepClone()。這個實用程序毫不意外地執行深度克隆並處理循環引用;該實現由CIL代碼生成支持,所以性能不應該比手工反射代碼好得多。

0

如果MyClass的聲明一個拷貝構造函數,你可以做一個

MyClass obj2=new MyClass(obj1). 

否則,你應該創建一個函數來複製爲:

MyClass CopyMyClassObject(MyClass obj1) 
{ 
    MyClass Result = new MyClass(); 
    Result.Value1 = obj1.Value1; 
    Result.Value2 = obj1.Value2; 
    //... 
    Result Valuen = obj1.Valuen; 
    Result.Object1.Value1 = obj1.Object1.Value1; 
    Result.Object1.Value2 = obj1.Object1.Value2; 
    //... 
    Result.Object1.Valuen = obj1.Object1.Valuen; 
    //..and so on until all values have been assigned 
    //The actual assignments will use whatever methods are provided in MyClass, of course. 
    return Result; 
} 

之後,在你的代碼,你只需做:

MyClass obj2 = CopyMyClassObject(obj1); 

我希望這可以幫助。