2013-03-14 6 views
1

고유성이 해당 개체의 모든 속성을 조합하여 결정되는 개체를 캐시하려고합니다. 내가 가진 객체가이 같은 것입니다 :여러 속성을 사용하여 개체를 캐시하는 방법

public double A { get; set; } 
    public double B { get; set; } 
    public short C { get; set; } 
    public bool D { get; set; } 
    public double E { get; set; } 
    public double F { get; set; } 
    public double G { get; set; } 
    public double H { get; set; } 
    public double J { get; set; } 
    public double K { get; set; } 
    public double[] L { get; set; } 
    public double[] M { get; set; } 

나는 나는 많은 충돌이있을 것이라는 점을 걱정, GetHashCode을 덮어 그러나 return A^B^C etc... 뭔가를 할 수 있습니다.

이와 같이 개체를 캐시하는 가장 좋은 방법은 무엇입니까?

+0

가장 좋은 방법은 GetHashCode를 덮어 쓰고 A^B^C ...와 같은 작업을하는 것입니다. 테스트를하고 충돌이있는 경우 필요에 맞게 수식을 조정하는 방법을 찾아야합니다. 바퀴를 다시 만들지 마라. –

+0

속성에 공용 설정자가 있기 때문에 '.GetHashCode'를 연속적으로 호출 할 때 데이터가 변경되지 않는다고 보장 할 수 없다. 상태가 변경되면 사전과 같은 해시 코드에 의존하는 모든 동작이 완전히 손상됩니다. –

+0

당신은 걱정할 권리가 있습니다. 속성이 "클러스터"하는 경향이 있다면 xoring이 많은 비트를 지울 수 있습니다. –

답변

4

GetHashCode을 사용할 수 있습니다 : 다른 속성이 동일한 값을 가질 때 다른 해시 코드를 생성

public override int GetHashCode() 
{ 
    int hash = 23; 
    unchecked 
    { 
     hash *= 17 + A.GetHashCode(); 
     hash *= 17 + B.GetHashCode(); 
     hash *= 17 + C.GetHashCode(); 
     // the same applies with the rest of your properties ... 
     // collections must be treated differently: 
     if(L != null) 
     { 
      hash *= 17 + L.Length; 
      foreach(var d in L) 
       hash *= 17 + d.GetHashCode(); 
     } 
     if (M != null) 
     { 
      hash *= 17 + M.Length; 
      foreach (var d in M) 
       hash *= 17 + d.GetHashCode(); 
     }   
    } 
    return hash; 
} 

. 프라임 승수를 생략하면 A==A 또는 A==B 일 경우 차이가 발생하지 않습니다. 소수는 거짓 충돌 가능성을 줄이기 위해 사용됩니다.

또한 배열과 해당 값 + 주문을 고려합니다.

이것은이 주제에 "읽기해야한다"입니다 : E. Lippert, Guidelines and rules for GetHashCode

+0

17과 23의 목적은 무엇입니까? – TJF

+0

@ ThomasJ.Frey :이 질문을 목표로하는이 답변을보십시오 : http://stackoverflow.com/a/3613382/284240 간단히 말해서 소수는 서로 다른 입력 매개 변수에 대해 동일한 해시 값을 얻는 것을 피하는 데 도움이됩니다. –

+1

또한 서로 다른 속성이 동일한 값을 가질 때 서로 다른 해시 코드를 생성합니다. 만약 23 배수를 생략하면'A' =='A' 또는'A' =='B'이면 차이가 없습니다. –

0

간단한 (입력해도 아마 최적이 아닌) 솔루션이 될 수 :

  1. 는 클래스의 캐릭터 라인 표현을 생성합니다. 에스컬레이터 속성 만있는 경우 string.Format("{0}-{1}-{2}", A, B, C)과 같은 작업을 수행 할 수 있습니다. 배열이 있으므로 StringBuilder을 사용하고 루프 내에서 문자열을 구성하는 것이 좋습니다.

  2. 생성 된 문자열에 GetHashCode을 호출하십시오.

+0

해시 코드를 올바르게 계산하는 것이 실제로는 훨씬 간단하다고 생각하지 않습니다. 특히 헬퍼 메소드를 생성했다면 말이죠. – svick

관련 문제