何时复制 C# 值/对象以及何时复制其引用?

发布于 2024-10-06 02:00:57 字数 1256 浏览 9 评论 0原文

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

例如,如果我将对象发送到另一个表单,即:

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等系统对象似乎总是被复制,除了上面的clone方法。

我的问题是,不考虑在函数中使用 ref 关键字,在每种情况下(即传递给函数时,何时复制对象以及何时引用对象)当设置为其他对象时(如上面的前两个示例),当复制成员变量时如第三个示例等)?

I keep getting the same issue over and over again where an object I want to reference is copied or where an object I want to copy is referenced. This happens when I use the = operator.

For example, if I am sending the object to another form, ie:

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

...and then modify the object in the form, the original object does not get modified. It is as if the object was copied and not referenced. Yet, when I do this:

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

...and then modify anotherObject, myObject gets modified as well.

The most aggravating case is when I try to Clone one of my defined objects:

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;
    }
}

when I do this...

SomeObject obj1 = new SomeObject(1, 2);
SomeObject obj2 = new SomeObject();
obj2.Clone(obj1);

...obj1 is referenced and any modifications to obj2 changes obj1.

System objects such as int, double, string, etc seem to always be copied, except for in the case of the clone method above.

My question is, not taking into account the use of the ref keyword in functions, when does an object get copied and when does an object get referenced in every case of the matter (i.e. when passing to functions, when setting as other objects (like the first two above examples), when copying member variables like the third example, etc.)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

庆幸我还是我 2024-10-13 02:00:57

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

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

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

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

看一下您的具体示例:

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

这意味着 myForm.formObjectmyObject 引用 SomeObject 的同一个实例 - 就像两个人拥有不同的部分一张纸,每张纸上都写着相同的地址。如果你去一张纸上的地址,把房子涂成红色,然后去第二张纸上的地址,你会看到一座红色的房子。

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

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

It's hard to answer this sort of question precisely without spending an awful lot of time picking your words carefully.

I've done so in a couple of articles which you may find useful:

That's not to say that the articles are perfect, of course - far from it - but I've tried to be as clear as I can.

I think one important thing is to separate the two concepts (parameter passing and reference vs value types) out in your head.

To look at your specific examples:

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

This means that myForm.formObject and myObject refer to the same instance of SomeObject - like two people having separate pieces of paper, with each one having the same address written on them. If you go to the address on one piece of paper and paint the house red, then go to the address on the second piece of paper, you'll see a red house.

It's not clear what you mean by "and then modify the object in the form" because the type you have provided is immutable. There's no way of modifying the object itself. You can change myForm.formObject to refer to a different instance of SomeObject, but that's like scribbling out the address on one piece of paper and writing a different address on it instead. That won't change what's written on the other piece of paper.

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.

终遇你 2024-10-13 02:00:57

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

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

希望有帮助:)

Hi Mike
All objects, which derives from ValueType, such as struct or other primitive types are value types. That means that they are copied whenever you assign them to a variable or pass them as a method parameter. Other types are reference types, that means that, when you assign a reference type to a variable, not it's value, but it's address in memory space is assigned to the variable.
Also you should note that you can pass a value type as a reference using ref keyword. Here's the syntax

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

Hope it helps :)

猥琐帝 2024-10-13 02:00:57

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

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

考虑使用 IClonable 界面,尽管它不是最好的解决方案恕我直言。

With regards to cloning your objects if the values you are copying from one object to another are reference types then any modification to those values in the original object will affect the values in the copied object (since they are just references to the same object)

If you need to clone an object which has properties which are reference types you need to either make those types clonable or do a manual copy of them by instantiating new instances as required.

Conside using the IClonable interface though it isn't the best of solutions imho.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文