Подтвердить что ты не робот

Строки против классов, когда оба являются ссылочными типами

Вот как прошло мое последнее интервью:

Вопрос: Где хранятся строки?

Ответ: Куча, так как это ссылочный тип

Вопрос: Объясните мне следующий код:

static void Main(string[] args)
{
     string one = "test";
     string two = one;
     one = one + " string";

     Console.WriteLine("One is {0}" , one);
     Console.WriteLine("Two is {0}", two);
}

Ответ: Нарисуйте две диаграммы, как показано ниже:

(представляет собой оператор string two = one;

enter image description here

(представляет оператор, one = one + " string";. Новая цепочка создается в куче и назначается)

enter image description here

Вопрос: Правильно. Нарисуйте аналогичный фрагмент кода ниже:

class Program
{
    static void Main(string[] args)
    {
        Test one = new Test { someString = "test" };
        Test two = one;
        one.someString = "test String";

        Console.WriteLine("One is {0}", one.someString);
        Console.WriteLine("Two is {0}", two.someString);
    }
}

class Test
{
    public string someString { get; set; }
}

Ответ:

[Test two = one] enter image description here

one.someString = "test String";

enter image description here

Вопрос: Хорошо. Вы сказали, что оба strings и classes являются ссылочными типами. Тогда почему был создан новый объект для строки и назначен значение, тогда как для класса изменилось существующее свойство строки?

Ответ:. Поскольку строки являются неизменяемыми, тогда как классы изменяемы.

(Несмотря на то, что я очистил интервью, я все еще не понял этого поведения. Почему дизайнеры класса сделали его изменчивым, сохраняя неизменяемые строки? Во всем мире есть много разных ответов, но может ли кто-нибудь сделать это простым, объяснив это конкретное поведение с приведенным выше кодом?)

4b9b3361

Ответ 1

Одна из причин, когда строки были неизменными, хотя они и являются ссылочными типами, заключались в том, чтобы заставить их выглядеть и вести себя как примитивные типы (например, int, double, float).

Это также причина, по которой строки являются единственным ссылочным типом, который может быть представлен как литерал (например, "some string"). Многие другие языки используют один и тот же подход, например, Java.

Ответ 2

Строки неизменяемы, потому что логически они представляют собой одно значение, а быть изменяемым приведет к неожиданному поведению.

Тем не менее, строки являются не типами значений, потому что они, как правило, передаются по множеству, что потребует большого количества копий значений. Это станет довольно дорогостоящим, особенно для больших строк.

Итак, чтобы получить лучшее из обоих миров, строки в .Net являются ссылочными типами, но также неизменяемы.

Ответ 3

Команда one = ... устанавливает указатель * с именем one в новое значение. Поскольку two - другой указатель, он сохраняет исходное значение.

Команда one.someString = ... изменяет объект , указанный one. two по-прежнему является другим указателем, но поскольку он указывает на тот же объект, изменения разделяются между ними.

Ответ 4

Буфер обмена цепочками. В вашем случае, если одна и две были строками, они были бы отдельными объектами (два объекта в куче), но внутри они указывали бы на один и тот же буфер (третий объект в куче).