2013-09-06 1 views
3

나는 해시 가능 객체 만 사전에 대한 키로 사용할 수있는 파이썬 세계에서 왔습니다. C#에서도 비슷한 제한이 있습니까? 사용자 정의 유형을 사전 키로 사용할 수 있습니까?C# 사전에서 키로 무엇을 사용할 수 있습니까?

+5

이론적으로 모든 유형을 키로 사용할 수 있습니다. 실제로 그것은 변경 불가능한 유형이어야합니다. 그렇지 않으면 키가 돌연변이를 시작할 때 고통의 세계에있게 될 것입니다 ... –

답변

4

사전 키의 요구 사항은 비교 가능하고 해시 가능하다는 것입니다. NET에서 모든 종류의 거북이입니다. 포인터 유형 이외의 모든 유형은 System.Object에서 파생되며 항상 Equals() 메소드 덕분에 비교할 수 있습니다. GetHashCode() 메서드 덕분에 해시 가능합니다. 따라서 모든 .NET 유형을 자동으로 키로 사용할 수 있습니다.

개체 유형을 키로 사용하려면 개체 ID를 다시 정의하려면 특별한 작업 만 수행하면됩니다. 즉, 두 개의 별개의 객체가 동일해야하는 능력이 필요한 경우입니다. 그런 다음 일반적으로 객체의 필드를 비교하여 Equals() 메서드를 재정의합니다. 그리고 GetHashCode()를 오버라이드해야합니다. 동일한 객체가 동일한 해시 코드를 생성해야합니다.

형식을 변경할 수 없거나 특히 사전에 대한 동작을 사용자 지정하려는 경우 사용자 지정 IEqualityComparer <>을 생성자에 전달할 수 있습니다. 자신 만의 GetHashCode()로 생성 한 해시 코드의 품질은 사전 효율성을 결정한다는 것을 명심하십시오.

2

예, 인터페이스 IEqualityComparer를 구현하고 GetHashCode 및 Equals를 재정의 할 수 있습니다.

+0

너 혼자서 모든 것을해야합니까? 해시 기능을 구현하는 데 도움이되는 항목이 있습니까? –

+0

나는 resharper를 사용한다. 모든 일상적인 작업을한다. – Suhan

+2

'GetHasCode'는 메서드의 재미있는 이름이다. :) 기본 구현은'return false; '입니다. –

1

예 키의 중요한 점은 GetHashCodeEquals을 구현한다는 것입니다. Dictionary<T, K> 구현에서는 일반 IEqualityComparer<T>을 이용할 수 있습니다.

모든 사용자 정의 유형은 GetHashCodeEquals의 기본 구현으로 제공되며 이는 object의 멤버이기 때문에 기본값은 항상 사용자 유형과 관련이 없을 수 있습니다.

사전은 먼저 값이 착륙 할 버킷을 결정하기 위해 해시 코드를 얻으려고 시도합니다. 해시 충돌이 발생하면 평등으로 되돌아갑니다 (I think).

사용하는 키 유형 (class, struct, 기본 유형 등)은 서로 다른 성능 특성을 나타낼 수 있습니다. 우리의 코드베이스에서 우리는 GetHashCode의 기본 구현이 struct에 있었지만 스스로를 오버라이드하는 것보다 빠르지 않다는 것을 발견했습니다. 또한 중첩 된 사전은 복합 키가있는 하나의 사전보다 액세스 시간면에서 우수한 것으로 나타났습니다.

+0

만약 당신이 평등의 명백한 정의를 사용한다면 (즉, 모든 필드가 동일하다면 객체가 같음), 기본 Equals와 GetHashCode가 충분하다고 생각합니까? (성능상의 이유로 어쩌면 예외는 있지만 아직 거기에 없다) –

+3

@static_rtti'class'에 대한 equality의 기본 구현은 field-equal이 아니며, 필자가 생각한 것과 같다. 'struct'에 대해서는 첫 번째 x-byte 블록이나 그와 같은 무언가에 대해 가치가 있다고 생각합니다. 개인적으로 필자는 구현이 키로 사용자 정의 유형에 대해 잘 정의되어 있는지 확인하는 팬이지만 동시에 사용자 정의 유형이 키인 경우가 거의 없습니다. –

+1

@static_rtti 모든 참조 유형은 기본적으로 참조 동일성을 사용합니다. –

관련 문제