CA2218: Equals를 재정의할 때 GetHashCode를 재정의하십시오.

항목
RuleId CA2218
범주 Microsoft.Usage
주요 변경 내용 주요 변경 아님

원인

퍼블릭 형식은 System.Object.Equals를 재정의하지만 System.Object.GetHashCode를 재정의하지 않습니다.

규칙 설명

GetHashCode는 현재 인스턴스를 기반으로 해싱 알고리즘 및 해시 테이블과 같은 데이터 구조체에 적합한 값을 반환합니다. 동일한 형식이고 동일한 두 개체가 동일한 해시 코드를 반환하여 다음 형식의 인스턴스가 제대로 작동하는지 확인해야 합니다.

위반 문제를 해결하는 방법

이 규칙의 위반 문제를 해결하려면 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);        
        }    
    }
}

CA1046: 참조 형식에 같음 연산자를 오버로드하지 마십시오.

CA2225: 연산자 오버로드에는 명명된 대체 항목이 있습니다.

CA2226: 연산자에는 대칭 오버로드가 있어야 합니다.

CA2224: 같음 연산자를 오버로드할 때 Equals를 재정의하십시오.

CA2231: ValueType.Equals를 재정의할 때 같음 연산자를 오버로드하십시오.

참고 항목