[More Effective C#] 1장 - Item 10: GetHashCode()의 위험성을 이해하라

SY·2023년 10월 3일

More Effective C#

목록 보기
10/46
post-thumbnail

빌 와그너, ⌜More Effective C# 2판⌟, 김완섭 옮김, 한빛미디어, 2019
이 포스팅은 ⌜More Effective C# 2판⌟의 내용을 기반으로 작성되었습니다.


아이템 10: GetHashCode()의 위험성을 이해하라



GetHashCode()는 해시 기반 컬렉션에서 키의 해시값을 정의할 때 한곳에서만 사용된다.

  • HashSet<T>과 Dictinary<K,V>과 같은 컨테이너들이다.



베이스 클래스의 GetHashCode() 구현부는 문제가 있다.
참조 타입에서는 겨우 동작하지만 매우 비효율적이며, 값 타입에서는 베이스 클래스의 버전이 정확하지 않을 때가 있다.

컬렉션의 키로 사용될 일이 없는 타입을 정의한다면 문제될 것이 없다.
참조 타입에서는 비효율적이지만 올바른 해시코드를 얻을 수 있기는 하다.
값 타입의 경우에는 변경 불가능하도록 작성해야 한다.



.NET에서는 모든 객체가 해시 코드를 가지며, 그 값은 System.Object.GetHashCode()에 의해서 결정되는데, 이 메서드를 오버로드 할때는 세가지 규칙을 따라야 한다.
간단하게 정의하면 다음과 같다.

  1. 동일한 객체는 동일한 해시 코드를 생성해야 한다.
  2. 인스턴스 생성 후 불변이여야 한다.
  3. 자주 사용되는 입력값들에 대해 균일하게 분포된 정수값을 생성해야 한다.

이 세가지 규칙을 모두 만족하는 것은 변경 불가능한 타입밖에 없다.
그 외의 타입이라면 기본 동작에 의존해야 한다.

GetHashCode() 함수의 구현부는 문제가 있다.
개선하기 위해 오버로드 한다면, 세 가지 규칙을 따라야 하는데 모두 만족하는 것은 변경 불가능한 타입밖에 없다.
그 외의 타입이라면 비효율 적이지만 기본 동작에 의지해야 한다.

profile
게임 개발 공부

0개의 댓글