-1

It might be because it's immutable.

    class A
    {
        public string a;
    }

    static void Main(string[] args)
    {
        A a1 = new A();
        A b1 = new A();
        string a = "abc";
        a1.a = "abc";
        string b = "ca";
        b1.a = "ca";
        a = b;
        a1 = b1;
        b = "cab";
        b1.a = "cab";
        Console.WriteLine(a);
        Console.WriteLine(a1.a);
        Console.ReadLine();
    }

The answer is "ca" for a and "cab" for a1.a, and that's what I answered in an interview question and I explained the reason as "immutability" of string.

But the interviewer didn't look convinced. Could someone provide a convincing explanation of the above code?

Deepak Mishra
  • 2,984
  • 1
  • 26
  • 32
  • Internally string is a char array. Arrays are reference types. – opewix Dec 24 '14 at 08:29
  • http://msdn.microsoft.com/en-us/library/system.string - .Net strings are represented by this. – ikh Dec 24 '14 at 08:31
  • 3
    You are pointing `a` to the same value where `b` is pointing, in your case `ca`. After that you say that `b` must point to another value `cab` this does not mean that `a` is now pointing to `cab` it is still pointing to `ca` – Mivaweb Dec 24 '14 at 08:31
  • Possible duplicate of http://stackoverflow.com/questions/636932/in-c-why-is-string-a-reference-type-that-behaves-like-a-value-type. – Patrick Hofman Dec 24 '14 at 08:32
  • @DeepakMishra Probably because this is a basic misconception about how C# and references works, and as far as I know every introductory textbook explains this. – Mark Rotteveel Dec 24 '14 at 08:41
  • You might have gotten downvotes because you ask why string does not behave like a reference type when, in fact, it behaves exactly like a reference type. – Theodoros Chatzigiannakis Dec 24 '14 at 08:44
  • ok I will edit the post by comparing it with a refernce types having different answer. If it is a misconception, then I would request you to please answer the misconception after that. It will help other people also who have the same miconception I have. – Deepak Mishra Dec 24 '14 at 08:48
  • @TheodorosChatzigiannakis: Can you explain now? – Deepak Mishra Dec 24 '14 at 08:57
  • Better Title: Interview question about assignment and reference types – DrKoch Dec 24 '14 at 13:35

5 Answers5

8

This situation has nothing about immutability. It is all about how reference types works.

In your;

a = b;

line, your b and a reference points the same object which is "ca" and changing b reference to another object doesn't effect the object that a points.

Let me try to explain line by line what is going on here;

First of all, string is a reference type and reference types have 2 parts. An object and a reference to that object.

In your

string a = "abc";

line, you have an "abc" object and a reference to that object called a.

string b = "ca";

In this line, you have an "ca" object and a reference to that object called b.

a = b;

In this line, now a reference points the same object that b reference points which is "ca".

b = "cab";

In this line, you create a new object called "cab" and your b reference now points this object. It doesn't points "ca" object anymore.

Console.WriteLine(a);

In this line, since a still refers to "ca" object, this string will be printed. Changing the object that b refers doesn't effect it.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
  • @SonerGönül Can you explain the edited code now? Why a1.a is coming as "cab" but a is coming as "ca" only. I am sorry if I were a little offensive. But this is slighly confusing to me. – Deepak Mishra Dec 24 '14 at 09:00
  • @DeepakMishra This is the same principle as I explained in my answer. When you say `string b = "ca";` and after `a = b;`, now your `a` refer to `ca` and changing `b` to another object with `b = "cab";` line, doesn't effect it. And when you say `a1 = b1;` and after `b1.a = "cab";` since `a1` and `b1` points the same object, changing `b1.a = "cab";` will change `a1.a` as well because you changed (created new `string`) the object itself that **both** reference points. – Soner Gönül Dec 24 '14 at 09:14
  • @DeepakMishra And remember, in `string a = "abc";` line, `a` is a local variable but in `a1.a = "abc"` line, `a` is a field of `A` class. – Soner Gönül Dec 24 '14 at 09:37
  • @SonerGönül: When you said a is the field of A class, you actually answered my question. One more thing I would like to add here that references are not transitive i.e a1=b1; b1=c1; would not cause a1=c1 and a1=b1 would also not be valid. Thanks for the answers which made me to research further but still I am not able to understand the reason of downvotes. – Deepak Mishra Dec 24 '14 at 10:04
