Почему .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
Типы значений и типы ссылок