CA2218:重写 Equals 时重写 GetHashCode
类型名 |
OverrideGetHashCodeOnOverridingEquals |
CheckId |
CA2218 |
类别 |
Microsoft.Usage |
是否重大更改 |
否 |
原因
某公共类型重写 Object.Equals 但是不重写 Object.GetHashCode。
规则说明
GetHashCode 基于适合哈希算法和诸如哈希表的数据结构的当前实例返回一个值。 两个相等的同类型对象必须返回相同的哈希代码,才能确保以下类型的实例正确运行:
HashTable
Dictionary
SortDictionary
SortList
HybredDictionary
实现 IEqualityComparer 的类型
如何解决冲突
要修复与该规则的冲突,请提供 GetHashCode 的实现。 对于一对相同类型的对象,如果 Equals 的实现为该对对象返回 true,则必须确保该实现返回相同的值。
何时禁止显示警告
不要禁止显示此规则发出的警告。
类示例
说明
下面的示例演示一个与此规则冲突的类(引用类型)。
代码
using System;
namespace Samples
{
// Violates this rule
public class 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 bool Equals(object obj)
{
if (obj == null)
return false;
if (GetType() != obj.GetType())
return false;
Point point = (Point)obj;
if (_X != point.X)
return false;
return _Y == point.Y;
}
}
}
注释
下面的示例通过重写 GetHashCode 修复冲突。
代码
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);
}
}
}
结构示例
说明
下面的示例演示一个与此规则冲突的结构(值类型)。
代码
using System;
namespace Samples
{
// Violates this rule
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 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);
}
}
}
注释
下面的示例通过重写 GetHashCode 修复冲突。
代码
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);
}
}
}
相关规则
CA2231:重写 ValueType.Equals 时应重载相等运算符
请参见
参考
Guidelines for Implementing Equals and the Equality Operator (==)
HashTable