2010-07-23 15 views
13

हे सब, मैं .NET में ऑब्जेक्ट्स के लिए GetHashCode() ओवरराइड को लागू करने का सबसे अच्छा तरीका पढ़ रहा हूं, और अधिकांश उत्तरों में जो भी मैं दौड़ता हूं, उन सदस्यों से मिलकर संख्याओं को एक साथ जोड़ता है एक विधि के साथ आने के लिए संख्यात्मक प्रकार। समस्या यह है कि, मेरे पास एक ऑब्जेक्ट है जो अल्फान्यूमेरिक स्ट्रिंग का उपयोग अपनी कुंजी के रूप में करता है, और मैं सोच रहा हूं कि स्ट्रिंग्स के साथ स्ट्रिंग वाले ऑब्जेक्ट्स के लिए आंतरिक आईडी का उपयोग करने के साथ कुछ मूलभूत रूप से गलत है, तो निम्न की तरह कुछ?स्ट्रिंग कुंजियों के साथ GetHashCode()


// Override GetHashCode() to return a permanent, unique identifier for 
// this object. 
static private int m_next_hash_id = 1; 
private int m_hash_code = 0; 
public override int GetHashCode() { 
    if (this.m_hash_code == 0) 
    this.m_hash_code = <type>.m_next_hash_id++; 
    return this.m_hash_code; 
} 

वहाँ एक बेहतर तरीका है एक वस्तु उसके प्रमुख के रूप में एक अल्फ़ान्यूमेरिक स्ट्रिंग का उपयोग करता है के लिए एक अनूठा हैश कोड साथ आने के लिए है? (और नहीं, अल्फान्यूमेरिक स्ट्रिंग के संख्यात्मक भाग अद्वितीय नहीं हैं; इनमें से कुछ तारों में वास्तव में उनमें संख्याएं नहीं हैं।) किसी भी विचार की सराहना की जाएगी!

उत्तर

19

आप अपने ऑब्जेक्ट में उपयोग किए गए गैर-संख्यात्मक मानों पर GetHashCode() पर कॉल कर सकते हैं।

private string m_foo; 
public override int GetHashCode() 
{ 
    return m_foo.GetHashCode(); 
} 
+0

लेकिन क्या होगा यदि वह स्ट्रिंग बदलती है? उदाहरण के लिए, मैं एक नया उपयोगकर्ता ऑब्जेक्ट बना सकता हूं: उपयोगकर्ता foo = new user(); और कन्स्ट्रक्टर उपयोगकर्ता.आईडी = "" सेट करता है। बाद में, अगर मैं उपयोगकर्ता कहता हूं। आईडी = "ए 12345"; और मैं इसे वापस भेजता हूं। आईडी.गेटशैशकोड() foo.GetHashCode() के परिणामस्वरूप, क्या यह परिवर्तित नहीं होगा, इस सिद्धांत का उल्लंघन करना कि किसी ऑब्जेक्ट के हैश कोड को कभी नहीं बदला जाना चाहिए? –

+6

ऑब्जेक्ट बदल गया। हैश कोड * को भी बदलना है *। –

+0

@ किंग - हैश कोड का उपयोग करने के कुछ अलग-अलग तरीके हैं। हैश कोड का मान हमेशा एक ही प्रारंभिक मान के समान होना चाहिए। यदि आपका मान उत्परिवर्तनीय है, तो आपको परिणामी हैशकोड को स्टोर करने की आवश्यकता है और इसके बजाय 'GetHashCode()' कहा जाता है। –

0

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

एक स्थिर क्षेत्र में वृद्धि करने और हैशकोड के रूप में इसका उपयोग करने का विचार एक बुरा है। हैश कोड में संभावित मूल्यों के स्थान पर भी वितरण होना चाहिए। यह अन्य चीजों के साथ सुनिश्चित करता है कि हैशटेबल में कुंजी के रूप में उपयोग किए जाने पर यह अच्छा प्रदर्शन करेगा।

0

