2010-06-22 16 views
7

क्यों GetHashCode ऑब्जेक्ट क्लास का हिस्सा है? कक्षाओं की वस्तुओं का केवल छोटा हिस्सा हैश टेबल में चाबियों के रूप में उपयोग किया जाता है। एक अलग इंटरफ़ेस रखना बेहतर नहीं होगा जिसे लागू किया जाना चाहिए जब हम कक्षा की वस्तुओं को हैश तालिका में कुंजी के रूप में सेवा करना चाहते हैं।ऑब्जेक्ट क्लास में GetHashCode क्यों है?

एक कारण होना चाहिए कि एमएस टीम ने ऑब्जेक्ट क्लास में इस विधि को शामिल करने का निर्णय लिया और इस प्रकार इसे "हर जगह" उपलब्ध कराया।

+1

मुझे संदेह है कि इसे 'java.lang.object' के' हैशकोड() 'के बाद मॉडलिंग किया गया था इससे पहले .NET ने इंटरफेस का उपयोग करना शुरू कर दिया था (ध्यान दें कि' GetHashCode' वापस .NET 1.0 पर जाता है)। –

उत्तर

16

यह जावा, आईएमओ से कॉपी की गई एक डिज़ाइन गलती थी।

मेरे आदर्श दुनिया में:

  • ToStringToDebugString नाम दिया जाएगा उचित रूप से
  • Equals अपेक्षाएं निर्धारित करने के और GetHashCode चला गया हो जाएगा
  • IEqualityComparer<T> के ReferenceEqualityComparer कार्यान्वयन वहाँ होगा: इस के हिस्से के बराबर होती है फिलहाल यह आसान है, लेकिन अगर इसे
  • ऑब्जेक्ट्स ओवरराइड किया गया है तो "मूल" हैश कोड प्राप्त करने का कोई तरीका नहीं है। टी उनके साथ जुड़े मॉनीटर हैं: Monitor में एक कन्स्ट्रक्टर होगा, और Enter/Exit आदि उदाहरण विधियां होंगी।

समानता (और इस प्रकार hashing) सामान्य रूप में विरासत पदानुक्रम में कारण समस्याओं - इतने लंबे समय आप हमेशा तुलना आप उपयोग करना चाहते की तरह निर्दिष्ट कर सकते हैं के रूप में (IEqualityComparer<T> के माध्यम से) और वस्तुओं IEquatable<T> खुद को लागू कर सकते हैं वे करना चाहते हैं, मुझे नहीं लगता कि यह Object पर क्यों होना चाहिए। EqualityComparer<T>.Default संदर्भ कार्यान्वयन का उपयोग कर सकते हैं यदि TIEquatable<T> लागू नहीं किया गया है और अन्यथा वस्तुओं को स्थगित कर दिया गया है। जीवन सुखद होगा।

आह ठीक है। जबकि मैं इसमें हूं, सरणी covariance एक और मंच गलती थी। यदि आप सी # में भाषा गलतियों को चाहते हैं, तो मैं आपको एक और मामूली रान शुरू कर सकता हूं;) (यह अभी भी मेरी पसंदीदा भाषा है, लेकिन ऐसी चीजें हैं जो मेरी इच्छा पूरी तरह से की गई थीं।)

मेरे पास blogged about this कहीं और है, btw।

+3

हां, भाषा गलतियों के लिए एक और धागा चर्चा क्यों नहीं खोलें। मेरा मानना ​​है कि वहाँ दूसरों जो आप GetHashCode "ग़लती" की तरह कुछ नोट करने के लिए चाहते हो जाएगा :) – Incognito

+0

@Incognito: वहाँ एक "अपने पसंदीदा भाषा में शीर्ष 5 गलतियों" सवाल कहीं आसपास है ... –

+0

@JonSkeet मैं तर्क था कि 'ToDebugString' या तो अच्छा नहीं है। डिबगिंग उत्पादन कोड से अलग होना चाहिए। इस प्रकार, गुण एक बेहतर समाधान हैं। ("" क्योंकि वे पहले से ही उपलब्ध हैं) –

