我一遍又一遍地得到同样的问题,我想要引用的对象被复制,或者我想要复制的对象被引用。当我使用=运算符时会发生这种情况。
例如,如果我将对象发送到另一个表单,即:
SomeForm myForm = new SomeForm();
SomeObject myObject = new SomeObject();
myForm.formObject = myObject;
...然后在表单中修改对象,原始对象不会被修改。就好像复制了对象而没有引用对象。然而,当我这样做时:
SomeObject myObject = new SomeObject();
SomeObject anotherObject = new SomeObject();
anotherObject = myObject;
...然后修改anotherObject
,myObject
也会被修改。
最严重的情况是当我尝试克隆我定义的一个对象时:
public class SomeObject
{
double value1, value2;
//default constructor here
public SomeObject(val1, val2)
{
value1 = val1;
value2 = val2;
}
public void Clone(SomeObject thingToCopy)
{
this.value1 = thingToCopy.value1;
this.value2 = thingToCopy.value2;
}
}
当我这样做时......
SomeObject obj1 = new SomeObject(1, 2);
SomeObject obj2 = new SomeObject();
obj2.Clone(obj1);
引用了 ... obj1
,对obj2
的任何修改都会更改obj1
。
除了上面的克隆方法外,似乎总是复制int, double, string
等系统对象。
我的问题是,没有考虑在函数中使用ref
关键字,何时复制对象以及何时在每种情况下引用对象(即传递给函数时)当设置为其他对象时(如上面的前两个例子),复制成员变量时,如第三个例子等)?
答案 0 :(得分:45)
如果不花费大量时间仔细挑选你的话,很难回答这类问题。
我已经在一些您认为有用的文章中这样做了:
这并不是说这些文章是完美的 - 当然 - 远非如此 - 但我已经尽力了。
我认为一个重要的事情是将两个概念(参数传递和参考与值类型)分开来。
查看您的具体示例:
SomeForm myForm = new SomeForm();
SomeObject myObject = new SomeObject();
myForm.formObject = myObject;
这意味着myForm.formObject
和myObject
引用SomeObject
的相同实例 - 就像两个人有单独的纸张一样,每个人都有相同的地址。如果你去一张纸上的地址并把房子漆成红色,那么去第二张纸上的地址,你会看到一个红房子。
您不清楚“然后修改表单中的对象”是什么意思,因为您提供的类型是不可变的。没有办法修改对象本身。您可以更改myForm.formObject
以引用SomeObject
的其他实例,但这就像在一张纸上涂写地址并在其上写一个不同的地址一样。这不会改变另一篇论文上的内容。
如果您可以提供一个简短但完整的程序,其行为您不理解(理想情况下是一个控制台应用程序,只是为了让事情变得更简单和更简单),那么在具体内容中讨论事情会更容易术语
答案 1 :(得分:6)
public void MyMethod(ref int a) { a = 25 }
int i = 20;
MyMethod(ref i); //Now i get's updated to 25.
希望有所帮助:)
答案 2 :(得分:1)
关于克隆对象,如果从一个对象复制到另一个对象的值是引用类型,那么对原始对象中这些值的任何修改都会影响复制对象中的值(因为它们只是对它们的引用)对象)
如果您需要克隆具有引用类型属性的对象,则需要使这些类型可克隆,或者通过根据需要实例化新实例来手动复制它们。
考虑使用IClonable界面虽然它不是最好的解决方案imho。