Section 3.2: 동등 (equality) 연산자 재정의하기

동등 연산자 하나를 재정의 하는 것만으로는 충분치 않은 경우가 있다. 여러가지 다양한 상황에 따라, 아래에 소개된 내용들이 사용될 수 있다:

  1. object.Equalsobject.GetHashCode
  2. IEquatable<T>.Equals (선택 사항, 불필요한 boxing 을 피할 수 있게 해준다)
  3. == 연산자와 != 연산자 (선택 사항, 연산자를 사용할 수 있게 해준다)

Equals 를 재정의 하는 경우, GetHashCode 역시 재정의가 되어야 한다. Equals 를 실제로 구현하는 경우, 특수한 경우가 다수 존재한다: 다른 타입의 객체들 (object) 과 비교를 한다거나, 자기 자신과의 비교를 수행하는 경우 등이 이에 해당한다.

재정의가 되지 않은 경우, Equals 메소드와 == 연산자는 클래스와 구조체 (struct) 에 대해 각각 다르게 동작한다. 클래스들에 대해서는 단순히 reference 만을 비교하게 되며, 구조체들에 대해서는 속성 (property) 들에 대한 값을 (성능 저하를 유발할 수도 있는) reflection 을 이용해 비교하게 된다. == 는 재정의 되지 않는 한 구조체 비교를 위해서는 사용될 수 없다.

역주: 상황에 따라 byte 비교를 수행하는 경우와 reflection 을 이용한 field 비교를 수행하는 경우가 존재합니다. 보다 자세한 사항은 MSDN 을 참고하세요.

일반적으로 동등 연산자는 다음 규칙들을 준수해야 한다:

  • 예외 (exception) 를 throw 해서는 안된다.

  • 재귀성 (reflexivity) : A 는 언제나 A 자신과 동등해야 한다 (일부 시스템에서는 NULL 값에 이 규칙이 적용되지 않을 수 있다).

  • 전이성 (transitvity) : 만약 A 가 B 와 동등하며, B 가 C 와 동등하다면, A 는 C 와 동등하여야 한다.

  • 만약 A 가 B 와 동등하다면, A 와 B 는 동등한 hash code 값을 가진다.

  • 상속 트리 독립성 (Inheritance tree independence) : 만약 BCClass1 을 상속한 Class2 의 instance 라고 하면, Class1.Equals(A,B) 는 언제나 Class2.Equals(A,B) 와 동일한 값을 반환하여야 한다.

class Student: IEquatable < Student > { public string Name { get; set; } = ""; public bool Equals(Student other) { if (ReferenceEquals(other, null)) return false; if (ReferenceEquals(other, this)) return true; return string.Equals(Name, other.Name); } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; return Equals(obj as Student); } public override int GetHashCode() { return Name ? .GetHashCode() ?? 0; } public static bool operator == (Student left, Student right) { return Equals(left, right); } public static bool operator != (Student left, Student right) { return ! Equals(left, right); } }
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

+ Recent posts