0
  1. तो कुछ भी चालू किया जा सकता है। (सॉर्टा)
  2. इस तरह HashTable उदाहरण के लिए IHashable लागू करने वाला ऑब्जेक्ट बनाम कुछ ले सकता है।
  3. सरल समानता तुलना ड्राइव करने के लिए।

ऑब्जेक्ट को लागू नहीं करते यह सीधे नेट के आंतरिक हैश कोड में चूक जो मेरा मानना ​​है कि या वस्तु उदाहरण के लिए या तो एक अद्वितीय ID स्मृति पदचिह्न के हैश यह लेता है उस पर। (मुझे याद नहीं है और .NET परावर्तक कक्षा के .NET घटक से पहले नहीं जा सकता है)।

+2

गेटहाशकोड के पास तुलना के साथ कुछ लेना देना नहीं है - यह एक अलग मुद्दा है। –

+0

ए। गेटहाशकोड() ए। गेटहाशकोड() के बराबर है, लेकिन बी। गेटहाशकोड() ए। गेटहाशकोड() के बराबर हो सकता है। इसे "समान समानता तुलना ड्राइव करने के लिए" इसका उपयोग करना वास्तव में एक बुरा विचार है। – HoLyVieR

3

वर्गों की वस्तुओं के केवल छोटा सा हिस्सा हैश तालिकाओं

मैं तर्क है कि यह एक सच बयान नहीं है में कुंजी के रूप में उपयोग किया जाता है। कई वर्गों को अक्सर हैश तालिकाओं में चाबियों के रूप में उपयोग किया जाता है - और ऑब्जेक्ट संदर्भ स्वयं अक्सर उपयोग किए जाते हैं। GetHashCode का डिफ़ॉल्ट कार्यान्वयन सिस्टम में मौजूद है। ऑब्जेक्ट का अर्थ है कि किसी भी ऑब्जेक्ट को बिना किसी प्रतिबंध के कुंजी के रूप में उपयोग किया जा सकता है।

यह ऑब्जेक्ट्स पर कस्टम इंटरफ़ेस को मजबूर करने से बहुत अच्छा लगता है, बस उन्हें हैश करने में सक्षम होने के लिए। किसी ऑब्जेक्ट को किसी शेड संग्रह में कुंजी के रूप में उपयोग करने की आवश्यकता होने पर आपको कभी पता नहीं होता है।

HashSet<T> जैसी चीजों का उपयोग करते समय यह विशेष रूप से सच है - इस मामले में, अक्सर, ऑब्जेक्ट संदर्भ ट्रैकिंग और विशिष्टता के लिए उपयोग किया जाता है, जरूरी नहीं कि "कुंजी" के रूप में। हैशिंग को एक कस्टम इंटरफ़ेस की आवश्यकता होती है, कई कक्षाएं बहुत कम उपयोगी हो जाती हैं।

+1

फिर यह 'गेटहाशकोड' [पेज] (http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx) में क्यों लिखा गया है: "... इस विधि का डिफ़ॉल्ट कार्यान्वयन हैशिंग प्रयोजनों के लिए एक अद्वितीय ऑब्जेक्ट पहचानकर्ता के रूप में उपयोग नहीं किया जाना चाहिए "? –

+1

कुछ भी कम उपयोगी क्यों होगा? आप बस एक उचित 'IEqualityComparer ' कार्यान्वयन निर्दिष्ट करेंगे - जिसे "संदर्भ द्वारा तुलना" किया जा सकता है। वास्तव में, यही है 'समानता कॉम्पैयर । डीफॉल्ट' कर सकता है। अधिक जानकारी के लिए मेरा जवाब देखें। –

+0

@ जोन: सच - इसे अलग से निर्दिष्ट करने की आवश्यकता होगी, लेकिन काफी आसानी से किया जा सकता है - मेरा मुद्दा यह था कि मैं ऑब्जेक्ट को इंटरफ़ेस को लागू करने के लिए ऑब्जेक्ट की आवश्यकता के लिए ऑब्जेक्ट करता हूं - लेकिन इसे अलग से निर्दिष्ट करना ठीक होगा। –

