2011-03-31 2 views
0

해시 코드로 개체를 비교할 수 있기를 원합니다.이진 직렬화 (바이너리) 중에 객체의 해시 코드를 저장할 수 있습니까?

예를 들어, 하나는 객체 자체이고 다른 하나는 직렬화 (바이너리) 된 다음 객체의 복구 된 버전입니다.

직렬화 된 (바이너리) 객체에 해시를 저장하려면 어떻게해야합니까?

+2

어떻게 든 옛날 해시 코드를 저장할 수 있지만 역 직렬화 후에는 쓸모가 없습니다. 새 개체에 맞지 않을 수 있습니다. 특히, 기본 구현에서는 직렬화 된 객체를 이전과 동일하게 간주합니다. 참조 평등을 기반으로하기 때문입니다. – CodesInChaos

답변

3

왜 해시 코드를 직렬화해야합니까? 대신 객체에 GetHashCode()Equals()의 적절한 구현을 제공해야합니다.이 객체를 사용하면 두 객체의 해시 코드가 일치해야하는 두 객체의 값에 따라 두 객체를 비교할 수 있습니다. 따라서 객체를 비 직렬화하면 객체에 GetHashCode()을 사용하여 다른 객체와 비교할 수 있습니다. 두 개의 해시 코드가 일치한다는 사실은 평등을 결정하는 데 충분하지 않으며 여전히 다를 수 있습니다. 평등을 결정하려면 Equals()의 적절한 구현을 호출해야합니다.

개체의 사용자 지정 필드를 비교하기 위해 전체 비교가 너무 비싸면 (즉, 큰 이진 배열) 필드에 MD5 해시를 생성하고 (즉, MD5CryptoServiceProvider.ComputeHash()) 그러면 객체 자체 내에서 다른 객체 속성과 마찬가지로 직렬화됩니다.

+1

"해시 코드 자체는 정의에 따라 개체의 속성/필드 값의 조합으로 계산할 수 있습니다." 참조 동등성이 사용되는 경우가 아니라, 특히 참조 유형에 대한 GetHashCode의 기본 구현은 필드를 기반으로하지 않습니다. – CodesInChaos

+0

고마워요, 고쳤습니다. 그것은 실수였습니다. – BrokenGlass

3

주의하십시오!

.Net 개체의 기본 HashCode는 종종 프로그램의 런타임 인스턴스간에 변경됩니다. 환언

, 프로그램이 디스크에 해시 완전한 객체 A를, 직렬화 경우, 프로그램이 종료 한 후에 다시 시작하고, 탈 직렬화는 디스크로부터 A 개체, (또는 동일한 객체 A를 작성 런타임), 저장된 것보다 다른 해시 코드가 있습니다.

기본 해시 코드는 오브젝트의 가비지 콜렉터 정보에서 비롯된 것입니다. 새로운 프로그램 인스턴스에서 GC는 다른 정보와 다른 해시 코드를 갖습니다.

독자가 GetHashCode이라고 쓰면 프로세스간에 일관된 해시 코드를 만들 수 있습니다. 그러나 여기에 당신이 알고 있어야 할 함정이 있습니다.

1

어떤 개체가 어떤 원본에서 직렬화되고 역 직렬화되었는지 알 수있는 정보가 있습니까? 그렇다면 GetHashCode()를 재정 의하여 해당 정보를 기반으로 해시 코드를 계산할 수 있습니다.

그렇지 않은 경우 새로 생성 된 각 개체에 UUID를 할당하여 종합적으로 생성 할 수 있습니다. 이 값을 다른 데이터와 함께 직렬화하면 재구성 된 객체가 동일한 UUID를 갖게됩니다. 그런 다음 GetHashCode()를 재정 의하여 해당 UUID의 해시 코드를 반환 할 수 있습니다. (당신이 찾고있는 것이 일종의 참조 평등의 수정 버전입니다.)

관련 문제