可空类型和问题

Nullable type and if issue

这是最简单的一段代码

Dim testInvoiceDate As DateTime? = If(String.IsNullOrEmpty(Nothing),
                                      Nothing,
                                      New DateTime(2018, 3, 20))

为什么变量testInvoiceDate不是Nothing,而是#1/1/0001 12:00:00 AM#?! 这很奇怪!

在 VB.NET 中编译(而不是 C#),因为这里 Nothing 有多重含义。

  1. null
  2. 该类型的默认值

在这种情况下,编译器使用第二个选项,因为在 DateTimeNothing 之间没有隐式转换(在 null 的含义中)。

DateTime(一个Structure是值类型)的默认值是#1/1/0001 12:00:00 AM#

你可以用它来获得 Nullable(Of DateTime):

Dim testInvoiceDate As DateTime? = If(String.IsNullOrEmpty(Nothing), New Nullable(Of Date), New DateTime(2018, 3, 20))

或使用 If:

Dim testInvoiceDate As DateTime? = Nothing
If Not String.IsNullOrEmpty(Nothing) Then testInvoiceDate = New DateTime(2018, 3, 20)

If-语句将return两种情况下的相同数据类型。
因为 False-case 中的 return-type 是 DateTime,return-type 是 DateTime-default-value True-案例.

DateTime 的默认值是 DateTime.MinValue,即 #1/1/0001 12:00:00 AM#

这将按预期工作:

Dim testInvoiceDate As DateTime? = If(String.IsNullOrEmpty(Nothing),
                                      Nothing,
                                      New DateTime?(New Date(2018, 3, 20)))
VB.Net 中的

Nothing 等同于 C# 中的 default(T):给定类型的默认值。

  • 对于值类型,这基本上等同于 'zero':0 代表 IntegerFalse 代表 BooleanDateTime.MinValue DateTime, ...
  • 对于引用类型,它是 null 值(指的是什么都没有的引用)。

因此将 Nothing 分配给 DateTime 与将其分配 DateTime.MinValue

相同

这是因为您正在使用 If() 的 3 参数形式。它将尝试 return 基于参数 2 和 3 的相同类型,因此参数 2 中的 Nothing 被转换为 DateTime(你得到 DateTime.MinValue)。

如果您使用 2 参数形式,它适用 null-coalescing,即当第一个参数(必须是 Object 或可空类型)是 Nothing 时,它 return 是第二个参数,否则 return 是第一个参数。

如果你使用 Dim foo As DateTime? = If(Nothing, new DateTime(2018, 3, 20))你会得到预期的价值。