В .NET, каково обоснование для инициализации строк в ноль? - PullRequest
5 голосов
/ 14 октября 2011

Я понимаю, что String - это объект, в отличие от Int, и переменные объекта, как правило, ни на что не указывают, пока вы не создадите объект. Так что я знаю, как это работает.

Но, с точки зрения простого практического программирования, почему .NET не инициализирует строку как пустую (""), так как это, безусловно, наиболее распространенное использование строковой переменной - как строка, а не как объект

У меня никогда (пока) не было необходимости, чтобы строка была нулевой, то есть "не строка". Это кажется редким требованием. Я не могу сказать, что переменная типа int равна нулю, так зачем это делать со строкой? Наличие его в качестве опции, несомненно, необходимо, но почему .NET делает его нулевым для начала, когда int и т. Д. Заданы правильные начальные значения?

Я спрашиваю, потому что мне нравится понимать не только, как что-то работает, но и почему, так как это уменьшило мое желание разглагольствовать о том, как странно это кажется. :)

Ответы [ 4 ]

7 голосов
/ 14 октября 2011

Строки не инициализируются как null. Вы путаете инициализацию с объявлением. Всякий раз, когда вы объявляете переменную вроде:

 Foo myFoo;

Он начинается с нуля, пока вы на самом деле не вызовете его конструктор. Вот так:

Foo myFoo = new Foo();

Теперь традиционно вы не вызываете конструкторы для строкового класса, вы создаете их экземпляры с помощью строковых литералов, таких как:

string myString = "foo";

Хотя есть конструкторы для строкового класса, некоторые из них, но все они используют некоторый массив символов / байтов, чтобы использовать для создания строки. Что никогда не происходит, это:

// initialize an empty string ("")
string myString = new string();

Это потому, что класс строки неизменен , то есть после того, как он был создан, вы никогда не сможете его изменить, вы можете только создать новую строку и установить переменную, указывающую на нее (вот почему все методы строкового класса возвращают новую строку, а не изменяют тот, для которого вы вызвали метод). Поэтому на самом деле нет смысла инициализировать какое-либо значение по умолчанию, потому что, как только вы это сделаете, вы застрянете с ним.

4 голосов
/ 14 октября 2011

String является ссылочным типом. Значением по умолчанию для всех ссылочных типов является null. Это определяется языком C #, и нет способа изменить это поведение.

Даже если дизайнеры класса String хотели , чтобы значение default(String) было пустой строкой (в чем я сомневаюсь), ее просто невозможно изменить.

0 голосов
/ 14 октября 2011

Вопрос связан с другим вопросом Почему строка является ссылочным типом?

Когда они выбрали string s в качестве ссылочных типов, ясно, что они должны были сделать default(string) == null, так же, как default(any reference type) == null.

Тогда возникает более разумный вопрос: «почему строки ссылаются на типы, а не, например, на struct String { private char[] MyInternalSting; }? Потому что они так решили (даже приведенная мною ссылка дает больше логики кыргызского мышления, чем реальных причин ... «потому что иначе вы не могли бы сделать Object.ReferenceEquals», как если бы вы могли сделать Object.ReferenceEquals с числами и другими типами значений).

Некоторые другие разумные вопросы могут быть следующими: почему "A" + null == "A" вместо NullPointerException или ArgumentNullException? (Я не смог найти разумный ответ ... Возможно, для совместимости с VB.NET)

0 голосов
/ 14 октября 2011

Поскольку string является ссылочным типом, а типами ссылок по умолчанию является null. Это просто последовательное поведение. Я был бы удивлен, если бы он по умолчанию на что-то другое.

Я могу привести пример, в котором пустые строки в качестве значения по умолчанию имеют смысл. Допустим, вы анализируете следующие узлы XML для имени attribute.

<node name=""/>
<node />

Учитывая следующую структуру, как можно дифференцировать 2 узла?

struct Node
{
  public string Name { get; }
}

Для <node name=""/> ваш анализатор видит атрибут name и затем устанавливает Node.Name в string.Empty. Для <node /> ваш анализатор не видит атрибута name и ничего не назначает.

Таким образом, у вас останется Node.Name==string.Empty для первого узла, а у второго узла будет Node.Name==null. Что имеет смысл.

...