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를 재정의할 때 같음 연산자를 오버로드하십시오.
참고 항목
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기