CA1815: следует переопределять равенства и равенства операторов в типах значений
TypeName |
OverrideEqualsAndOperatorEqualsOnValueTypes |
CheckId |
CA1815 |
Категория |
Microsoft.Performance |
Критическое изменение |
Не критическое |
Причина
Открытый тип значения не переопределяет Object.Equals или не реализует оператор равенства (==). Это правило не используется для проверки перечислений.
Описание правила
Для типов значений унаследованная реализация Equals использует библиотеку отражения и сравнивает содержимое всех полей. Отражение является процессом, требующим с точки зрения вычислений больших затрат, и сравнение каждого поля на равенство может быть лишним. Если предполагается, что пользователи будут сравнивать или сортировать экземпляры или использовать их в качестве ключей хэш-таблиц, тип значения должен реализовывать Equals. Если используемый язык программирования поддерживает перегрузку, следует предоставить реализацию операторов равенства и неравенства.
Устранение нарушений
Чтобы устранить нарушение данного правила, предоставьте реализацию Equals. Если возможно, реализуйте оператор равенства.
Отключение предупреждений
Если экземпляры типа значения не будут сравниваться друг с другом, для данного правила можно отключить вывод предупреждений.
Пример нарушения
Описание
В следующем примере показана структура (тип значения), нарушающая это правило.
Код
using System;
namespace Samples
{
// Violates this rule
public struct Point
{
private readonly int _X;
private readonly int _Y;
public Point(int x, int y)
{
_X = x;
_Y = y;
}
public int X
{
get { return _X; }
}
public int Y
{
get { return _Y; }
}
}
}
Пример исправления нарушения
Описание
В следующем примере показано исправление предыдущего нарушения с помощью переопределения ValueTypeEquals() и реализации операторов равенства (==, !=).
Код
using System;
namespace Samples
{
public struct Point : IEquatable<Point>
{
private readonly int _X;
private readonly int _Y;
public Point(int x, int y)
{
_X = x;
_Y = y;
}
public int X
{
get { return _X; }
}
public int Y
{
get { return _Y; }
}
public override int GetHashCode()
{
return _X ^ _Y;
}
public override bool Equals(object obj)
{
if (!(obj is Point))
return false;
return Equals((Point)obj);
}
public bool Equals(Point other)
{
if (_X != other._X)
return false;
return _Y == other._Y;
}
public static bool operator ==(Point point1, Point point2)
{
return point1.Equals(point2);
}
public static bool operator !=(Point point1, Point point2)
{
return !point1.Equals(point2);
}
}
}
Связанные правила
CA2224: переопределяйте равенство при перегрузке оператора равенства
CA2231: перегружать равенство операторов следует при перегрузке ValueType.Equals
CA2226: перегрузки операторов должны быть симметричны