一尘不染

什么时候复制C#值/对象,什么时候复制其引用?

c#

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

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

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


阅读 341

收藏
2020-05-19

共1个答案

一尘不染

如果不花大量时间仔细挑选您的单词,就很难准确地回答此类问题。

我已经在几篇文章中这样做了,您可能会发现它们很有用:

当然,这并不是说这些文章是完美的-远非如此-但我已尽我所能地做到了清晰。

我认为重要的是要把两个概念(参数传递和引用与值类型)分开。

要查看您的特定示例:

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

这意味着myForm.formObjectmyObject指的是相同的实例SomeObject-就像两个人有分开的纸,每个人都写有相同的地址。如果转到一张纸上的地址并将房子漆成红色,然后转到第二张纸上的地址,则会看到一个红色的房子。

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

如果您可以提供一个简短但 完整的 程序,但您不了解其行为(最好是控制台应用程序,只是为了使事情更简短,更简单),那么用具体的术语来谈论事情会更容易。

2020-05-19