다음을 통해 공유


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

TypeName

OverrideGetHashCodeOnOverridingEquals

CheckId

CA2218

범주

Microsoft.Usage

변경 수준

주요 변경 아님

원인

public 형식이 Object.Equals를 재정의하지만 Object.GetHashCode는 재정의하지 않습니다.

규칙 설명

GetHashCode는 현재 인스턴스를 기반으로 해싱 알고리즘 및 해시 테이블과 같은 데이터 구조체에 적합한 값을 반환합니다. 같은 형식의 동일한 두 개체가 같은 해시 코드를 반환해야 다음 형식의 인스턴스가 올바르게 작동한다고 할 수 있습니다.

위반 문제를 해결하는 방법

이 규칙 위반 문제를 해결하려면 GetHashCode의 구현을 제공합니다. 형식이 같은 두 개체의 경우 이들 개체에 대한 Equals의 구현이 true를 반환하는 경우 GetHashCode 구현이 같은 값을 반환하는지 확인해야 합니다.

경고를 표시하지 않는 경우

이 규칙에서는 경고를 표시해야 합니다.

클래스 예제

설명

다음 예제에서는 이 규칙을 위반하는 클래스(참조 형식)를 보여 줍니다.

코드

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를 재정의할 때 같음 연산자를 오버로드하십시오.

참고 항목

참조

Equals 및 같음 연산자(==) 구현 지침

Object.Equals

Object.GetHashCode

HashTable