CA2218: переопределяйте GetHashCode при переопределении Equals
Свойство | Значение |
---|---|
Идентификатор правила | CA2218 |
Заголовок | Переопределяйте GetHashCode при переопределении Equals |
Категория | Использование |
Исправление является критическим или не критическим | Не критическое |
Включен по умолчанию в .NET 9 | Как предложение |
Причина
Открытый тип переопределяет System.Object.Equals, но не System.Object.GetHashCode.
Описание правила
GetHashCode возвращает значение на основе текущего экземпляра, используемое для алгоритмов хэширования и структур данных, таких как хэш-таблица. Два объекта, которые относятся к одному типу и равны, должны возвращать один и тот же хэш-код, чтобы убедиться, что экземпляры следующих типов работают правильно:
- System.Collections.Hashtable
- System.Collections.SortedList
- System.Collections.Generic.Dictionary<TKey,TValue>
- System.Collections.Generic.SortedDictionary<TKey,TValue>
- System.Collections.Generic.SortedList<TKey,TValue>
- System.Collections.Specialized.HybridDictionary
- System.Collections.Specialized.ListDictionary
- System.Collections.Specialized.OrderedDictionary
- Типы, которые реализуют System.Collections.Generic.IEqualityComparer<T>
Примечание.
Это правило применяется только к коду 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
Связанные правила
- CA1046: не перегружайте оператор равенства для ссылочных типов
- CA2224: переопределяйте равенство при перегрузке оператора равенства
- CA2225: для перезагрузок оператора существуют дополнения с именами
- CA2226: перегрузки операторов должны быть симметричны
- CA2231: перегружать равенство операторов следует при перегрузке ValueType.Equals