KarlHungus
KarlHungus

Reputation: 237

Object equality in .NET

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.

Upvotes: 3

Views: 322

Answers (6)

Angelo Badellino
Angelo Badellino

Reputation: 2191

Every class in .NET is a reference type. This mean that when you create a new instance, it point to a reference in memory and not hold its value.

In your case, whene you use the = operator (assignment) you are just just associate the pointer of object a alsto to the pointer of object b. After this operation, every interaction on on object will be reflected to the orther bacause they just point to the same thing.

If you need to duplicate an object, you have to write the code on your own. But this is another story.

Upvotes: 0

Joel Coehoorn
Joel Coehoorn

Reputation: 415600

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)

Upvotes: 10

Lee
Lee

Reputation: 144126

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.

Upvotes: 0

JaredPar
JaredPar

Reputation: 754545

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.

Upvotes: 2

Santiago Palladino
Santiago Palladino

Reputation: 3542

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'.

Upvotes: 1

Kevin Montrose
Kevin Montrose

Reputation: 22571

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.

Upvotes: 4

Related Questions