मेरा मानना ​​है कि आप आमतौर पर चाहते हैं GetHashCode() कुछ है कि वस्तु को दिखाता है यह मूल्य है द्वारा वापस जाने के लिए, बजाय यह उदाहरण है, अगर मैं विचार यहाँ समझने रहा हूँ, मुझे लगता है कि अपने विधि बराबर मूल्यों के साथ दो अलग-अलग वस्तुओं पर GetHashCode() यह सुनिश्चित करना होगा होगा अलग-अलग हैंश वापस करें क्योंकि वे अलग-अलग उदाहरण हैं।

GetHashCode() एक ऐसा मूल्य वापस करने के लिए है जो आपको दो ऑब्जेक्ट मानों की तुलना करने देता है, न कि उनके संदर्भ।

2

हैश कोड अद्वितीय होने की आवश्यकता नहीं है। बशर्ते आपका Equals कार्यान्वयन सही है, दो उदाहरणों के लिए एक ही हैश कोड वापस करना ठीक है। m_next_hash_id तर्क टूटा हुआ है, क्योंकि यह दो ऑब्जेक्ट्स को अलग हैश कोड रखने की अनुमति देता है भले ही वे बराबर की तुलना करें।

एमएसडीएन Equals और GetHashCode को कार्यान्वित करने के निर्देशों का एक अच्छा सेट देता है। Several of the examples here किसी ऑब्जेक्ट के फ़ील्ड के हैश कोड के संदर्भ में GetHashCode लागू करें

18

यह ऑब्जेक्ट के लिए हैश उत्पन्न करने के लिए एक अच्छा पैटर्न नहीं है।

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

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

यदि आपके पास पहले से ही ऑब्जेक्ट में एक स्ट्रिंग सदस्य है, तो बस अपने हैश कोड को वापस करें ।

documentation on MSDN for implementers of GetHashCode() है एक किसी को भी कि उस विधि अधिभावी पर योजना बना रही है के लिए अवश्य पढ़ें: Implementers

एक हैश समारोह को

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

दो तो वस्तुओं के रूप में बराबर की तुलना,:

एक हैश समारोह निम्नलिखित गुण होना आवश्यक है। हालांकि, यदि दो ऑब्जेक्ट्स के बराबर तुलना नहीं करते हैं, के लिए GetHashCode विधियों को दो ऑब्जेक्ट को अलग-अलग मानों को वापस करने की आवश्यकता नहीं है।

एक वस्तु को The GetHashCode विधि लगातार जब तक वस्तु राज्य के लिए कोई संशोधन नहीं है के रूप में है कि निर्धारित करता है वस्तु की विधि के बराबर की वापसी मान एक ही हैश कोड लौटना चाहिए। ध्यान दें कि यह केवल किसी निष्पादन के वर्तमान निष्पादन के लिए सत्य है, और यदि अनुप्रयोग दोबारा चलाया जाता है तो अलग हैश कोड वापस किया जा सकता है।

सर्वोत्तम प्रदर्शन के लिए, हैश फ़ंक्शन को सभी इनपुट के लिए एक यादृच्छिक वितरण उत्पन्न करना होगा।

उदाहरण के लिए, स्ट्रिंग वर्ग द्वारा प्रदान की GetHashCode विधि के क्रियान्वयन रिटर्न समान हैश समान स्ट्रिंग मूल्यों के लिए कोड। इसलिए, दो स्ट्रिंग ऑब्जेक्ट्स समान हैश कोड लौटाते हैं यदि वे समान स्ट्रिंग मान का प्रतिनिधित्व करते हैं। इसके अलावा, विधि स्ट्रिंग में सभी वर्णों का उपयोग करता यथोचित बेतरतीब ढंग से वितरित उत्पादन उत्पन्न करने के लिए, तब भी जब इनपुट (उदाहरण के लिए कुछ पर्वतमाला में गुच्छा है, कई उपयोगकर्ताओं तार कि केवल निचले 128 ASCII शामिल हो सकता है पात्र, भले ही स्ट्रिंग में 65,535 यूनिकोड वर्ण शामिल हो सकते हैं)।

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