2

Here is my c# code. Why a reference type doesn't update in C#, below is the code

 class Program
    {
        public static void Main(string[] args)
        {
            var a = A.field;
            A.field = "2";

            Console.WriteLine(a);
            Console.Read();
        }
    }
    public static class A
    {
        public static string field = "1";
    }

The result is 1, why??

Habib
  • 219,104
  • 29
  • 407
  • 436

7 Answers7

10
public static void Main(string[] args)
{
    var a = A.field; // `a` is now a reference to the string "1"
    A.field = "2"; // `A.field` is now a reference to the string "2"

    Console.WriteLine(a); // nothing else has changed, so `a` is still a reference to the string "1"
    Console.Read();
}

So the answer to your question is basically: the reference doesn't update, because you're not changing the reference you're writing to the Console (a), but another reference (A.field).

Rik
  • 28,507
  • 14
  • 48
  • 67
  • sorry, but this answer doesn't seem focused on the OP question.. so I think that it is not a good practice to upvote it.. – Ciro Corvino Aug 16 '16 at 15:38
  • 1
    Why not? It explains exactly what's happening in OP's code, and consequently why the resulting output is what it is. – Rik Aug 16 '16 at 15:40
  • the OP asked why a reference assigned via another reference it is not affected when the original reference it is assigned with another value.. your answer shows a workaround to avoid a particular situation but it is not that it was asked – Ciro Corvino Aug 16 '16 at 15:43
  • 1
    The code in my answer is an exact copy of Op's code. I only added the comments to explain what's going on. – Rik Aug 16 '16 at 15:48
  • the OP is asking why... (as already said). Your code is focused on a workaround to avoid the particular situation that it is occurred in the OP example, but the OP is asking "why this situation is occurring?", not how to avoid this situation.. your answer doesn't explain that – Ciro Corvino Aug 16 '16 at 15:51
  • 2
    I'm sorry, I don't get what you're saying. I'm in no way suggesting any workaround, as my code is exactly that of the OP. If your issue is that my answer is specific to OP's code, instead of supplying a more general explanation of what a reference is, you are right, but that is what OP was asking about. – Rik Aug 17 '16 at 10:06
  • Sorry Rik you are right! about workaround, I was confunding your answer with the answer of Qadeer Mangrio. It was a misunderstanding, I beg your pardon.. your answer with notes at margin it is correct I also upvoted – Ciro Corvino Aug 17 '16 at 11:19
4

The behaviour you're witnessing is not limited to reference types. The same thing will happen with value types:

int x = 1;
int y = x;
x = 2; // y is still 1 at this point

This happens because the y variable stores the value 1, and changing value of x does not automatically change the value of y. x doesn't "know" about y.

It is the same with reference types - in your example a points to the same location in memory as A.field after the assignment, but it doesn't "know" where A.field points to. Therefore changing the reference of A.field doesn't influence a.

An analogy:

You give Joe a card with Cat written on it. Let Ann = Joe mean that Ann will receive a card from you with the same thing written on it as on Joe's card. So now they both have Cat written on their cards. Now if you give another card to Joe, with Dog written on it, Ann still has Cat on her card. This analogy applies to value types, for reference types you'd have a location written on the card, pointing to the place where they can find the word. The same principle still applies, though.

Kapol
  • 6,383
  • 3
  • 21
  • 46
3

This is the same as following:

String a = "1";
String b = a;
b = "2";
Console.Write($"a:{a} b:{b}");

Originally you have a variable a that references the object with the content 1, and a variable b that references the same object. Then you modify the variable b to reference a new object, one with content 2. You do not modify the object referenced by a nor b, you make the variable reference a different object. You would have to modify the object referenced by b so that the a variable 'sees' the change. Alas as String is immutable there is simply no method to actually modify it. Any API at your disposal would result in a new string that b would reference, and a would look the same as before. With a mutable type you would see the difference, as long as you modify the object, not simply assign a new object to the variable:

var a = new Widget {x = 1};
var b = a;
b.x = 2;
Console.Write($"a.x: {a.x} b.x: {b.x}");
Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
3

You are assigning reference and not modifying the original reference.

When you assign A.field to a you assign reference of string "1" to a. Later you assign a new string to A.field and there was no change in the original value of a. It still holds the old reference to string "1".

If somehow, you could modify the original reference then you should be able to see the change. Since your type is string, you can't really modify it because it is immutable, but consider an example with StringBuilder.

public static class A
{
    public static StringBuilder field { get; set; } = new StringBuilder("1");
}

And later.

static void Main(string[] args)
{
    var a = A.field;
    A.field.Insert(0, "2");

    Console.WriteLine(a);
    Console.Read();
}

Now you will get modified value "21" in variable a as well.

Notice that the code above is modifying the field with A.field.Insert(0, "2"); and since variable a holds the reference to A.field, you see the change on the next line.

But if you try to assign a new reference to A.field with statement like:

A.field = new StringBuilder("2");

Then A.field will have a new object to reference, and the previous variable a will still keep the old reference.

Habib
  • 219,104
  • 29
  • 407
  • 436
1

You may think at a "reference" type variable as a box, where it is into an address to some resource.

Let's consider a string value.. when we assign some literal value string to a "reference", we do nothing that:

  1. to allocate a memory area (static or heap) setted with the specified value;
  2. to allocate another memory area (static or heap) initialized with the memory address (reference) of the string value;

When we assign a string "reference" type var to another "reference", we do nothing that to assign the memory address of the referenced string value to the new "reference".

So, if we change the first "reference" with a new assignment statement, the second will not be affected and it continues to reference the original value.

Finally, it is not possible (for now at least) have "references to references" in C#, you can have it in C++ (where pointers and references are a bit different things..). See also this Eric Lippert answer to an analougous question: https://stackoverflow.com/a/15328414/3762855

Community
  • 1
  • 1
Ciro Corvino
  • 2,038
  • 5
  • 20
  • 33
0

The variable a gets a copy of value of the static property A.field.

So when you modify A.field, the copy does not change.

fafl
  • 7,222
  • 3
  • 27
  • 50
0

try this

 class Program
    {
        static void Main(string[] args)
        {
            A.field = "2";
            var a = A.field;


            Console.WriteLine(a);
            Console.Read();
        }
    }

    public static class A
    {
        public static  string field = "1";
    }
Mangrio
  • 1,000
  • 19
  • 41