2010-01-18 6 views
2

C#의 클래스 B에서 상속받은 클래스 A가 있다고 가정 해 보겠습니다. 클래스 B에는 Checksum이라는 속성이 있습니다.이 속성은 런타임에 호출 될 때 클래스 A의 인스턴스에있는 모든 속성의 체크섬을 계산합니다 (사용되는 특정 체크섬 알고리즘은 BCL에서 중요하지 않음).메모리의 체크섬 객체

중요하게도 체크섬 알고리즘은 체크섬 속성을 무시해야하며 그렇지 않으면 체크섬 값이 변경 될 때 나중에 확인 될 때 ​​실패합니다.

1), 반사를 사용하여 객체의 이상 모든 공용 속성을 반복 문자열 및 체크섬이에 연결할 :

그래서, 지금까지의 내가 그것을 볼 수있는 두 가지 옵션이 있습니다.

2) 객체가 단순히 인접한 주소의 묶음 인 것처럼 가정하고 바이트 배열 및 체크섬으로 처리합니다.

1 - 느린 소리 2 - 소리가 들리지 않습니다. 체크섬 자체를 나타내는 문자열을 무시하는 방법이나 다른 개체에 대한 참조를 처리하는 방법이 확실하지 않습니다.

누구나 1보다 나은 아이디어를 가지고 있습니까?이 두 가지 솔루션 중 더 나은 것으로 들리십니까?

답변

5

체크섬 속성을 NonSerialized으로 꾸며서 클래스 인스턴스를 바이트 배열로 직렬화 한 다음 체크섬을 계산할 수 있습니다. 이 방법은 속성이 직렬화되는 동안 무시됩니다.

+0

위의 (1)을 약간 더 우아하게 구현 한 것처럼 들리지만 essentailly 동일합니다. 직렬화가 내부적으로 반사를 사용하고 상대적으로 느리다는 것을 이해합니다. 다른 "소설"솔루션이 제안되지 않는다면, 나는 이것을 이것을 할 수있는 방법이라고 생각할 것입니다. –

+1

@Colin 빨리 만들 수 있습니다. http://codebetter.com/blogs/gregyoung/archive/2008/08/24/fast-serialization.aspx – Giorgi

+0

링크를 올바르게 이해하면이 "고속 시리얼 라이저"를 사용하면 각 유형에 대해 수동 직렬화 메소드를 구현하십시오. OP가 체크섬 만 원할 경우 각 유형에 대한 사용자 정의 체크섬 메소드를 작성하는 것이 더 간단하지 않습니까? (좋은 링크!) – Niki

1

옵션 3은 모든 속성의 체크섬을 계산하는 온 - 더 - 플라이 (on-the-fly) 방법을 만드는 것입니다 (예 : reflection.emit을 사용합니다. 첫 번째 호출에는 비효율적이지만 생성 된 메서드는 캐시 될 수 있습니다. 체크섬이 필요한 타입을 알고있는 경우, 컴파일 타임에 코드 생성을 사용하여 체크섬 메소드를 생성 할 수 있습니다.

2

왜 재산이어야합니까? 메서드라면 GetChecksum()에 특별한 논리가 없어도 체크섬 계산에 포함되지 않습니다. 자, 여러분이 만든 것은 기존의 GetHashCode() 메서드가 사용하는 것과 완전히 똑같습니다. 대신이 구현을 제공하십시오.

일반적으로 빠른 웹 검색에서 일반 (느리지 만) 메커니즘을 제공하기 위해 리플렉션을 사용하는 접근법이 표시되지만 각 클래스에 대해 GetHashCode()를 명시 적으로 코딩합니다. 일반적으로 해시 코드에 포함시키려는 각 필드를 인수로 취하여이를 정수로 변환하고 필드에 다른 값을 가진 다른 객체가 정수 범위에 걸쳐 잘 분산되어있는 다른 해시 코드를 제공하도록 고정 숫자로 곱합니다.

A는 INT는
public override int GetHashCode() 
{ 
    unchecked 
    { 
     int result = a; 
     result = (result * 397)^(b != null ? b.GetHashCode() : 0); 
     result = (result * 397)^c.GetHashCode(); 
     return result; 
    } 
} 

B는 문자열이며, C는 길이 : 일례로서

는 ReSharper에서 본 모습 GetHashCode() 메소드를 생성한다. 중간 값 (결과)은 397에 의해 곱 해져서 각 단계에서 다음 구성 요소의 해시 코드로 처리됩니다. unchecked는 정수가 오버플로 된 경우 (가능성 있음) 오버플로를 무시하고 랩 어라운드한다는 것을 의미합니다. 이것은 대부분의 경우 정수 공간에 대한 합리적인 적용 범위를 제공해야합니다. 비록 가난한 해시 코드가 시스템의 성능에 심각한 영향을 미칠 수 있으므로 적용 범위를 테스트하는 것이 좋습니다.

0으로 곱하지 않고 모두 해시 코드가 0 인 많은 수의 개체로 끝나도록 모든 필드의 0을 처리하는 데주의해야합니다.

+0

흥미로운 접근 방식. 속성의 이유는 Checksum 값이 Linq2SQL 또는 EF4를 사용하여 데이터베이스에 유지되므로 속성으로 사용하면 해당 매핑이 매우 간단 해집니다. 우리의 목적 (어느 수준의 안전성)을 위해서 MD5와 같은 "잘 알려진"알고리즘을 사용하여 체크섬을 계산해야합니다. –

+0

해시 코드를 사용해서는 안되며, 프로세스 나 프로세스를 계속 실행하는 동안 동일하지는 않으므로 해시 코드를 사용하면 안됩니다. 직렬화 방식이 더 적합 할 것입니다. –