CA1815:重写值类型上的 Equals 和相等运算符

类型名

OverrideEqualsAndOperatorEqualsOnValueTypes

CheckId

CA1815

类别

Microsoft.Performance

是否重大更改

非重大更改

原因

某公共值类型未重写 Object.Equals,或者未实现等号运算符 (==)。 该规则不检查枚举。

规则说明

对于值类型,Equals 的继承的实现使用反射库,并比较所有字段的内容。 反射需要消耗大量计算资源,可能没有必要比较每一个字段是否相等。 如果希望用户对实例进行比较或排序,或者希望用户将其作为哈希表键,则值类型必须实现 Equals。 如果编程语言支持运算符重载,则还应提供等号和不等号运算符的实现。

如何解决冲突

要修复与该规则的冲突,请提供 Equals 的实现。 如果可以实现等号运算符,则请实现该运算符。

何时禁止显示警告

如果不对值类型的实例进行互相比较,则可以安全地禁止显示此规则发出的警告。

冲突的示例

ms182276.collapse_all(zh-cn,VS.110).gif说明

下面的示例演示一个与此规则冲突的结构(值类型)。

ms182276.collapse_all(zh-cn,VS.110).gif代码

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; }        
        }    
    }
}

修复方法的示例

ms182276.collapse_all(zh-cn,VS.110).gif说明

下面的示例通过重写 ValueType.Equals 并实现相等运算符(== 和 !=)修复了上面的冲突。

ms182276.collapse_all(zh-cn,VS.110).gif代码

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 方法

CA2231:重写 ValueType.Equals 时应重载相等运算符

CA2226:运算符应有对称重载

请参见

参考

Object.Equals