HaPpY hApPy

10 GetHashCode()의 함정 본문

.NET/Effective C#

10 GetHashCode()의 함정

juniguya 2014. 3. 16. 23:58

1.     Collection Key로 활용될 경우가 아니라면 GetHashCode() 재정의 할 필요 없음

A.     Operator == 재정의했다면 무조건 재 정의 해야함.

2.     만약 정의 해야 한다면 따라야 할 3가지 규칙

A.     (operator == 에서 동일한 결과를 가질경우) 두 객체는 동일한 해시 코드를 생성해야 한다.

B.      객체가 생성된 이후에는 GetHashCode()에 대한 호출이 변경되면 안된다.

C.      해시 함수는 integer의 표현범위 내에서 골고루 잘 분산되어야한다.

3.     GetHashCode()의 역할

A.     System.Object의 객체 생성자에 의해서 만들어지고 1부터 시작하여 매 객체 생성 요청때마다 1씩 증가되는 값을 생성, GetHashCode는 이걸 단순히 return

4.     2번 따라야 할 규칙중 3번에 의해서 성능이 좌우됨

5.     Struct 에서(Value type) 첫번째 멤버변수가 HashKey로 사용됨

A.     첫번째 멤버변수를 가능하면 Immutable 로 하는게 좋음

public struct MyStruct

{

private string msg;

private int id;

private DateTime epoch;

}

만약 위에서 msg가 변할수 있는 (readonly가 아니면) GetHashCode()가 다르게 작동할 수 있음. 만약 readonly 라면 제대로 작동함.

 

B.      Class의 경우 주소가 바뀌지 않으면 동일함

        

      struct TestClass
     {
        public string name;
        public string name2;
      }

 

      TestClass TestClass1 = new TestClass();

TestClass1.name = "test1";
MessageBox.Show(TestClass1.GetHashCode().ToString());
TestClass1.name2 = "test2"; //여기서는 변하지 않음, 두번째 멤버변수이기 때문에
MessageBox.Show(TestClass1.GetHashCode().ToString());
TestClass1.name = "test2";    // 여기서는 변함
MessageBox.Show(TestClass1.GetHashCode().ToString());