2010-10-12 11 views
5

मैंने इस बारे में सोचा है, इसलिए मुझे लगता है कि मैं इसे पूछूंगा। आप एक ही अर्थ तर्क के लिए अधिभावी सदस्य वार समानता के लिए GetHashCode के रूप में बराबर का उपयोग देखेंगेगेटहाशकोड समानता

अधिकांश स्थानों ... लेकिन वे आम तौर पर विभिन्न कार्यान्वयन का उपयोग करें:

public override bool Equals(object obj) 
    { 
     if (obj == null || GetType() != obj.GetType()) 
     { 
      return false; 
     } 
     var other = (MyType)obj; 
     if (other.Prop1 != Prop1) 
     { 
      return false; 
     } 
     return true; 
    } 

    public override int GetHashCode() 
    { 
     int hash = -657803396; 
     num ^= Prop1.GetHashCode(); 
     return num; 
    } 

आप अपने प्रकार के लिए सदस्य वार समानता को लागू कर रहे हैं (की सुविधा देता है एक शब्दकोश में संग्रहीत करने के लिए कहते हैं), क्यों नहीं बस ओवरराइड GetHashCode तो बराबर के लिए कुछ इस तरह करते हैं:

public override bool Equals(object obj) 
    { 
     return this.HashEqualsAndIsSameType(obj); 
    } 

    public static bool HashEquals(this object source, object obj) 
    { 
     if (source != null && obj != null) 
     { 
      return source.GetHashCode() == obj.GetHashCode(); 
     } 
     if (source != null || obj != null) 
     { 
      return false; 
     } 
     return true; 
    } 

    public static bool HashEqualsAndIsSameType<T>(this T source, object obj) 
    { 
     return (obj == null || obj.GetType() == typeof(T)) && source.HashEquals(obj); 
    } 

उत्तर

10

क्योंकि विवादों का वास्तविक जोखिम है। हैश-कोड अद्वितीय नहीं हैं। वे असमानता साबित कर सकते हैं (लेकिन अलग), लेकिन समानता कभी नहीं। जब एक आइटम की तलाश:

  • हैश कोड (रों)
  • अगर हैश कोड अलग, वस्तु अलग है मिलता है, त्यागने यह
  • अगर हैश कोड एक ही है, जांच के बराबर है:
  • अगर बराबर रिपोर्ट true वे एक ही
  • बाकी
  • हैं त्यागने

पर विचार करें long ... के बाद से हैश कोड int है , यह देखना आसान है कि बहुत सारे और बहुत सारे संघर्ष हैं।

+0

तो आप कम से कम डुप्लीकेट सदस्य संदर्भों के साथ सदस्यवृत्ति GetHashCode/Equals को लागू करने की अनुशंसा कैसे करेंगे? इस तरह के नकल से आकस्मिक कमी हो सकती है और महत्वपूर्ण समस्याएं पैदा हो सकती हैं (जो आज मेरे प्रश्न को प्रेरित करती है)। इसके अलावा, अगर हम किसी ऑब्जेक्ट के लिए एक अद्वितीय चेकसम चाहते हैं तो क्या होगा। क्या कोई अच्छा इंटरफ़ेस है जो परिभाषित करने के लिए पहले से मौजूद है कि एक प्रकार चेकसम की गणना करने की क्षमता प्रदान करता है? – Jeff

+0

@jeff यह बहुत दुर्लभ है जिसकी आपको आवश्यकता है, लेकिन resharper जैसे टूल आपके लिए यह करेंगे –

+0

एक उदाहरण - ऑफ़लाइन आशावादी कैशिंग और/या विभिन्न प्रकार की वस्तुओं को लॉक करना (दूसरे शब्दों में, किसी तालिका में कोई तालिका नहीं है एक संस्करण आईडी के साथ टैग करने के लिए डेटाबेस)। क्लाइंट और सर्वर दोनों को हैश या चेकसम (जिसे आप इसे कॉल करेंगे) की गणना करने का एक तरीका चाहिए, जो कि अद्वितीय है, ताकि यदि क्लाइंट सर्वर पर एक पुराना संस्करण वापस भेजता है, तो सर्वर जानता है कि इसे सहेजने और उसे फेंकने के लिए अपवाद। इस उद्देश्य के लिए आप हैश/चेकसम की गणना कैसे करेंगे? – Jeff

1

हैश नहीं 1 से 1, आप कई विभिन्न मूल्यों है कि एक ही करने के लिए हैश हो सकता है कर रहे हैं मूल्य, लेकिन जो कॉम चाहिए बराबर के रूप में पारे। तो आप GetHashCode के संदर्भ में वास्तव में बराबर लागू नहीं कर सकते हैं। यही कारण है कि आपके पास हैश टेबल में टक्कर है, और हैश टेबल लुकअप में GetHashCode और Equals दोनों को कॉल (ओं) शामिल होना चाहिए।