Поделиться через


CA2218: переопределяйте GetHashCode при переопределении Equals

Свойство Значение
Идентификатор правила CA2218
Заголовок Переопределяйте GetHashCode при переопределении Equals
Категория Использование
Исправление является критическим или не критическим Не критическое
Включен по умолчанию в .NET 9 Как предложение

Причина

Открытый тип переопределяет System.Object.Equals, но не System.Object.GetHashCode.

Описание правила

GetHashCode возвращает значение на основе текущего экземпляра, используемое для алгоритмов хэширования и структур данных, таких как хэш-таблица. Два объекта, которые относятся к одному типу и равны, должны возвращать один и тот же хэш-код, чтобы убедиться, что экземпляры следующих типов работают правильно:

Примечание.

Это правило применяется только к коду Visual Basic. Компилятор C# создает отдельное предупреждение, CS0659.

Устранение нарушений

Чтобы устранить нарушение этого правила, предоставьте реализацию GetHashCode. Для пары объектов одного типа убедитесь, что реализация возвращает одно и то же значение, если ваша реализация Equals возвращает true для пары.

Когда лучше отключить предупреждения

Для этого правила отключать вывод предупреждений не следует.

Пример класса

В следующем примере показан класс (ссылочный тип), нарушающий правило.

' This class violates the rule.
Public Class Point

    Public Property X As Integer
    Public Property Y As Integer

    Public Sub New(x As Integer, y As Integer)
        Me.X = x
        Me.Y = y
    End Sub

    Public Overrides Function Equals(obj As Object) As Boolean

        If obj = Nothing Then
            Return False
        End If

        If [GetType]() <> obj.GetType() Then
            Return False
        End If

        Dim pt As Point = CType(obj, Point)

        Return X = pt.X AndAlso Y = pt.Y

    End Function

End Class

В следующем примере нарушение устраняется путем переопределения GetHashCode().

' This class satisfies the rule.
Public Class Point

    Public Property X As Integer
    Public Property Y As Integer

    Public Sub New(x As Integer, y As Integer)
        Me.X = x
        Me.Y = y
    End Sub

    Public Overrides Function GetHashCode() As Integer
        Return X Or Y
    End Function

    Public Overrides Function Equals(obj As Object) As Boolean

        If obj = Nothing Then
            Return False
        End If

        If [GetType]() <> obj.GetType() Then
            Return False
        End If

        Dim pt As Point = CType(obj, Point)

        Return Equals(pt)

    End Function

    Public Overloads Function Equals(pt As Point) As Boolean
        Return X = pt.X AndAlso Y = pt.Y
    End Function

    Public Shared Operator =(pt1 As Point, pt2 As Point) As Boolean
        Return pt1.Equals(pt2)
    End Operator

    Public Shared Operator <>(pt1 As Point, pt2 As Point) As Boolean
        Return Not pt1.Equals(pt2)
    End Operator

End Class

См. также