The output should be:
Another 1:100 Another 2:400 Method 1:500 Method 2:200
C# passes by value unless the ref
keyword is used. For value types the value is copied. For reference types the value of the reference is copied.
The variable i
is completely unrelated to testClass.i
. I'll look at the simple case first, i
is an int - a value type. When you call the method Another
with i
as an argument it is passed by value so modifying the value of i
inside the method Another
it does not change the value of the variable i
in Method
- it is equal to 200 all the time.
The value of variable testClass
is also passed by value, but in this case because it is a reference type the value of the reference is passed and so the variable testClass
in Another
initially refers to the same object as the variable in Method
. When you modify the value of testClass.i
in Another
it changes the object you created in Method
so that it's member is set to 300.
Then this line creates a new and unrelated object:
testClass = new TestClass();
Sometimes it is easier to see what happens in a diagram, where the top row shows variables and the bottom row shows the objects they refer to:
Before assignment: After assignment: +-------------+ +-------------+ +-------------+ +-------------+ | Method | | Another | | Method | | Another | | testClass | | testClass | | testClass | | testClass | +-------------+ +-------------+ +-------------+ +-------------+ | | | | | | | | v | v v +-----------+ | +-----------+ +-----------+ | TestClass |<-----------+ | TestClass | | TestClass | | i = 300 | | i = 300 | | i = 100 | +-----------+ +-----------+ +-----------+
So the value of testClass.i
when printed in Another
is the default that is set in the constructor, i.e. 100. The assignment does not modify the original object. You are only reassigning the variable to point to something else.