CA1815: equals および operator equals を値型でオーバーライドします
TypeName |
OverrideEqualsAndOperatorEqualsOnValueTypes |
CheckId |
CA1815 |
分類 |
Microsoft.Performance |
互換性に影響する変更点 |
なし |
原因
パブリック値型で Object.Equals をオーバーライドしていないか、等値演算子 (==) を実装していません。この規則で列挙型はチェックされません。
規則の説明
値型の場合、Equals を継承した実装では、Reflection ライブラリを使用し、すべてのフィールドの内容を比較します。Reflection は計算コストが高いため、場合によってはすべてのフィールドで等値性を比較する必要はありません。ユーザーがインスタンスの比較または並べ替えを行うことや、ハッシュ テーブル キーにインスタンスを使用することが予想される場合には、値型に 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; }
}
}
}
修正方法の例
説明
ValueType.Equals のオーバーライドと等値演算子 (==, !=) の実装によって上記の違反を修正するコード例を次に示します。
コード
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: オーバーロードする演算子 equals で Equals をオーバーライドします
CA2231: ValueType.Equals のオーバーライドで、演算子 equals をオーバーロードします
CA2226: 演算子は対称型オーバーロードを含まなければなりません