2010-06-22 2 views
7

GetHashCode이 Object 클래스의 일부입니까? 클래스 객체의 작은 부분 만 해시 테이블의 키로 사용됩니다. 클래스의 객체가 해시 테이블의 키 역할을하도록하려면 별도의 인터페이스를 구현하는 것이 더 좋지 않습니까?GetHashCode가 Object 클래스에있는 이유는 무엇입니까?

MS 팀이이 메서드를 Object 클래스에 포함시켜 "모든 곳"에서 사용할 수 있도록해야하는 이유가 있어야합니다.

+1

.NET이 인터페이스를 많이 사용하기 전에'java.lang.object'의'hashCode()'를 모델로 만든 것 같습니다 ('GetHashCode'는 .NET 1.0으로 돌아갑니다). –

답변

16

Java, IMO에서 복사 한 디자인 실수였습니다.내 완벽한 세상에서

는 :

  • ToString 적절하게
  • Equals을 기대치를 설정하는 ToDebugString 이름이 변경 될 및 GetHashCode
  • IEqualityComparer<T>ReferenceEqualityComparer 구현이 될 것이다 사라질 것이다 다음은이 부분에 해당 현재로서는 쉽지만 오버라이드 된 경우 "원래"해시 코드를 얻을 수있는 방법이 없습니다.
  • 오브젝트는 ' 그들과 연결된 모니터가 있습니다 : Monitor에는 생성자가 있고 Enter/Exit 등은 인스턴스 메소드입니다.

평등 일반적으로 상속 계층 구조의 문제를 야기 (및 해시) - 그래서 당신이 항상 (IEqualityComparer<T>를 통해) 사용할 비교의 종류를 지정할 수 있으며, 객체가 IEquatable<T> 자체를 구현할 수 그들이 원하는 경우, 내가 왜 Object에 있어야하는지 모르겠다. EqualityComparer<T>.DefaultTIEquatable<T>을 구현하지 않은 경우 참조 구현을 사용할 수 있으며, 그렇지 않으면 객체를 연기 할 수 있습니다. 인생은 즐겁습니다.

아. 그 동안 배열 공분산은 또 다른 플랫폼 실수였습니다. C#에서 언어 실수를 원한다면, 나는 원할 경우 다른 작은 호언 장담을 시작할 수있다.) (여전히 내가 좋아하는 언어이지만, 다르게 수행되기를 바란다.)

나는 다른 곳에서 blogged about this을 사용했다. btw.

+3

예, 언어 실수에 대한 다른 스레드 토론을 열지 마십시오. 나는 당신이 GetHashCode "실수"와 같은 것을 주목하고 싶은 다른 사람들이있을 것이라고 믿는다. :) – Incognito

+0

@Incognito : 어딘가에서 "좋아하는 언어로 5 번 실수"라는 질문이있다. –

+0

@JonSkeet 나는 'ToDebugString' 어느 쪽도 좋지 않다. 디버깅은 프로덕션 코드와 분리되어야합니다. 따라서 특성이 훨씬 더 나은 솔루션입니다. ("the"는 이미 사용 가능하므로) –

0
  1. 아무 것도 키 입력 할 수 있습니다. (Sorta)
  2. 그런 식으로 HashTable은 객체 대 객체 (예 : IHashable)를 취할 수 있습니다.
  3. 간단한 단순 비교를 유도합니다.

개체를 직접 구현하지 않으면 개체 인스턴스의 고유 ID 또는 차지하는 메모리 발자국의 해시 중 하나라고 생각되는 .NET의 내부 해시 코드가 기본값으로 사용됩니다. (나는 기억할 수없고 .NET Reflector는 클래스의 .NET 구성 요소를 지나갈 수 없다.) 클래스의 객체의

+2

GetHashCode는 비교와 관련이 없습니다. 이는 별개의 문제입니다. –

+0

a.GetHashCode()는 a.GetHashCode()와 같지만 b.GetHashCode()는 a.GetHashCode()와 같을 수 있습니다. 간단한 동등 비교를 유도하는 것은 정말 나쁜 생각입니다. – HoLyVieR

3

만 작은 부분은 해시 테이블

나는 이것이 진정한 문 아니라고 주장의 키로서 사용된다. 많은 클래스가 종종 해시 테이블의 키로 사용되며 객체 참조 자체가 자주 사용됩니다. System.Object에 GetHashCode의 기본 구현이 있으면 제약없이 ANY 개체를 키로 사용할 수 있습니다.

