可空类型和问题
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
有多重含义。
null
- 该类型的默认值
在这种情况下,编译器使用第二个选项,因为在 DateTime
和 Nothing
之间没有隐式转换(在 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
代表 Integer
,False
代表 Boolean
,DateTime.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))
你会得到预期的价值。
这是最简单的一段代码
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
有多重含义。
null
- 该类型的默认值
在这种情况下,编译器使用第二个选项,因为在 DateTime
和 Nothing
之间没有隐式转换(在 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)))
Nothing
等同于 C# 中的 default(T)
:给定类型的默认值。
- 对于值类型,这基本上等同于 'zero':
0
代表Integer
,False
代表Boolean
,DateTime.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))
你会得到预期的价值。