tags:

views:

83

answers:

3
+4  A: 

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.

Mark Byers
@Timwi: Updated. Is it better now?
Mark Byers
@Mark: If I set the value of i after testClass = new TestClass(); testClass.i = 600 in Another() method, what should be the out put in this case?
Vijjendra
@Vijjendra: Which `i`? The local variable or the member of testClass? (PS: it would be useful for explanation purposes to call the different variables different names. You have three different things that are all called `i`.)
Mark Byers
A: 

Basically,

    testClass.i = 500;

changes the value inside the object. You are passing this object around, so this change will be seen by everything that has a reference to the object. But

    i = 400;
    testClass = new TestClass();

these assignments only change the value of a local parameter. This change is not seen by any code outside the same method.

Timwi
+3  A: 

In C# anything that is a struct is a value type, anything that is a class is a reference type. When you pass a value type as a parameter to another method there is no way for the method to alter the original value (unless the value type is passed using the ref keyword). When you pass a reference type as a parameter to another method method any changes the method makes to the object will be reflected in the object upon return from the method. The output would be:

Another 1:100

Another 2:400

Method 1:500

Method 2:200

The i variable in the Another method cannot change the value of the variable i in the Method method, because i is a value type; therefore the value of i in Method (200) is unchanged by your call to Another. TestClass however is a reference type, so Another can alter the field within it, hence in the line:

testClass.i = 500;

changes the value as seen by Method, hence the output of Method 1:500. When you allocate a new instance of TestClass in the line:

testClass = new TestClass();

you have changed what the reference is within Another, but the original instance from Method is no longer available to the method Another, hence anything that another does to its testClass variable will have no impact on the instance the Method is referring to

Steve Ellinger