运算符“=”没有为类型 'DBNull' 和类型 'DBNull' 定义
Operator '=' is not defined for type 'DBNull' and type 'DBNull'
在使用 SqlDataReader(即 'reader')时,我在尝试检查值是否为 DBNull 时遇到以下错误。
Operator '=' is not defined for type 'DBNull' and type 'DBNull'.
使用以下代码时:
If reader("MyColumn") = DBNull.Value Then
'...
End If
我通过调用 IsDBNull() 绕过错误,我怀疑这是由于 'Is' 和 '=' 之间的差异造成的。
但是,我的问题是:为什么不能使用“=”运算符进行比较?
在 SQL 中,null = null 的计算结果为 false。这可能就是为什么没有为这种类型定义相等运算符的原因。
您无法确定未知事物是否等于其他未知事物,这使得相等运算符无用。
使用DBNull.Value.Equals()
判断是否为空
并非所有类型都适用于 =
运算符。当一个类型定义了各种运算符应该如何使用它的逻辑时,它被称为 "operator overloading" (这确实有点令人困惑,因为它与方法重载无关,而且完全不同)。基本 Object
类型不会重载 =
运算符,因此,当您创建自定义 class 时,它不会从 [=13] 继承 =
运算符重载=].因此,只有专门重载运算符的类型才能真正使用它。例如,以下代码将无法编译:
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
编译器给出以下构建错误:
BC30452 Operator '=' is not defined for types 'Module1.Person' and 'Module1.Person'.
但是,这将按预期构建和工作:
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
上出现该错误的原因是,无论出于何种原因,编写 class 的开发人员选择不为其重载 =
运算符.至于为什么会这样,你猜和我的一样好。
旁注,您也可以重载许多其他运算符,这有时很有用。但是,请小心。如果您对运算符重载的使用过于自由,您可能会后悔。
SqlDataReader class 有一个方法:SqlDataReader.IsDBNull(Int32) Method.
Dim colNum = reader.GetOrdinal("MyColumn")
If sqlReader.IsDBNull(colNum) Then
' Do something
End If
在使用 SqlDataReader(即 'reader')时,我在尝试检查值是否为 DBNull 时遇到以下错误。
Operator '=' is not defined for type 'DBNull' and type 'DBNull'.
使用以下代码时:
If reader("MyColumn") = DBNull.Value Then
'...
End If
我通过调用 IsDBNull() 绕过错误,我怀疑这是由于 'Is' 和 '=' 之间的差异造成的。
但是,我的问题是:为什么不能使用“=”运算符进行比较?
在 SQL 中,null = null 的计算结果为 false。这可能就是为什么没有为这种类型定义相等运算符的原因。
您无法确定未知事物是否等于其他未知事物,这使得相等运算符无用。
使用DBNull.Value.Equals()
判断是否为空
并非所有类型都适用于 =
运算符。当一个类型定义了各种运算符应该如何使用它的逻辑时,它被称为 "operator overloading" (这确实有点令人困惑,因为它与方法重载无关,而且完全不同)。基本 Object
类型不会重载 =
运算符,因此,当您创建自定义 class 时,它不会从 [=13] 继承 =
运算符重载=].因此,只有专门重载运算符的类型才能真正使用它。例如,以下代码将无法编译:
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
编译器给出以下构建错误:
BC30452 Operator '=' is not defined for types 'Module1.Person' and 'Module1.Person'.
但是,这将按预期构建和工作:
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
上出现该错误的原因是,无论出于何种原因,编写 class 的开发人员选择不为其重载 =
运算符.至于为什么会这样,你猜和我的一样好。
旁注,您也可以重载许多其他运算符,这有时很有用。但是,请小心。如果您对运算符重载的使用过于自由,您可能会后悔。
SqlDataReader class 有一个方法:SqlDataReader.IsDBNull(Int32) Method.
Dim colNum = reader.GetOrdinal("MyColumn")
If sqlReader.IsDBNull(colNum) Then
' Do something
End If