views:

106

answers:

5

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  A: 

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.

Kevin Montrose
+8  A: 

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)
Joel Coehoorn
Thanks, I feel pretty foolish, but the explanation is appreciated.
Jesse
+1  A: 

Not having pointers is not the same as not having references to objects. In your case 'a' is a reference to a particular object of type MyClass, as well as 'b'. When you do 'a = b', you are copying the reference, not the object, so 'a' points to the same object as 'b'.

Santiago Palladino
+2  A: 

What you need to understand about this scenario is that there are actually 4 entities of interest.

  1. Instance #1 of MyClass
  2. Instance #2 of MyClass
  3. MyClass Reference a
  4. MyClass Reference b

Initially Reference a refers to instance #1 and reference b refers to instance #2. That is until you execute the line a=b;. After this line both reference a and reference b point to instance #1. So when you call b.i you are actually asking instance #1 what the value if i is. Not instance #2.

JaredPar
A: 

a and b are references, so after the line a = b, a refers to the same object as b (and the object originally pointed to by a is no longer reachable). Therefore, when you set a.i you are also updating the object referred to by b, hence the change.

Lee