7

According to MSDN, if all arrays are reference type, then why in the given sample code, the new value of t2 doesn't reflect the change in t1?

string[] data = new[] { "One", "Two" };

var t1 = data[0];

Console.WriteLine(t1);

var t2 = t1;
t2 = "Three"; //assigning the new value, and this should reflect in t1

Console.WriteLine(t2);
Console.WriteLine(t1); // this should print 'Three', but it prints 'One'

Console.Read();

enter image description here

http://msdn.microsoft.com/en-us/magazine/cc301755.aspx

Arrays are mechanisms that allow you to treat several items as a single collection. The Microsoft® .NET Common Language Runtime (CLR) supports single-dimensional arrays, multidimensional arrays, and jagged arrays (arrays of arrays). All array types are implicitly derived from System.Array, which itself is derived from System.Object. This means that all arrays are always reference types which are allocated on the managed heap, and your app's variable contains a reference to the array and not the array itself.

nunu
  • 3,184
  • 10
  • 43
  • 58

6 Answers6

21

One picture is worth a thousand words, so here is what's going on:

Before and After

The effect of the assignment of "Three" to t2 is that before the assignment t1 and t2 referenced the same object, but after the assignment they reference different objects. Nothing else is going on here.

The situation would have been different if you had an array of mutable objects, and manipulated their value instead of setting their references. For example, imagine replacing the array of strings with an array of StringBuilder objects, and calling t2.Replace("Two", "Three") instead of the assignment. Now the effect would be different, because t1, t2, and data[0] would be pointing to the same object.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 2
    There's no need for 1000 words, just these: The only array in the OP's code is `data`, which is never used, other than to pull out its 0th element. – Jim Balter Dec 17 '16 at 05:53
8

Your question has nothing to do with arrays. Since your data[0] is string -and it is a reference type- it's value is One, you never change it's value. You just created an another string reference called t2 and set point to same object with t1 reference. After you changed this reference object to "Three", but this won't effect to what t1 refers.

Let's look at line by line your code;

var t1 = data[0];

With this line you created a string reference as t1 and this points to "One" object.

var t2 = t1;

With this line, you create a new string reference as t2 and this points to same object with t1 which is "One"

t2 = "Three";

With this line, you create a string object called "Three" and your t2 is reference this object. It doesn't point to "One" object anymore. But this doesn't effect to t1 reference. It still points to "One" object.

That's why

Console.WriteLine(t2);
Console.WriteLine(t1);

prints

Three
One
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
7

Strings are also reference types. So if you write:

var t1 = data[0];

You have declared a new variable t1 that references to the same string as data[0]. After this you write:

var t2 = t1;

Now you have a new variable t2 that references to the same string as t1. You now have one String object on the heap, and three references to this object: data[0], t1 and t2.

Then you write:

t2 = "Three";

After this statement, t2 points to antoher string in the heap with the value "Three". However, data[0] and t1 still point to the same original string.

Elian Ebbing
  • 18,779
  • 5
  • 48
  • 56
0

Writing t2 = "Three" won't alter the value of t1 because the types are reference type, so they "point" to their data. By assigning to t2 you're telling it to reference something else.

Liukewise, when you wrote t2 = t1 you're just telling t2 to reference the same thing as t1. Future assignments to t2 will just make it reference something else.

Some languages, like C++, do have the ability for you to store a reference to another variables, so that when you change the reference you actually change what the other variable is.

Sean
  • 60,939
  • 11
  • 97
  • 136
0

this program exactly behaving as you expecting.

void Main()
{
    abc[] data = new[] { new abc(){i=1}, new abc(){i=2} };

var t1 = data[0];
var t2 = t1;
// here is the difference 
// t2 is still pointing to its old location
// but i will point a new position.
t2.i  = 5 ; //assigning the new value to i
// but t2 still pointing to t1
//all will be identical now.
Console.WriteLine(t2);
Console.WriteLine(t1); 
Console.WriteLine(data[0]);


  // repeating like you.
  t2 = new abc() {i=444};
 //now you will see t2 is different form t1. because
 // now t2 pointing to a new object instead of t1.
 Console.WriteLine(t2);
Console.WriteLine(t1);


}

public class abc{
    public int i ;
}
sm.abdullah
  • 1,777
  • 1
  • 17
  • 34
-1

when you assign one array reference variable to another, you are simply making both variables refer to the same array. You are neither causing a copy of the array to be created, nor are you causing the contents of one array to be copied to the other.

// Assigning array reference variables.

        using System; class AssignARef {
     static void Main()
     {
 int i; 
    int[] nums1 = new int[10];
     int[] nums2 = new int[10]; 
    for(i=0; i < 10; i++)
     nums1[i] = i;
     for(i=0; i < 10; i++)
     nums2[i] = -i;
     Console.Write("Here is nums1: "); 
    for(i=0; i < 10; i++)
     Console.Write(nums1[i] + " ");
     Console.WriteLine();
     Console.Write("Here is nums2: ");
     for(i=0; i < 10; i++)
     Console.Write(nums2[i] + " "); 
    Console.WriteLine(); nums2 = nums1; // now nums2 refers to nums1 
    Console.Write("Here is nums2 after assignment: "); 
    for(i=0; i < 10; i++)
     Console.Write(nums2[i] + " "); 
    Console.WriteLine(); // Next, operate on nums1 array through nums2. 
    nums2[3] = 99; 
    Console.Write("Here is nums1 after change through nums2: ");
     for(i=0; i < 10; i++) 
    Console.Write(nums1[i] + " ");
     Console.WriteLine(); 

}
 }

o/p

Here is nums1: 0 1 2 3 4 5 6 7 8 9
Here is nums2: 0 -1 -2 -3 -4 -5 -6 -7 -8 -9
Here is nums2 after assignment: 0 1 2 3 4 5 6 7 8 9
Here is nums1 after change through nums2: 0 1 2 99 4 5 6 7 8 9