在复制我要引用的对象或引用我要复制的对象时,我不断遇到相同的问题。当我使用 = 运算符时会发生这种情况。
例如,如果我将对象发送到另一种形式,即:
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
等系统对象似乎总是被复制,除了上面的clone方法。
我的问题是,不考虑在函数中使用
ref
关键字,在每种情况下何时复制对象以及何时引用对象(即,当传递给函数时,当设置为其他时)对象(如上面的前两个示例),当复制成员变量(如第三个示例等)时?
如果不花费大量时间仔细挑选措辞,就很难准确回答此类问题。
我在几篇文章中这样做了,您可能会觉得有用:
当然,这并不是说这些文章是完美的 - 远非如此 - 但我已尽力表达清楚。
我认为一件重要的事情是在你的头脑中区分两个概念(参数传递和引用与值类型)。
看你的具体例子:
SomeForm myForm = new SomeForm();
SomeObject myObject = new SomeObject();
myForm.formObject = myObject;
这意味着
myForm.formObject
和 myObject
指的是 SomeObject
的同一个实例 - 就像两个人拥有不同的纸,每个人都写有相同的地址。如果你去一张纸上的地址,把房子涂成红色,然后去第二张纸上的地址,你会看到一栋红色的房子。
不清楚“然后修改表单中的对象”是什么意思,因为您提供的类型是不可变的。没有办法修改对象本身。您可以更改
myForm.formObject
以引用 SomeObject
的不同实例,但这就像在一张纸上潦草地写下地址,然后在上面写一个不同的地址。这不会改变另一张纸上写的内容。
如果您可以提供一个简短但完整的程序,其行为您不理解(最好是控制台应用程序,只是为了让事情变得更短更简单),那么具体地讨论事情会更容易。
嗨迈克 所有派生自 ValueType 的对象(例如结构体或其他基本类型)都是值类型。这意味着每当您将它们分配给变量或将它们作为方法参数传递时,它们都会被复制。其他类型是引用类型,这意味着,当您将引用类型分配给变量时,分配给该变量的不是它的值,而是它在内存空间中的地址。 您还应该注意,您可以使用 ref 关键字将值类型作为引用传递。这是语法
public void MyMethod(ref int a) { a = 25 }
int i = 20;
MyMethod(ref i); //Now i get's updated to 25.
希望有帮助:)
关于克隆对象,如果从一个对象复制到另一个对象的值是引用类型,那么对原始对象中这些值的任何修改都会影响复制对象中的值(因为它们只是对同一对象的引用)
如果您需要克隆一个具有引用类型属性的对象,您需要使这些类型可克隆,或者通过根据需要实例化新实例来手动复制它们。
考虑使用 IClonable 界面,但恕我直言,它不是最好的解决方案。