为什么我的对象是指针?

时间:2013-03-05 22:49:58

标签: c# oop

我的问题涉及在C#中使用对象。我想我明白发生了什么,但我想明白为什么。由于我不打算进入的原因,我想创建一个具有当前数据(当前状态)的对象的临时副本。所以我想我可以创建一个新对象,为它分配原始对象,然后更改原始对象。那时我会有两个处于不同状态的物体。但是,所复制的对象最终看起来与第一个完全相同。以下是一些代码来说明:

Order o1 = new Order();
o1.property1 = "test 1";

Order o2 = new Order();
o2 = o1;

o1.property1 = "test 2";

但是在这段代码的末尾,o1和o2都将property1设置为“test 2”。我想我已经意识到所有对象都只是指针,所以如果你改变了一个就会改变另一个,但是我无法理解为什么会这样,或者为什么它有用。我在这里缺少一些基本的东西吗?另外,完成我想要做的最好的方法是什么?其中:存储对象的状态,进行更改,然后在必要时还原。希望这是有道理的。

7 个答案:

答案 0 :(得分:7)

C#中的对象变量是指向内存中特定对象的引用(不是指针)。当你宣布

Order o2 = new Order();

您正在堆中创建一个新的Order对象,并将该对象的引用分配给您的o2变量。当你说出

o2 = o1;

你告诉编译器让o2引用o1。此时,对原始o2对象的引用将丢失,并且在下一次垃圾回收扫描期间将删除该对象的内存。

此后,o1和o2都在内存中引用相同的对象。要将信息从一个对象复制到另一个对象,您需要实现一个过程来实例化一个新的目标对象,并将所有数据从一个对象复制到另一个对象。有关详细信息,请参阅ICloneable上的MSDN文档。

答案 1 :(得分:4)

您所指的是值类型和引用类型之间的区别。显然你的Order对象是一个引用类型,我认为它是一个类。

类是引用类型,意味着它们是“指针”。其中一个原因是性能,因为每次分配变量时都不想复制大量数据。

结构是值类型,在分配时会复制到内存中。

你有2个解决方案:

  • 使用结构而不是类
  • 使用MemberwiseClone克隆对象(如果它非常简单),或者如果需要执行深度克隆,请使用自己的方法。

答案 2 :(得分:2)

这是设计。如果您想克隆并保持克隆独立,我建议您在类型上实现“克隆”机制。这可以是ICloneable,甚至只是一个构造函数,它接受一个实例并从中复制值。

答案 3 :(得分:2)

关于你的问题

  

完成我想要做的最好的方法是什么?这是:   存储对象的状态,进行更改,然后在必要时还原

一种简单的方法是简单地序列化对象,例如使用XMLSerializer。然后,如果要丢弃更改,只需反序列化原始对象并将修改后的对象替换为原始版本。

答案 4 :(得分:2)

使用Structures完成任务,类是引用类型,Structs是Value类型。 类存储在内存堆上 结构存储在堆栈中。 了解更多信息搜索Structs vs Classes并学习差异

答案 5 :(得分:1)

根据定义,对象是“指针”;他们为您的数据保留引用,而不是实际的数据本身。您可以为其指定一个值类型,它将显示保存数据的外观。

如上所述,理解Value types vs. Reference types是关键。

答案 6 :(得分:1)

除了对象引用之外,Java没有任何非原始数据类型的概念;因为几乎任何人都能用对象引用做什么就涉及对Java所引用的.运算符进行操作。尽管.net确实具有非原始值类型,但大多数.net语言都保持约定(不同于C和C ++,它使用->来访问指向对象的成员,并使用.来访问结构的一个成员)同一个.运算符用于“取消引用和访问成员”和“访问值类型成员”。

就个人而言,我不喜欢Java的“一切都是对象引用”设计,而.net决定让值类型和引用类型使用相同的.运算符来表示非常不同的东西没有帮助,但它是它是什么。