1

There isn't the case of immutability of strings. The string is a reference type. Initially, you set a to point to a string with value "abc". While you set b to point to a string with value ca. Later, you set a be equals to b. Since they are both reference types, the a now points, where b points to. In other words now a points to ca. Later you just change where b points to. This change doesn't affect the value that a points to.

Christos
  • 53,228
  • 8
  • 76
  • 108
  • Good one, because I understood your answer in less time than the more upvoted post because that was actually too long. :D – Deepak Mishra Dec 24 '14 at 10:10
1

This has more to do with the difference between pointers and references in C#.

With a = b, you don't point a to whatever b holds now and in the future. You don't assign the pointer variable a to the pointer variable b (the way C++ pointer act).

Because they are references, a gets initialized with whatever (string) value b holds at that moment. And that's it, any other ties to b are lost.

It's like a copy constructor, a new string value is created for a. When b gets changed again, a will not be affected. Because they hold different objects!

Edit:

Correction on the copying procedure: no new object is actually created. What's different from a pointer is the one-time assignment of the memory address of the object at that point in time. a will point to the same string value, in memory, hold by b at that point in time and that's it, no further ties to b in the future.

Cristian Scutaru
  • 1,375
  • 19
  • 23
  • 1
    Your answer implies something that isn't entirely correct - after all, references are typically implemented as pointers. I think that what you are comparing in your answer isn't C# references versus C++ pointers, but C# references versus C++ pointer-pointers. Copying the value of a C++ pointer to another C++ pointer of the same kind by simple assignment doesn't introduce any ties between the two. – Theodoros Chatzigiannakis Dec 24 '14 at 09:36
  • @Theodoros Chatzigiannakis, see my later Edit. I think we both (and Christos here below) are in fact trying to say the same thing: that's kind of a one time assignment of a memory pointer, with no further/future ties to the right-side object variable. – Cristian Scutaru Dec 24 '14 at 09:46
  • @CristiS. Thanks, I liked the way you tried to understand the actual question. – Deepak Mishra Dec 24 '14 at 10:29
1

While Sonor's answer is brilliant and correct it misses one important point. The whole point has nothing to do with strings. The puzzle works with integers exactly the same way:

class A
{
    public int a;
}

static void Main(string[] args)
{
    A a1 = new A();
    A b1 = new A();
    int a = 123;
    a1.a = 123;
    int b = 31;
    b1.a = 31;
    a = b;
    a1 = b1;
    b = 312;
    b1.a = 312;
    Console.WriteLine(a);
    Console.WriteLine(a1.a);
    Console.ReadLine();
}

The critical fact is a1 and b1 being references. (Not a and b)

DrKoch
  • 9,556
  • 2
  • 34
  • 43
0

This question has actually solved some of my misconception regarding string literals.

  1. What does string a="abc"; means?

I was actually considering "abc" as the value which a points to.

But that was partially correct.

"abc" is the string literal which is itself a string object (created by ldstr IL instruction) as mentioned in the below link and the statement basically makes the a local variable point to the string literal

Why don't we use new operator while initializing a string?

  1. What the below code meant to me?

    string b = "ca";
    a = b;
    b = "cab";
    

I thought "cab" as the update to the value which b points to and hence a will also be updated. I was thinking that value does not get updated due the immutability of string.

But as the string literal is not a value but an object which is equivalent to the below code: (hence gives answer to my question)

string b = "ca";
a = b;
string c = "cab";
b = c;
Community
  • 1
  • 1
Deepak Mishra
  • 2,984
  • 1
  • 26
  • 32