-1

I extremely get counfused about types of reference. I searched and saw that the string type is a reference type. Is not ?

My problem is :

I copied a string variable to another and I changed the value of first one however the second one has still the same value. I did not understand this issue. Even though type of string is a reference type, the second one does not change. Also I tried the boxing method but I could not obtain the result.

I read this article In C#, why is String a reference type that behaves like a value type?, however I still get counfused.

And this is my code:

        string my_text1 = "My text 1";
        string my_text2 = my_text1;

        my_text1 = "My text 2";
        Console.WriteLine("First text --> " + my_text1); // It prints My text 2
        Console.WriteLine("Second text -->" + my_text2); // It prints My text 1(I want it prints "My text 2" too)

        string text_1 = "Example 1";
        object text_2 = text_1;

        text_1 = "Example 2";
        Console.WriteLine("First example --> " + text_1); // It prints Example 2
        Console.WriteLine("Second example -->" + text_2);// It prints Example 1
Ahmet Furkan
  • 84
  • 11

3 Answers3

5

Assignment is an action that affects variables. Variables themselves are independent. The important distinction between value and reference types is whether the data is stored in the variable itself or elsewhere (and the variable only contains a reference).

So, when assigning to a variable, you change the contents of that variable1. In and of itself, this will have no visible effects on any other variable.

Where you will often notice a difference between value types and reference types is when you mutate the data. Here, a difference is noticeable, because when you mutate a value type's data, you do it via a specific variable, and what you're mutating is that variable's copy of the data. Whereas when you mutate the data for a reference type, you mutate the data and all variables which reference that same copy of the data will have the change visible to them.

But, since string doesn't have any (without reflection tricks or unsafe code) mutable fields or mutating methods, you'll never be able to observe such mutations with string variables.


1Here I'm referring to local variables and fields. Other forms of assignment (e.g. to properties) can run arbitrary code and so of course they could have other visible side effects.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
3

Because strings are an immutable reference type.

An immutable type is a type of object whose data cannot be changed after its creation. There are many benefits of immutable strings. It improves runtime efficiency and security(A process cannot change the string by injecting something). You can read it for detail explanation.

And, the reason why the string is reference type is, they can be huge and need to store in heap. Details here

You can use StringBuilder which is mutable.

StringBuilder my_text1 = new StringBuilder("My text 1");
StringBuilder my_text2 = new StringBuilder("My text 2");

my_text1 = my_text2;
Console.WriteLine("First text --> " + my_text1); 
Console.WriteLine("Second text -->" + my_text2);

In this above example, you will get "My text 2" for both of the expression.

Noor A Shuvo
  • 2,639
  • 3
  • 23
  • 48
0

like Damien_The_Unbeliever pointed out, Assignment always changes that variable and doesn't affect previous variables.

Consider the following example with classes

class Program
{
    static void Main(string[] args)
    {
        Foo my_text1 = new Foo("My text 1");
        Foo my_text2 = my_text1;

        my_text1 = new Foo("My text 2");
        Console.WriteLine("First text --> " + my_text1); // It prints My text 2
        Console.WriteLine("Second text -->" + my_text2); // It prints My text 1

        Foo text_1 = new Foo("Example 1");
        object text_2 = text_1;

        text_1 = new Foo("Example 2");
        Console.WriteLine("First example --> " + text_1); // It prints Example 2
        Console.WriteLine("Second example -->" + text_2);// It prints Example 1
    }
}

class Foo
{
    private readonly string _name;

    public Foo(string name)
    {
        _name = name;
    }

    public override string ToString()
    {
        return _name;
    }
}

a string does not quite work in this way, but it gives you an idea of ​​what Damien_The_Unbeliever meant

If you want a variable to act like a reference, you should add the ref keyword

string my_text1 = "My text 1";
ref string my_text2 = ref my_text1;

my_text1 = "My text 2";
Console.WriteLine("First text --> " + my_text1); // It prints My text 2
Console.WriteLine("Second text -->" + my_text2); // It prints My text 2
Pepernoot
  • 3,409
  • 3
  • 21
  • 46