IF运算符与If之间的评估差异,那么,否则

时间:2013-10-29 17:46:23

标签: asp.net .net sql sql-server vb.net

我遇到了一个我没想到并需要帮助回答的场景。我们当前的系统调用SQL存储过程并因此创建SQL命令,添加参数并添加这些参数的值...比如插入。

我们的代码如下所示......

cmd.Parameters.Add("@MyTimestamp", SqlDbType.DateTime)
If MyObject.MyTimestamp <> Nothing Then
   cmd.Parameters.Item("@MyTimestamp").Value = MyObject.MyTimestamp
Else
   cmd.Parameters.Item("@MyTimestamp").Value = Nothing
End If

现在,当我第一次看到这个时,我有点惊讶MyObject.MyTimestamp曾经评估过Nothing,但它已存在多年没有问题。在清理工作期间,添加参数和设置其值的代码被组合在一起,因此上面的代码变成了......

cmd.Parameters.Add("@MyTimestamp", SqlDbType.DateTime).Value = If(MyObject.MyTimestamp <> Nothing, MyObject.MyTimestamp, Nothing)

对我而言,这看起来与代码最初所做的相同,但这不是测试期间发现的内容。在测试时我收到了一个SqlTypeException:

  

SqlDateTime溢出。必须在1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间。

这是因为使用If运算符将MyObject.MyTimestamp评估为不是Nothing,它不是DateTime.MinValue并且它试图将其插入到sql中并且它已经爆炸了。编写原始代码的方式将相同的Timestamp评估为Nothing(不确定如何/为什么)并执行false部分。所以我的问题是有什么区别,我应该关注其他数据类型......?

1 个答案:

答案 0 :(得分:3)

记住(我经常不这样做)Nothing不等同于C#中的null,但更像是Default(T),以下内容不会检查MyObject.MyTimestamp是否已经过设置:

MyObject.MyTimestamp <> Nothing

但是在实际检查它是否是默认的日期时间(DateTime.MinValue),它可能总是如此。

此外,当您使用:

If(MyObject.MyTimestamp <> Nothing, MyObject.MyTimestamp, Nothing)

两种返回类型(MyObject.MyTimestampNothing)必须属于同一类型,因此编译器知道MyObject.Timestamp应该是一个日期时间,它不会将任何内容转换为默认日期时间

但是当你使用它时:

If MyObject.MyTimestamp <> Nothing Then
   cmd.Parameters.Item("@MyTimestamp").Value = MyObject.MyTimestamp
Else
   cmd.Parameters.Item("@MyTimestamp").Value = Nothing
End If

它识别"@MyTimestamp"的参数属于SqlDbType.DateTime类型,因此为此创建默认值。我不知道这是DbNull还是我头顶的实际值,但无论哪种方式都是允许的值,所以不会抛出错误。

另外,您可能希望将参数设置为DbNull.Value而不是Nothing

If MyObject.MyTimestamp <> Nothing Then
   cmd.Parameters.Item("@MyTimestamp").Value = MyObject.MyTimestamp
Else
   cmd.Parameters.Item("@MyTimestamp").Value = DbNull.Value
End If