74

在复制要引用的对象或引用要复制的对象的位置时,我一遍又一遍地遇到相同的问题。当我使用 = 运算符时会发生这种情况。

例如,如果我将对象发送到另一种形式,即:

SomeForm myForm = new SomeForm();
SomeObject myObject = new SomeObject();
myForm.formObject = myObject;

...然后修改表单中的对象,原始对象不会被修改。就好像对象被复制而不被引用一样。然而,当我这样做时:

SomeObject myObject = new SomeObject();
SomeObject anotherObject = new SomeObject();
anotherObject = myObject;

...然后修改anotherObjectmyObject也被修改。

最严重的情况是当我尝试克隆我定义的对象之一时:

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函数中关键字的使用,何时复制对象以及何时在每种情况下引用对象(即传递给函数时,设置为其他对象时(如上面的前两个示例),当复制第三个示例等成员变量时)?

4

3 回答 3

56

如果不花大量时间仔细挑选你的话,很难准确地回答这类问题。

我在几篇您可能会觉得有用的文章中这样做了:

当然,这并不是说这些文章是完美的——远非如此——但我已经尽可能地清楚了。

我认为一件重要的事情是在你的脑海中将这两个概念(参数传递和引用与值类型)分开。

查看您的具体示例:

SomeForm myForm = new SomeForm();
SomeObject myObject = new SomeObject();
myForm.formObject = myObject;

这意味着myForm.formObjectmyObject指的是同一个例子SomeObject——就像两个人有不同的纸片,每个人的地址都写在上面。如果你去一张纸上的地址,把房子涂成红色,然后去第二张纸上的地址,你会看到一座红色的房子。

不清楚您所说的“然后修改表单中的对象”是什么意思,因为您提供的类型是不可变的。无法修改对象本身。您可以更改myForm.formObject以引用 的不同实例SomeObject,但这就像在一张纸上潦草地写下地址并在上面写下不同的地址。这不会改变另一张纸上写的内容。

If you could provide a short but complete program whose behaviour you don't understand (ideally a console application, just to keep things shorter and simpler) it would be easier to talk about things in concrete terms.

于 2010-12-03T17:16:45.810 回答
9

嗨,迈克,从 ValueType 派生的所有对象,例如结构或其他原始类型都是值类型。这意味着只要将它们分配给变量或将它们作为方法参数传递,它们就会被复制。其他类型是引用类型,这意味着,当您将引用类型分配给变量时,不是它的值,而是它在内存空间中的地址分配给变量。您还应该注意,您可以使用 ref 关键字将值类型作为引用传递。这是语法

public void MyMethod(ref int a) { a = 25 }
int i = 20;
MyMethod(ref i); //Now i get's updated to 25.

希望能帮助到你 :)

于 2010-12-03T17:03:44.757 回答
1

关于克隆对象,如果您从一个对象复制到另一个对象的值是引用类型,那么对原始对象中这些值的任何修改都会影响复制对象中的值(因为它们只是对同一对象的引用)

如果您需要克隆具有引用类型属性的对象,则需要使这些类型可克隆或通过根据需要实例化新实例来手动复制它们。

考虑使用IClonable接口虽然它不是最好的解决方案恕我直言。

于 2010-12-03T17:04:38.797 回答