CA1815:重写值类型上的 Equals 和相等运算符
类型名 |
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; }
}
}
}
修复方法的示例
说明
下面的示例通过重写 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);
}
}
}
相关规则
CA2231:重写 ValueType.Equals 时应重载相等运算符