CA1815: Override equals and operator equals on value types

 

For the latest documentation on Visual Studio 2017, see Visual Studio 2017 Documentation.

For the latest documentation on Visual Studio 2017, see CA1815: Override equals and operator equals on value types on docs.microsoft.com.

TypeNameOverrideEqualsAndOperatorEqualsOnValueTypes
CheckIdCA1815
CategoryMicrosoft.Performance
Breaking ChangeNon-breaking

A public value type does not override Object.Equals, or does not implement the equality operator (==). This rule does not check enumerations.

For value types, the inherited implementation of Equals uses the Reflection library, and compares the contents of all fields. Reflection is computationally expensive, and comparing every field for equality might be unnecessary. If you expect users to compare or sort instances, or use them as hash table keys, your value type should implement Equals. If your programming language supports operator overloading, you should also provide an implementation of the equality and inequality operators.

To fix a violation of this rule, provide an implementation of Equals. If you can, implement the equality operator.

It is safe to suppress a warning from this rule if instances of the value type will not be compared to each other.

Description

The following example shows a structure (value type) that violates this rule.

Code

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

Description

The following example fixes the previous violation by overriding M:System.ValueType.Equals and implementing the equality operators (==, !=).

Code

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: Override equals on overloading operator equals

CA2231: Overload operator equals on overriding ValueType.Equals

CA2226: Operators should have symmetrical overloads

Object.Equals

Show: