2010-03-21 91 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); 

我希望这可以帮助。