0

GetHashCode ऑब्जेक्ट में है ताकि आप मूल कंटेनर क्लास हैशटेबल में किसी कुंजी के रूप में कुछ भी उपयोग कर सकें। यह समरूपता प्रदान करता है। मैं किसी भी ऐरेलिस्ट में डाल सकता हूं, क्यों हैशटेबल नहीं?

यदि आपको IHashable को लागू करने के लिए कक्षाओं की आवश्यकता होती है, तो प्रत्येक सीलबंद वर्ग के लिए जो IHashable को लागू नहीं करता है, आप एडाप्टर लिखेंगे जब आप इसे उस कुंजी के रूप में उपयोग करना चाहते हैं जिसमें हैशिंग क्षमता शामिल है। इसके बजाय, आप इसे डिफ़ॉल्ट रूप से प्राप्त करते हैं।

ऑब्जेक्ट समानता तुलना के लिए हैशकोड एक अच्छी दूसरी पंक्ति है (पहली पंक्ति पॉइंटर समानता है)।

1

यह किसी भी ऑब्जेक्ट को "पहचान" द्वारा कुंजी के रूप में उपयोग करने की अनुमति देता है। यह कुछ मामलों में फायदेमंद है, और किसी में हानिकारक नहीं है। तो क्यों नहीं?

+0

क्योंकि प्रतिशत तुलना में केवल बहुत ही कम वर्ग वस्तुओं को कुंजी के रूप में उपयोग किया जाता है। अपने जवाब के अनुसार एक निष्कर्ष निकाल सकते हैं कि हम क्यों IComparable इंटरफ़ेस का ऑब्जेक्ट वर्ग में compareTo शामिल कर सकते हैं की जरूरत है :) – Incognito

+0

@Incognito: नहीं, एक निष्कर्ष नहीं निकाल सकता है कि 'IComparable' अनावश्यक है, क्योंकि एक * समझदार *' के कार्यान्वयन को परिभाषित करने के लिए संभव नहीं है सभी वस्तुओं के लिए तुलना करें '। * पहचान * के आधार पर एक समकक्ष संबंध बहुत समझ में आता है, और उस परिभाषा के अनुरूप एक 'गेटहाशकोड' विधि को परिभाषित करना आसान है। कोई 'तुलनात्मक' के लिए ऐसा नहीं कह सकता है। जबकि नक्शा कुंजी के रूप में उपयोग करते हैं, सीमित है एक पहचान-आधारित बनाने 'HashSet' कई प्रकार के लिए आम है, और वस्तु के किसी भी प्रकार के लिए एक हैश कोड कंप्यूटिंग के एक साधन के बिना रोका किया जाएगा। – erickson

+1

@ एरिक्सन इसी तरह, बराबर/GetHashCode अधिकांश वस्तुओं के लिए समझदार नहीं है। –

0

यदि प्रत्येक वर्ग में GetHashCode है तो आप प्रत्येक ऑब्जेक्ट को हैश में डाल सकते हैं। कल्पना कीजिए कि आपके पास तीसरे पक्ष की वस्तुओं का उपयोग करना है (जिसे आप संशोधित नहीं कर सकते) और उन्हें अब हैश में रखना चाहते हैं। यदि इन वस्तुओं ने आपको काल्पनिक IHashable लागू नहीं किया है तो आप इसे नहीं कर सके। यह स्पष्ट रूप से एक बुरी चीज है;)

+2

हाँ, आप कर सकते हैं - तुम सिर्फ हैश तालिका क्या 'IEqualityComparer ' के माध्यम से उपयोग करने के लिए कहेंगे। बहुत सरल –

0

बस एक अनुमान है, लेकिन कचरा कलेक्टर आंतरिक रूप से कुछ वस्तुओं के हैंशटेबल स्टोर कर सकता है (शायद अंतिम रूप से वस्तुओं का ट्रैक रखने के लिए), जिसका अर्थ है कि किसी वस्तु को हैश कुंजी होना चाहिए।

संबंधित मुद्दे