Почему добавление 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() так, как строковые операторы преобразуют ноль в "", ваше объяснение имело бы смысл.
Проще всего сказать, что строковые операторы - это ярлык (особый случай) для удобства.
Концептуально, строки обычно рассматриваются как значения, а не как ссылки на объекты, которые имеют идентичность. Одна из главных причин того, что они не struct
s с семантикой значения происходит из-за накладных расходов, связанных с копированием при назначении. Если бы строки были значениями, они не могли бы быть обнуляемыми, и поэтому null
просто обрабатывается оператором "+", как если бы это была пустая строка (т. е. как будто default(string) == ""
как только default(int) == 0
).
Я предполагаю, что разработчики языка (или стандартной библиотеки) решили, что это будет достаточно распространенным случаем, что они окажут программистам услугу.
(Опрятно! Я всегда предполагал, что в результате исключения с нулем будет сделано исключение!)
Причина, по которой он не генерирует исключение нулевой ссылки, заключается в том, что вы на самом деле не пытаетесь получить доступ к каким-либо свойствам или методам нулевого объекта. Как и в цитатах CMS, при конкатенации строк нулевые значения заменяются пустыми строками.