VB.NET无日期时间?数据阅读器

VB.NET无日期时间?数据阅读器,vb.net,datetime,nullable,datareader,getvalue,Vb.net,Datetime,Nullable,Datareader,Getvalue,一个简单的问题,如果内联: 将mydate设置为datetime '版本1(有效!) 值=零 '版本2(不起作用!) 值=#12:00:00# 有人能解释一下为什么版本2会得到这个值吗?打开开关选项!隐式转换正在进行 有关示例,请参见答案 更新:如果您设置的类型不可为空,则这两条If语句完全相同。如果它们是可空的(默认情况下DateTime不是),那么两个If语句会产生不同的结果。例如: 测试1: 代码: 结果: DateTime? dateTime = new DateTime?(Dat

一个简单的问题,如果内联: 将mydate设置为datetime


'版本1(有效!)

值=零


'版本2(不起作用!)

值=#12:00:00#



有人能解释一下为什么版本2会得到这个值吗?

打开开关选项!隐式转换正在进行

有关示例,请参见答案

更新:如果您设置的类型不可为空,则这两条If语句完全相同。如果它们是可空的(默认情况下DateTime不是),那么两个If语句会产生不同的结果。例如:

测试1:

代码:

结果:

DateTime? dateTime = new DateTime?(DateTime.MinValue);
DateTime? dateTime = null;
测试2:

代码:

Dim d As DateTime?
If True Then
    d = Nothing
Else
    d = Now
End If
结果:

DateTime? dateTime = new DateTime?(DateTime.MinValue);
DateTime? dateTime = null;

这归结为编译器必须对
If
进行类型分析。请记住,这与C的null不同,它更接近于
default(T)

如果变量的值类型不可为null,则不为其赋值会将其设置为其声明类型的默认值

现在,当编译器分析If时,必须确定整个表达式的类型。下面是它所看到的:

If(Boolean,<AnyType>,DateTime)

根据第11.22节(条件表达式):

如果提供了三个操作数,则所有三个表达式都必须分类为值,并且第一个操作数必须是布尔表达式。如果表达式的结果为真,则第二个表达式将是运算符的结果,否则第三个表达式将是运算符的结果。表达式的结果类型是第二个表达式和第三个表达式类型之间的主导类型。如果没有主类型,则会发生编译时错误

(我的重点)


请注意,这里没有关于“如果在赋值语句中使用该语句,还可以考虑所赋值变量的声明类型”的条件文本。

这没有任何意义。检查您的输入信息(例如,如果您一个接一个地编写代码,他们将分析不同的行)。内联或多行条件肯定具有相同的行为;只是正确地使用它们。不是很清楚,你是对的,编辑过,它们看起来完全一样,除了一个使用三元if。请提供足够的代码来重现问题?你可以随时查看IL来了解差异。那么你能告诉我为什么我得到了同样的结果:如果(真的,没有,现在)@SamMakin的回答证明了两种类型的可空日期条件之间存在着非常奇怪的差异!!真奇怪。在任何情况下,建议的条件都太不清楚(可能很容易涉及到不同的输入)。您是对的-它不会警告Option Strict On。原因仍然是转换。这是返回一个新的日期时间,而不是什么。这当然很奇怪,而且你的答案是值得的(也是问题)。在任何情况下,严格的开/关问题在这里都没有任何影响。但问题是:为什么当您执行
mydate=Nothing
时,它会得到
Nothing
而不是逻辑最小日期值?为什么三元运算符的行为不同?在我看来,这是一个bug(虽然不是很相关):三元运算符应该总是提供与条件(正常赋值)相同的结果。@varocabas-语言按照指定的方式工作。它不符合你的期望,这是不存在的。我试图解释为什么语言是这样设计的,为什么它不符合您的期望。我不知道如何才能说,
If
运算符中的类型求值和赋值分析必然是解耦的。@SamMakin-是的,
DirectCast
也可以使用。你甚至可以现在施放
,而不是
什么都不施放。关键部分是让编译器选择
DateTime?
。事实上,我已经用C做了一些测试,我理解了这个问题。如果您这样做:
d=If(True,Nothing,CType(Now,DateTime?)
它的行为完全符合预期。当您直接分配
Now
时,您迫使三元运算符认为它处理的是
DateTime
,而不是
DateTime?
。我的观点是C不允许我做这样的事情(抱怨
Now
不是
DateTime?
),这就是我意识到这个问题的原因。如前所述,这种行为是正常的(即,奇怪的发生是因为没有转换/转换到正确的类型),但VB.NET应该警告这个问题(即,不允许这种行为使用
选项Strict Off
,C做得对)。
If(Boolean,<AnyType>,DateTime)
mydate = If(dtReader.IsDBNull(dtReader.GetOrdinal("mydate")), _
          CType(Nothing,DateTime?), _
          dtReader.GetDateTime(dtReader.GetOrdinal("mydate")))