【问题标题】:Object Reference Handling in C# [duplicate]C# 中的对象引用处理 [重复]
【发布时间】:2014-04-25 01:09:18
【问题描述】:

我今天正在编写一个 c# 程序,结果不得不追一个 bug 很长一段时间。

我试图让一个对象的副本更改几个字段并将其与原始对象一样发送

例如

Function(Object A)
{
    Object B = new Object();
    Object B = A;

    B.foo = "bar";

    Send(A);

    Send(B);
}

我的程序开始将 A 和 B 视为同一个对象,这意味着对 A 的任何更改也会更改 B,反之亦然。

我知道对象 A 和 B 都在引用相同的内存。

是否有一种简便的方法来确保Object B = A 行引用新内存从而创建不同的对象。或者是在我的 Object 中创建复制构造函数并使用 Object B = new Object(A) 创建 B 的唯一方法

例如:

Object(Object a){
   foo = a.foo;
   ...
}

基本上,我只是想了解更多关于 C# 如何处理对象引用和内存分配的信息。我知道的大主题。

【问题讨论】:

  • msdn.microsoft.com/en-us/library/t63sy5hs.aspx。如果您想要一份(浅)作业副本,您可能想要使用struct
  • 仅供参考,Object B = new Object(); 对您没有任何作用,因为下一行,您将 B 设置为其他值。
  • ... 因为从表面上看,“对象 B”不会创建对象、对象或“对象”。它甚至没有声明一个持有变量的变量。

标签: c#


【解决方案1】:

您的代码中有 2 个对象。有一个通过参数A 传入,一个在第3 行实例化。第二个在分配给B 时立即丢弃。 B 现在持有对变量 A 引用的同一对象的引用。当您通过B 引用更新其foo 属性时,当您通过A 引用访问它时,此更改可见。

如果您希望 B 引用 A 中的内容的副本,您可以定义并使用复制构造函数 (B = new SomeClass(A)) 或定义并使用克隆函数 (B = A.Clone())。在这些操作之后,AB 将引用不同的对象实例。还有一些涉及结构(“值类型”)的解决方案,但这通常不是初学者想要做的。除此之外,请记住 B = A 不会创建新对象。

【讨论】:

    【解决方案2】:

    您可以调用受保护的MemberwiseClone 方法,该方法将对所有对象进行浅拷贝。如果您可以修改对象的类,您甚至可以创建一个委托给它的公共Clone 方法。如果你愿意使用结构而不是类,任何赋值都会创建一个副本。这是因为结构是值类型,将一个值类型变量分配给另一个值类型变量会创建一个副本。

    关于MemberwiseClone,请注意我所说的“浅薄”部分。值类型字段将被复制,但引用类型字段仍将引用相同的底层对象。

    【讨论】:

    • 你可能想说为什么结构赋值会创建一个副本。
    • 您选择结构是值类型的原因是什么,并且所有值类型在分配时都会被复制,还是其他原因?
    • 还有别的吗?我的意思是值类型。
    • 只是不确定你在想什么,我会编辑我的答案。
    【解决方案3】:

    另一种方式是序列化。您序列化原始对象并在另一个对象中反序列化。 C# 广泛支持该方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-20
      • 2014-07-14
      • 2021-10-21
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      • 2011-04-26
      相关资源
      最近更新 更多