이것은 해시 할 수 있도록 개체에 맞춤 인터페이스를 적용하는 것보다 훨씬 좋게 보입니다. 해시 콜렉션에서 객체를 키로 사용해야 할 때를 알 수 없습니다. 과 같은 것을 사용할 때 특히 그렇습니다.이 경우 흔히 "키"가 아닌 추적 및 고유성을 위해 객체 참조가 사용됩니다. 해싱에 사용자 정의 인터페이스가 필요하다면 많은 클래스가 유용하지 않게됩니다.

+1

그런데 왜 이것이'GetHashCode' [페이지] (http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx)에 쓰여 있습니다 : "...이 메소드의 기본 구현 해싱을위한 고유 한 객체 식별자로 사용하면 안됩니다. " –

+1

왜 아무것도 유용하지 않게됩니까? 적절한 'IEqualityComparer '구현을 지정하면됩니다. 이는 "비교 기준"일 수 있습니다. 실제로, 그것은'EqualityComparer .Default'가 할 수있는 것입니다. 자세한 내용은 내 대답을 참조하십시오. –

+0

@ 존 : 사실 : 별도로 지정해야하지만 상당히 쉽게 수행 할 수 있습니다. 요점은 객체 자체가 인터페이스를 구현해야한다는 사실에 반대한다는 것입니다.하지만 별도로 지정하는 것이 좋을 것입니다. –

0

GetHashCode는 객체이므로 기본 컨테이너 클래스 인 Hashtable에 키를 사용할 수 있습니다. 대칭을 제공합니다. 나는 Hashtable이 아닌 ArrayList에 무엇이든 넣을 수 있습니까?

IHashable을 구현하기 위해 클래스가 필요한 경우 IHashable을 구현하지 않는 모든 봉인 된 클래스에 대해 해시 기능이 포함 된 키로 사용할 때 어댑터를 작성합니다. 대신 기본적으로 가져옵니다.

또한 해시 코드는 개체 동일성 비교 (첫 번째 줄은 포인터 같음)에 적합한 두 번째 줄입니다.

1

모든 개체를 "ID"로 키로 사용할 수 있습니다. 이것은 어떤 경우에 유익하며 아무에게도 해롭지 않습니다. 그래서 왜 안돼?

+0

백분율 비교에서는 키로 사용되는 클래스 개체가 거의 없기 때문입니다. 당신의 대답에 따르면 우리는 왜 IComparable 인터페이스가 Object 클래스에 CompareTo를 포함시켜야하는지 결론 내릴 수 있습니다 :) – Incognito

+0

@Incognito : 아니오, 'IComparable'은 불필요하다고 결론 지을 수 없습니다. 왜냐하면' 모든 개체에 대해 CompareTo'. * identity *에 기초한 동치 관계는 많은 의미를 가지며, 그 정의와 일치하는'GetHashCode' 메소드를 정의하는 것은 쉽습니다. 'CompareTo'에 대해서도 똑같이 말할 수는 없습니다. 맵 키로 사용하는 것은 제한되어 있지만 신원 기반 'HashSet'을 만드는 것은 많은 유형에 공통적이며 어떤 유형의 객체에 대해서도 해시 코드를 계산할 수있는 수단 없이는 배제됩니다. – erickson

+1

@erickson 마찬가지로, Equals/GetHashCode는 MOST 객체에는 적합하지 않습니다. –

0

모든 클래스에 GetHashCode가 있으면 모든 객체를 해시에 넣을 수 있습니다. 당신이 수정할 수없는 써드 파티 객체를 사용하고이를 해쉬 해시에 넣고 싶다고 상상해보십시오. 이 객체들이 당신을 구현하지 않았다면 가상의 IHashable을 할 수 없습니다. 이것은 분명히 나쁜 것입니다;)

+2

네, 해시 테이블에'IEqualityComparer '을 통해 무엇을 사용할 지 알려 주시면됩니다. 매우 간단합니다. –

0

가비지 컬렉터가 일부 객체의 해시 테이블을 내부적으로 저장할 수 있습니다. 즉, 최종 객체를 추적 할 수 있습니다. 즉, 모든 객체에 해시 키가 있어야합니다.

관련 문제