在使用SqlDataReader(即“ reader”)时,尝试检查值是否为DBNull时遇到了以下错误。
未为类型'DBNull'和类型'DBNull'定义运算符'='。
使用以下代码时:
If reader("MyColumn") = DBNull.Value Then
'...
End If
我通过使用对IsDBNull()的调用来解决该错误,我怀疑这是由于'Is'和'='之间的差异所致。
但是,我的问题是:为什么不能使用'='运算符进行比较?
答案 0 :(得分:1)
在SQL中,null = null的结果为false。这可能就是为什么没有为此类型定义相等运算符的原因。
您无法确定未知的事物是否等于其他未知的事物,从而使等式运算符无用。
使用DBNull.Value.Equals()
确定是否为空。
答案 1 :(得分:1)
并非所有类型都可与=
运算符一起使用。当一个类型定义了应该如何使用各种运算符的逻辑时,它称为“运算符重载”(由于它与方法重载无关,并且有很大的不同,因此它有点令人困惑)。基本Object
类型不会重载=
运算符,因此,当您创建自定义类时,它不会从=
继承Object
运算符重载。因此,只有那些特别使操作员超负荷的类型才能实际使用它。例如,以下代码将无法编译:
Module Module1
Public Sub Main()
Dim dan As New Person() With {.Id = 1, .Name = "Daniel Thorne"}
Dim steve As New Person() With {.Id = 2, .Name = "Steven Doggart"}
If dan = steve Then
Console.WriteLine("They're the same")
End If
End Sub
Public Class Person
Public Property Id As Integer
Public Property Name As String
End Class
End Module
编译器给出以下构建错误:
未为类型'Module1.Person'和'Module1.Person'定义BC30452运算符'='。
但是,它会按预期构建并运行:
Public Sub Main()
Dim dan As New Person() With {.Id = 1, .Name = "Daniel Thorne"}
Dim steve As New Person() With {.Id = 2, .Name = "Steven Doggart"}
If dan = steve Then
Console.WriteLine("They're the same")
End If
End Sub
Public Class Person
Public Property Id As Integer
Public Property Name As String
Public Shared Operator =(x As Person, y As Person) As Boolean
Return AreEqual(x, y)
End Operator
Public Shared Operator <>(x As Person, y As Person) As Boolean
Return Not AreEqual(x, y)
End Operator
Private Shared Function AreEqual(x As Person, y As Person) As Boolean
If (x Is Nothing) And (y Is Nothing) Then
Return True
ElseIf (x IsNot Nothing) And (y IsNot Nothing) Then
Return x.Id = y.Id
Else
Return False
End If
End Function
End Class
所以,您在DBNull
上收到此错误的原因是,出于任何原因,编写该类的开发人员都选择不为其重载=
运算符。至于为什么,你猜我和我一样好。
请注意,您也可以重载许多其他运算符,这有时会很有用。但是,要小心。如果您对运算符重载的使用过于宽容,您可能会后悔。