Почему добавление null в строку допустимо?

Статья MSDN об Основах Строки показывает это:

string str = "hello";
string nullStr = null;
string emptyStr = "";

string tempStr = str + nullStr; // tempStr = "hello"
bool b = (emptyStr == nullStr);// b = false;
string newStr = emptyStr + nullStr; // creates a new empty string
int len = nullStr.Length; // throws NullReferenceException

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

5 ответов

Решение

Из MSDN:

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

Больше информации о бинарном операторе +:

Бинарный оператор + выполняет конкатенацию строк, когда один или оба операнда имеют тип string.

Если операнд конкатенации строк равен нулю, подставляется пустая строка. В противном случае любой нестроковый аргумент преобразуется в его строковое представление, вызывая виртуальный метод ToString, унаследованный от объекта типа.

Если ToString возвращает ноль, подставляется пустая строка.

Я согласен, что концептуально строки - это просто значения. Однако рассмотрим следующий код:

int? i = null;
i += 1; // The result of this is that i == null

Если бы другие операторы типа значения использовали default() так, как строковые операторы преобразуют ноль в "", ваше объяснение имело бы смысл.

Проще всего сказать, что строковые операторы - это ярлык (особый случай) для удобства.

Концептуально, строки обычно рассматриваются как значения, а не как ссылки на объекты, которые имеют идентичность. Одна из главных причин того, что они не structs с семантикой значения происходит из-за накладных расходов, связанных с копированием при назначении. Если бы строки были значениями, они не могли бы быть обнуляемыми, и поэтому null просто обрабатывается оператором "+", как если бы это была пустая строка (т. е. как будто default(string) == "" как только default(int) == 0).

Я предполагаю, что разработчики языка (или стандартной библиотеки) решили, что это будет достаточно распространенным случаем, что они окажут программистам услугу.

(Опрятно! Я всегда предполагал, что в результате исключения с нулем будет сделано исключение!)

Причина, по которой он не генерирует исключение нулевой ссылки, заключается в том, что вы на самом деле не пытаетесь получить доступ к каким-либо свойствам или методам нулевого объекта. Как и в цитатах CMS, при конкатенации строк нулевые значения заменяются пустыми строками.

Другие вопросы по тегам