While using an SqlDataReader (namely 'reader'), I encountered the following error when trying to check if a value is DBNull.
Operator '=' is not defined for type 'DBNull' and type 'DBNull'.
When using the following code:
If reader("MyColumn") = DBNull.Value Then
'...
End If
I have circumnavigated the error by using a call to IsDBNull() and I suspect it is due to a difference between 'Is' and '='.
However, the question I have is: why is it not possible to make the comparison using the '=' operator?
Not all types work with the =
operator. When a type defines the logic for how various operators are supposed to work with it, it's called "operator overloading" (which is admittedly a little confusing because it is unrelated, and quite different, from method overloading). The base Object
type doesn't overload the =
operator, so, when you create a custom class, it won't inherit the =
operator overload from Object
. So, only types which specifically overload the operator can actually work with it. For instance, the following code will not compile:
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
The compiler gives the following build error:
BC30452 Operator '=' is not defined for types 'Module1.Person' and 'Module1.Person'.
However, this will build and work as expected:
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
So, the reason why you get that error on DBNull
is because, for whatever reason, the developers who wrote that class chose not to overload the =
operator for it. As far as why that is, you're guess is as good as mine.
Side note, you can overload a lot of other operators too, which can sometimes be useful. However, be careful. If you are too liberal in your use of operator overloading, you'll probably come to regret it.