Почему .ToString() в нулевой строке вызывает нулевую ошибку, когда .ToString() отлично работает в nullable int с нулевым значением?

selectedItem имеет два поля:

  • int? _cost
  • string _serialNumber

В этом примере _cost и _serialNumber of selectedItem BOTH null. Я читаю поля selectedItem через их свойства и заполняя текстовые поля своими значениями, когда...

TextBox1.Text = selectedItem.Cost.ToString(); //no error
TextBox2.Text = selectedItem.SerialNumber.ToString(); //error

Я понимаю, что SerialNumber.ToString() избыточно (потому что это уже строка), но я не понимаю, почему это вызывает это исключение:

Nullable object должен иметь значение.

  • int? _cost имеет значение NULL и не имеет значения, но это не дает мне исключения.
  • string _serialNumber имеет значение NULL и не имеет значения, но делает исключение.

Этот question затрагивает это, парень по сути задает одно и то же, но нет назначенного ответа, и он также не объясняет, почему nullable int? Например, могу ли я использовать .ToString() в nullable int, но не в нулевой строке?

Ответ 1

Потому что string type null действительно ничего не указывает, в памяти нет объекта.
Но int? type (nullable) даже со значением, установленным в null, все еще указывает на некоторый объект.
Если вы читаете Джеффри Рихтера "CLR через С#", вы обнаружите, что тип с нулевым значением - это просто классы фасадов для общих типов с некоторыми инкапсулированными логиками, чтобы сделать работу с нулевым DB более удобным.

Отметьте msdn, чтобы узнать о типах с возможностью NULL.

Ответ 2

A Nullable<int> является struct и не может быть действительно нулевым. Таким образом, вызов метода с "пустой" структурой все еще работает.

Существует некоторая "магия компилятора", которая делает _cost == null допустимым выражение.

Ответ 3

int? на самом деле не объект, а объект Nullable<int>.

Итак, когда вы объявляете int? _Cost, вы фактически объявляете Nullable<int> _Cost, а свойство _Cost.Value - это undefined не сам объект _Cost.

На самом деле синтаксический сахар обычно использует типы non nullable типа int, bool или decimal.

Согласно MSDN:

Синтаксис T? является сокращением для System.Nullable<T>, где T - тип значения. Эти две формы взаимозаменяемы.

Ответ 4

Строка является ссылочным типом, но nullable int является типом значения. Вот хорошее обсуждение различий http://www.albahari.com/valuevsreftypes.aspx.

Ответ 5

Nullable на самом деле представляет собой структуру, раскрывающую два свойства: HasValue и Value. Если вы сделаете это, вы получите сообщение об ошибке:

int? i = null;
i.Value.ToString()

Чтобы проверить, действительно ли ваш int? имеет значение, доступ к которому можно получить i.HasValue

Ответ 6

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

Ответ 7

Причина проста. int? или Nullable<int> является структурой или тип значения, он никогда не может быть null.

Итак, что происходит, когда мы делаем:

int? _cost = null;

_cost будет иметь два поля Value и HasValue, когда мы назначим null - _cost, флаг HasValue будет установлен в false, а поле Value будет присвоено default(T) в случае int? это будет 0.

Теперь, когда мы вызываем ToString на _cost, Nullable<T> имеет переопределенное определение ToString, которое, если мы посмотрим на Microsoft предоставила Исходная ссылка реализована следующим образом:

public override string ToString() {
    return HasValue ? value.ToString() : "";
}

Таким образом, он возвращает пустую строку, поскольку _cost присваивается null.

Теперь идет случай string _serialNumber. Быть string является ссылочным типом, и он может чисто удерживать null. Если он удерживает null, то вызов ToString на нем приведет к созданию Null Reference Exception, как ожидалось.

Вы можете видеть: Типы значений и типы ссылок - MSDN

Ответ 8

TextBox2.Text = selectedItem.SerialNumber.ToString(); //error

ошибка yiels, потому что она вызывает функцию ToString(), которая является членом System.String. Эта функция возвращает этот экземпляр System.String; фактическое преобразование не выполняется. Кроме того, String является ссылочным типом. Тип ссылки содержит указатель на другую ячейку памяти, в которой хранятся данные.

TextBox1.Text = selectedItem.Cost.ToString(); //no error

не выдает ошибки, потому что вызывает функцию ToString(), которая является членом System.Integer. Эта функция преобразует числовое значение этого экземпляра в эквивалентное строковое представление. Кроме того, Integer является типом значений. Тип данных - это тип значения, если он содержит данные в пределах собственного распределения памяти.

То же имя функции ToString(), но выполняет различную задачу.

Метод String.ToString

Метод Int32.ToString

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