2009-02-03 8 views
15

नीचे एक इकाई बेस क्लास के लिए ऑब्जेक्ट। एक्वाल्स() को ओवरराइड करने का एक नमूना कार्यान्वयन है, जिससे एप्लिकेशन में अन्य सभी इकाइयां प्राप्त होती हैं।इकाई कक्षाओं के लिए GetHashCode() के लिए सही कार्यान्वयन क्या है?

सभी इकाई वर्गों में संपत्ति आईडी है, जो एक शून्य है। कैसे आप सही तरीके से लागू करते हैं GetHashCode() (यह भी टेबल इकाई वर्ग से मेल खाती है की प्राथमिक कुंजी है।)

public override bool Equals(object obj) 
     { 
      if (obj == null || GetType() != obj.GetType()) 
       return false; 

      if (base.Equals(obj)) 
       return true; 

      return Id.HasValue && ((EntityBase) obj).Id.HasValue && 
        Id.Value == ((EntityBase) obj).Id.Value; 
     } 

बराबर() की इस कार्यान्वयन को देखते हुए,?

+0

रिकॉर्ड के लिए, आईडी के लिए एक निरर्थक int होना एक भयानक विचार है। आईडी वास्तव में हमेशा GUID होना चाहिए और निश्चित रूप से शून्य नहीं होना चाहिए। –

उत्तर

23

आप कुछ है कि पहले से ही ओवरराइड करता है GetHashCode से पाने रहे हैं मैं इसे लागू होता है:

public override int GetHashCode() 
{ 
    unchecked 
    { 
     int hash = 37; 
     hash = hash * 23 + base.GetHashCode(); 
     hash = hash * 23 + Id.GetHashCode(); 
     return hash; 
    } 
} 

आईडी की एक शून्य मान Id.GetHashCode के लिए 0 वापस आ जाएगी()।

अपनी कक्षा सिर्फ वस्तु से निकला है, तो मैं सिर्फ वापसी चाहते हैं Id.GetHashCode() - आप करते हैं कि मूल रूप से वस्तु पहचान किया जा रहा समाप्त होता है, अपने हैश कोड में object.GetHashCode कार्यान्वयन शामिल करने के लिए नहीं चाहते हैं।

ध्यान रखें कि आपके समानता परिभाषा नहीं होगा वापसी true अगर न इकाई एक आईडी है, लेकिन एक ही hashCode दोनों वस्तुओं से लौटा दी जाएगी। आप अपने बराबर कार्यान्वयन को बदलने पर विचार करना चाह सकते हैं।

+9

उन लोगों के लिए, जैसे मैंने किया: 23 और 37 मनमानी संख्याएं हैं जो सह-प्रधान हैं। जॉन ने यहां एक समान उत्तर में यह कहा: http://www.eggheadcafe.com/software/aspnet/29483139/override-gethashcode.aspx –

+0

@ जोनस्केट आप सहमत नहीं होंगे कि 'base.GetHashCode()' ऑब्जेक्ट का उपयोग करेगा .GetHashCode, जो स्मृति पते का उपयोग करता है। उस स्थिति में GetHashCode में संपत्ति नहीं है कि जब बराबर दो वस्तुओं के लिए सत्य लौटाता है, तो उनके हैशकोड समान होना चाहिए ?? – Jaap

+0

@ जोनस्केट मैं कंपाइलर विकल्पों से बचने के लिए हैशकोड कार्यान्वयन के लिए 'अनचेक {}' भी जोड़ूंगा ... यह एक बढ़िया मामला है जिसे आप शायद कभी नहीं चलाएंगे ... किसी भी तरह से, अनचेक किए गए कीवर्ड को दस्तावेज करने का एक तरीका है फ़ंक्शन में पूर्णांक ओवरफ़्लो ठीक है। – Jaap

1

आप केवल सही ढंग से GetHashCode() लागू कर सकते हैं, तो Id संपत्ति एक उदाहरण के जीवन भर के लिए अपरिवर्तनीय है (या कम से कम समय है कि अपने हैश की जरूरत के लिए, इस तरह के हैं, जबकि वस्तु एक नक्शा या अन्य संग्रह की आवश्यकता होती है में है के रूप में प्रयोग की जाने वाली हैश)।

यह मानते हुए कि आप Id के मान को सभी वैध मानों के लिए हैश के रूप में उपयोग कर सकते हैं और फिर शून्य के लिए एक निश्चित हैश का उपयोग कर सकते हैं। मुझे याद नहीं है कि इसके लिए सबसे उपयुक्त क्या है, लेकिन मैं शून्य के लिए यादृच्छिक रूप से चयनित मूल्य मानता हूं (संकलन से पहले यादृच्छिक रूप से चयनित, रनटाइम पर नहीं) या वैध Id मानों का औसत मूल्य (यानी 0 और int के बीच आधे रास्ते। मैक्स)।

+1

इसे जीवन भर के लिए अपरिवर्तनीय नहीं होना चाहिए - केवल उस बिंदु से जिस पर इसे पहले मानचित्र या जो कुछ भी डाला गया हो।एक उदाहरण बनाने के लिए ठीक है, इसके साथ गड़बड़, इसे एक मानचित्र में डाल दें और * फिर * इसके साथ गड़बड़ करना बंद करें। –

+0

यह एक उचित बिंदु है। मैं एक संपादन कर दूंगा। –

2

क्या जॉन स्कीट उत्तर दिया, एक अच्छा समाधान, हालांकि, आप एक अनियंत्रित कोड ब्लॉक जोड़ने के लिए पूर्णांक बह निकला

unchecked 
{ 
    int hash = ...; 
    return hash 
} 

https://msdn.microsoft.com/en-us/library/khy08726(v=vs.140).aspx

न जाँच की है और न ही अनियंत्रित निर्दिष्ट है, तो अनुमति देने के लिए चाहते हो सकता है है डिफ़ॉल्ट संदर्भ बाहरी कारकों जैसे संकलक विकल्पों पर निर्भर करता है।

मैं भी जोड़ने के लिए फिर से, कि POCO पर base.GetHashCode() का उपयोग कर डिफ़ॉल्ट object.GetHashCode कॉल करेंगे चाहते हैं। यह निश्चित रूप से नहीं है कि आप क्या चाहते हैं ...

+0

'अनचेक' डिफ़ॉल्ट है और अनावश्यक है। –

+0

"यदि न तो चेक किया गया और न ही अनचेक किया गया है, तो डिफ़ॉल्ट संदर्भ बाहरी कारकों जैसे कि कंपाइलर विकल्पों पर निर्भर करता है।" https://msdn.microsoft.com/en-us/library/khy08726(v=vs.140).aspx तो यदि आप ऐसा कोड लिखते हैं, तो मैं इसे वहां रखूंगा। यह दस्तावेज का एक रूप भी है। – Jaap

+1

अब अपने स्वयं के जवाब में अनचेक हिस्सा जोड़ा है, बीटीडब्ल्यू। –

2

हैश कोड के हिस्से के रूप में प्रकार का उपयोग करने के बारे में क्या?
क्या यह एक अच्छा कार्यान्वयन होगा?

public class Foo 
{ 
    public int Id { get; set; } 

    // other properties here 
    // ...... 

    public override int GetHashCode() 
    { 
     int hash = 37; 
     hash = hash * 23 + typeof(Foo).GetHashCode(); 
     hash = hash * 23 + Id.GetHashCode(); 
     return hash; 
    } 
} 
संबंधित मुद्दे