Типы значений и ссылочные типы

Переменная xStr - ссылочный тип или нет ?

Почему переменную xStr - не затрагивают изменения как объект stringBuilder ?

В метод всё таки попадает копия значения, а не копия ссылки ?

class Program
{
    static void Main(string[] args)
    {
        int xInt = 0;
        string xStr = "0";
        StringBuilder stringBuilder = new("0");

        TestChange(xInt);
        TestChange(xStr);
        TestChange(stringBuilder);

        Console.WriteLine(xInt);
        Console.WriteLine(xStr);
        Console.WriteLine(stringBuilder);
    }

    static void TestChange(int xInt) 
    {
        xInt = 1;
    }

    static void TestChange(string xStr)
    {
        xStr = "1";
    }

    static void TestChange(StringBuilder stringBuilder)
    {
        stringBuilder.Clear();
        stringBuilder.Append("1");
    }
}

В консоли вывод:

0

0

1

UPD

class Program
{
    static void Main(string[] args)
    {
        int xInt = 0;
        string xStr = "0";
        StringBuilder stringBuilder = new("0");

        TestChange(xInt);
        TestChange(xStr);
        TestChange(stringBuilder);

        Console.WriteLine(xInt);
        Console.WriteLine(xStr);
        Console.WriteLine(stringBuilder);
    }

    static void TestChange(int xInt) 
    {
        xInt = 1;
    }

    static void TestChange(string xStr)
    {
        xStr = null;
    }

    static void TestChange(StringBuilder stringBuilder)
    {
        stringBuilder = null;
    }
}

В консоли вывод:

0

0

0

UPD: Разобрался в понимании - спасибо!


Ответы (3 шт):

Автор решения: Sergey K.

В языке C# тип String является неизменяемым. Это означает, что, когда вы присваиваете одной переменной новое значение, то создаётся новый объект типа String и сохраняется в этой пременной, а прежний объект теряется, если на него не указывают другие ссылки.

→ Ссылка
Автор решения: Igor

Подумайте о разнице между

variable = another_value;

и

variable.modifyVariableContent();

внутри функции, куда передается variable.

→ Ссылка
Автор решения: Ivan Silkin

Чтобы Int менялся, его надо по ссылке передавать, а не по значению:

static void TestChange(ref int xInt) 
{
    xInt = 1;
}

Иначе создаётся локальная переменная типа int в функции. Согласно ответу @SergeyK, со стрингами та же история.

using NUnit.Framework;
        [Test]
        public static void Test()
        {
            int xInt = 1;
            string xStr = "1";
            StringBuilder stringBuilder = new("1");

            TestChange(ref xInt);
            TestChange(ref xStr);
            TestChange(ref stringBuilder);

            Console.WriteLine(xInt);
            Console.WriteLine(xStr);
            Console.WriteLine(stringBuilder);
        }
        static void TestChange<T>(ref T value)
        {
            dynamic d = null;
            if (typeof(string) == typeof(T))
                d = "0";
            else if (typeof(int) == typeof(T)) 
                d = 0;
            else if (typeof(StringBuilder) == typeof(T))
                d = new StringBuilder("0");
            value = d;
        }

Standard Output: 0 0 0

→ Ссылка