Оператор '=' не определен для типа 'DBNull' и типа 'DBNull' - PullRequest
0 голосов
/ 01 марта 2019

При использовании SqlDataReader (а именно 'reader') я столкнулся со следующей ошибкой при попытке проверить, является ли значение DBNull.

Оператор '=' не определен для типа 'DBNull'и введите 'DBNull'.

При использовании следующего кода:

If reader("MyColumn") = DBNull.Value Then
  '...
End If

Я обошел ошибку, используя вызов IsDBNull (), и я подозреваю, что это связано сразница между 'Is' и '='.

Однако у меня есть вопрос: почему невозможно выполнить сравнение с помощью оператора '='?

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Не все типы работают с оператором =.Когда тип определяет логику того, как различные операторы должны работать с ним, это называется «перегрузкой операторов» (что, по общему признанию, немного сбивает с толку, поскольку не связано и сильно отличается от перегрузки методов).Базовый тип 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

Компилятор выдает следующую ошибку сборки:

BC30452 Оператор '=' не определен для типов '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, заключается впотому что по какой-то причине разработчики, написавшие этот класс, решили не перегружать оператор = для него.Что касается того, почему это так, вы, наверное, так же хороши, как и я.

Примечание: вы также можете перегружать множество других операторов, что иногда может быть полезно.Однако будьте осторожны.Если вы слишком либеральны в использовании перегрузки операторов, вы, вероятно, пожалеете об этом.

0 голосов
/ 01 марта 2019

В SQL null = null оценивается как false.Вероятно, это причина того, что оператор равенства не определен для этого типа.

Вы не можете определить, равно ли что-то неизвестное чему-либо другому, что делает неизвестным оператор бесполезности.

Использование DBNull.Value.Equals(), чтобы определить, является ли оно нулевым.

...