VB.NET - Nullable DateTime и тернарный оператор

У меня возникают проблемы с Nullable DateTime в VB.NET(VS 2010).

Способ 1

If String.IsNullOrEmpty(LastCalibrationDateTextBox.Text) Then
    gauge.LastCalibrationDate = Nothing
Else
    gauge.LastCalibrationDate = DateTime.Parse(LastCalibrationDateTextBox.Text)
End If

Способ 2

gauge.LastCalibrationDate = If(String.IsNullOrEmpty(LastCalibrationDateTextBox.Text), Nothing, DateTime.Parse(LastCalibrationDateTextBox.Text))

Когда задана пустая строка, метод 1 присваивает значение Null (Nothing) для параметра gauge.LastCalibrationDate, но метод 2 присваивает ему DateTime.MinValue.

В других местах моего кода у меня есть:

LastCalibrationDate = If(IsDBNull(dr("LastCalibrationDate")), Nothing, dr("LastCalibrationDate"))

Это правильно присваивает Null (Nothing) от тернарного оператора Nullable DateTime.

Что мне не хватает? Спасибо!

Ответ 1

Я признаю, что я не эксперт в этом, но, по-видимому, это связано с двумя вещами:

  • Тернерарный оператор If может возвращать только один тип, в этом случае тип даты, а не тип даты с нулевой датой
  • Значение VB.Net Nothing на самом деле не равно null, но эквивалентно значению по умолчанию указанного типа, в данном случае дате, а не дате null. Следовательно, минимальное значение даты.

Я получил большую часть информации для этого ответа из этого сообщения SO: Тернарный оператор VB vs С#: почему решает целое число, а не целое?

Надеюсь, что это поможет, и кто-то вроде Джоэла Коэхорна может пролить больше света на эту тему.

Ответ 2

Боб Мак прав. Обратите особое внимание на его вторую точку - это не так в С#.

Что вам нужно сделать, это заставить Nothing присвоить null DateTime, произведя его следующим образом:

gauge.LastCalibrationDate = If(String.IsNullOrEmpty(LastCalibrationDateTextBox.Text), CType(Nothing, DateTime?), DateTime.Parse(LastCalibrationDateTextBox.Text))

Вот фрагмент, демонстрирующий:

Dim myDate As DateTime?
' try with the empty string, then try with DateTime.Now.ToString '
Dim input = ""
myDate = If(String.IsNullOrEmpty(input), CType(Nothing, DateTime?), DateTime.Parse(input))
Console.WriteLine(myDate)

Вместо кастинга вы также можете объявить новый значение с возможностью NULL: New Nullable(Of DateTime) или New DateTime?(). Последний формат выглядит немного странным, но он действителен.