3

I feel pretty ignorant asking this, but would someone be able to explain to me why this is happening?

class MyClass{ public int i {get; set; } }
class Program
{
    static void Main(string[] args)
    {
        MyClass a = new MyClass();
        MyClass b = new MyClass();

                b.i = 2;
        a = b;
        a.i = 1;

        Console.Write(b.i + "\n"); //Outputs 1
    }
}

This makes sense to me were I using pointers and all that great stuff, but I was under the impression that with C# that "b" would remain independent from "a."

Am I just using some terribly bad practice? Maybe someone could point me towards something that explains why this is so in C#?

Thanks.

4

6 回答 6

10

It's this line that has you confused:

a = b;

You expected b to be copied to a by value, but in fact all that happens is you've assigned the reference from b to a.

.Net divides the world into two categories: reference types and value types (there's also delegate types and a couple others, but that's another story). Any class you define is a reference type, and there are a few important things to remember about reference types:

  • There's no built-in way to do a deep copy
  • Be careful checking equality. == is intended for reference equality (do the variables refer to the same object) while .Equals() is intended for value equality, and you may need to override .Equals() (and GetHashCode()) for your type to get that right.
  • assignment just copies the reference (this is the part that bit you)
于 2010-01-21T23:02:38.223 回答
4

You are using pointers after a fashion. Object are referred to by reference, unless they descend from ValueType.

So

a = b;

Sets the reference a equal to the reference to b.

于 2010-01-21T23:02:20.007 回答
2

关于这个场景,您需要了解的是实际上有 4 个感兴趣的实体。

  1. MyClass 的实例 #1
  2. MyClass 的实例 #2
  3. MyClass 参考
  4. MyClass 参考 b

最初引用 a 指的是实例 #1,引用 b 指的是实例 #2。直到您执行该行a=b;。在此行之后,引用 a 和引用 b 都指向实例 #1。因此,当您打电话时,b.i您实际上是在询问实例 #1 if 的值i是什么。不是实例#2。

于 2010-01-21T23:03:50.507 回答
1

没有指针与没有对象引用不同。在您的情况下,“a”是对 MyClass 类型的特定对象以及“b”的引用。当你做'a = b'时,你复制的是引用,而不是对象,所以'a'指向与'b'相同的对象。

于 2010-01-21T23:03:45.357 回答
0

a 和 b 是引用,因此在 line 之后, a 与 b 引用a = b相同的对象(并且 a 最初指向的对象不再可达)。因此,当您设置时,a.i您也在更新 b 引用的对象,因此发生了更改。

于 2010-01-21T23:04:56.927 回答
0

.NET 中的每个类都是引用类型。这意味着当你创建一个新实例时,它指向内存中的一个引用,而不是保存它的值。

在您的情况下,当您使用= operator(assignment) 时,您只需将 object 的指针也关联到 objecta的指针b。在这个操作之后,对象上的每一次交互都会被反射到另一个对象上,因为它们只是指向同一个东西。

如果需要复制对象,则必须自己编写代码。但这是另一个故事。

于 2017-09-21T09:20:05.660 回答