I’ve come across this tricky issue. See the following code:
public class Foo
public int A { get; set; }
}
static void Main(string[] args)
{
Foo foo1 = new Foo();
Foo foo2 = new Foo();
ChangeObject1(foo1);
ChangeObject2(ref foo2);
Console.WriteLine("Foo1 = " + foo1.A);
Console.WriteLine("Foo2 = " + foo2.A);
Console.ReadKey();
}
static void ChangeObject1(Foo foo)
{
foo.A += 1;
foo = new Foo();
}
static void ChangeObject2(ref Foo foo)
{
foo.A += 1;
foo = new Foo();
}
After some testing, foo1.A is equal to 1, and foo2.A is still equal to 0. To my understanding, this is because the second method has the instance passed in by reference rather than value. This changes the content of the instance, so when a new object is created and assigned in the method, the value is no longer defined.
But thinking about it confuses me as I feel that there should be similar effects in the first method, even if it’s passed by value because the content of the instance is still changed outside of the method.
Anyone know whats actually going on? Thanks!
I presume that you’re using c# or java. either way, the concept remains the same
when you declare your foo variables
you’re declaring what is called a reference type. (all objects that represent classes are reference types)
so, the value stored in
foo1isn’t really aFoo, but it’s a value that holds the memory address of thatFoo.when you call
you’re passing a copy of that reference. Therefore, when you do
foo.A += 1, you’re changing the member value of the object that you’ve just passed in.when you do
foo = new Foo();you’re only changing the copy of the reference, but not the original object reference itself.now, when you call
you’re not passing a copy of the address of your
Foobut you’re passing the address of the address of yourFoo.you can think of it as though you’re passing the original
Fooaddress itself.So when you call
foo = new Foo(), it doesn’t matter what you did to foo before that. You’ve just over-written your address with the address of a brand newFooobject.if you change your method to look like the following
then you should notice the change
Here’s a page that explains reference types It’s in java, but the same principles apply to c# too