CA2231: перегружать равенство операторов следует при перегрузке ValueType.Equals
Свойство | Значение |
---|---|
Идентификатор правила | CA2231 |
Заголовок | Перегрузите оператор равенства на переопределяющем типе ValueType.Equals |
Категория | Использование |
Исправление является критическим или не критическим | Не критическое |
Включен по умолчанию в .NET 8 | Как предложение |
Причина
Тип значения переопределяет System.Object.Equals, но не реализует оператор равенства.
По умолчанию это правило проверяет только видимые извне типы, но это поведение можно настроить.
Описание правила
В большинстве языков программирования стандартная реализация оператора равенства (==) для типов значений отсутствует. Если ваш язык программирования поддерживает перегрузки операторов, следует рассмотреть возможность реализации оператора равенства. Его поведение должно быть идентично поведению Equals.
Нельзя использовать оператор равенства по умолчанию в перегруженной реализации оператора равенства. Это приведет к переполнению стека. Чтобы реализовать оператор равенства, используйте метод Object.Equals в реализации. Например:
If (Object.ReferenceEquals(left, Nothing)) Then
Return Object.ReferenceEquals(right, Nothing)
Else
Return left.Equals(right)
End If
if (Object.ReferenceEquals(left, null))
return Object.ReferenceEquals(right, null);
return left.Equals(right);
Устранение нарушений
Чтобы устранить нарушение этого правила, реализуйте оператор равенства.
Когда лучше отключить предупреждения
Можно спокойно отключить предупреждение из этого правила. Однако рекомендуется по возможности указать оператор равенства.
Отключение предупреждений
Если вы просто хотите отключить одно нарушение, добавьте директивы препроцессора в исходный файл, чтобы отключить и повторно включить правило.
#pragma warning disable CA2231
// The code that's violating the rule is on this line.
#pragma warning restore CA2231
Чтобы отключить правило для файла, папки или проекта, задайте его серьезность none
в файле конфигурации.
[*.{cs,vb}]
dotnet_diagnostic.CA2231.severity = none
Дополнительные сведения см. в разделе Практическое руководство. Скрытие предупреждений анализа кода.
Настройка кода для анализа
Используйте следующий параметр, чтобы выбрать части базы кода для применения этого правила.
Этот параметр можно настроить только для этого правила, для всех правил, к которым он применяется, или для всех правил в этой категории (использование), к которым она применяется. Дополнительные сведения см. в статье Параметры конфигурации правила качества кода.
Включение определенных контактных зон API
Вы можете настроить, для каких частей базы кода следует выполнять это правило в зависимости от их доступности. Например, чтобы указать, что правило должно выполняться только для закрытой контактной зоны API, добавьте следующую пару "ключ-значение" в файл EDITORCONFIG в своем проекте:
dotnet_code_quality.CAXXXX.api_surface = private, internal
Пример
В следующем примере определяется тип, нарушающий это правило:
public struct PointWithoutHash
{
private int x, y;
public PointWithoutHash(int x, int y)
{
this.x = x;
this.y = y;
}
public override string ToString()
{
return String.Format("({0},{1})", x, y);
}
public int X { get { return x; } }
public int Y { get { return x; } }
// Violates rule: OverrideGetHashCodeOnOverridingEquals.
// Violates rule: OverrideOperatorEqualsOnOverridingValueTypeEquals.
public override bool Equals(object? obj)
{
if (obj?.GetType() != typeof(PointWithoutHash))
return false;
PointWithoutHash p = (PointWithoutHash)obj;
return ((this.x == p.x) && (this.y == p.y));
}
}
Связанные правила
- CA1046: не перегружайте оператор равенства для ссылочных типов
- CA2225: для перезагрузок оператора существуют дополнения с именами
- CA2226: перегрузки операторов должны быть симметричны