2009-11-08 17 views

उत्तर

30

परीक्षण करें कि बराबर दो अलग-अलग वस्तुएं समान हैंश कोड (विभिन्न मानों के लिए) हैं। जांचें कि गैर-बराबर वस्तुएं विभिन्न हैश कोड देती हैं, एक समय में एक पहलू/संपत्ति बदलती हैं। जबकि हैश कोड अलग होने के लिए नहीं हैं, तो आप एक ही हैश कोड देने के लिए गुणों के लिए अलग-अलग मान चुनने के लिए वास्तव में दुर्भाग्यपूर्ण होंगे, जब तक आपको कोई बग नहीं मिल जाता है।

+0

कुछ निर्मित प्रकारों के लिए एक ही हैश कोड प्राप्त करना काफी आसान है। उदाहरण के लिए नया प्वाइंट (1,1) .GetHashCode() और नया प्वाइंट (2,2) .GetHashCode() एक ही मान देता है ... – Guffa

+6

सिर्फ इसलिए कि किसी और का कोड अच्छी तरह से वितरित हैश मानों का उत्पादन करने में विफल रहता है इसका मतलब यह नहीं है कि यह आपके कोड के लिए एक अच्छा परीक्षण नहीं है। –

+0

@Pete: बिल्कुल। यही कारण है कि मैं अपने हैश कोड के लिए एक्सओआर का उपयोग नहीं करता ... –

0

मैं एक ज्ञात/अपेक्षित हैश की पूर्व-आपूर्ति करता हूं और गेटहाशकोड के परिणाम की तुलना करता हूं।

+7

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

+0

अच्छी कॉल, टिप्पणी के लिए धन्यवाद। – Myles

5

यह बराबर() के बराबर होगा। आप यह सुनिश्चित करना चाहते हैं कि दो ऑब्जेक्ट्स "समान" थे, कम से कम एक ही हैश कोड था। इसका मतलब है कि अगर एक्वाल्स() सत्य लौटाता है, तो हैश कोड भी समान होना चाहिए। जहां तक ​​उचित हैशकोड मान हैं, यह इस बात पर निर्भर करता है कि आप कैसे हैंशिंग।

+0

+1 - यह निश्चित रूप से परीक्षण करने के लिए एक बात है। वितरण भूल जाओ, लेकिन एक ही ऑब्जेक्ट में एक ही हैश कोड होना चाहिए। – TomTom

0

आप एक ही मूल्य के साथ अलग-अलग उदाहरण बनाते हैं और जांचते हैं कि उदाहरण के लिए GetHashCode समान मान देता है, और उसी उदाहरण पर बार-बार कॉल समान मान देता है।

हैश कोड के लिए यह एकमात्र आवश्यकता है। अच्छी तरह से काम करने के लिए हैश कोडों का निश्चित रूप से एक अच्छा वितरण होना चाहिए, लेकिन इसके लिए परीक्षण के लिए बहुत सारे परीक्षण की आवश्यकता है ...

3

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

 List<int> hashList = new List<int>(testObjectList.Count); 
     for (int i = 0; i < testObjectList.Count; i++) 
     { 
      hashList.Add(testObjectList[i]); 
     } 

     hashList.Sort(); 
     int differentValues = 0; 
     int curValue = hashList[0]; 
     for (int i = 1; i < hashList.Count; i++) 
     { 
      if (hashList[i] != curValue) 
      { 
       differentValues++; 
       curValue = hashList[i]; 
      } 
     } 

     Assert.Greater(differentValues, hashList.Count/2); 
9

Gallio/MbUnit v3.2 सुविधाजनक अनुबंध प्रमाणक जो GetHashCode() और IEquatable<T> के अपने कार्यान्वयन का परीक्षण करने में सक्षम हैं के साथ आता है। अधिक विशेष रूप से आपको EqualityContract और HashCodeAcceptanceContract से रुचि हो सकती है। अधिक जानकारी के लिए here, here और there देखें।

public class Spot 
{ 
    private readonly int x; 
    private readonly int y; 

    public Spot(int x, int y) 
    { 
    this.x = x; 
    this.y = y; 
    } 

    public override int GetHashCode() 
    { 
    int h = -2128831035; 
    h = (h * 16777619)^x; 
    h = (h * 16777619)^y; 
    return h; 
    } 
} 

तो फिर तुम इस तरह अपने अनुबंध सत्यापनकर्ता घोषित:

[TestFixture] 
public class SpotTest 
{ 
    [VerifyContract] 
    public readonly IContract HashCodeAcceptanceTests = new HashCodeAcceptanceContract<Spot>() 
    { 
    CollisionProbabilityLimit = CollisionProbability.VeryLow, 
    UniformDistributionQuality = UniformDistributionQuality.Excellent, 
    DistinctInstances = DataGenerators.Join(Enumerable.Range(0, 1000), Enumerable.Range(0, 1000)).Select(o => new Spot(o.First, o.Second)) 
    }; 
} 
0

उस वस्तु समानता की जाँच के अलावा hashcodes की समानता का अर्थ है, और हैश का वितरण काफी फ्लैट के रूप में यान Trevin ने सुझाव दिया है (यदि प्रदर्शन एक चिंता है), आप यह भी विचार करना चाहेंगे कि क्या होता है यदि आप ऑब्जेक्ट की संपत्ति बदलते हैं।

मान लीजिए कि आपका ऑब्जेक्ट एक शब्दकोश/हैशसेट में होने पर बदलता है। क्या आप चाहते हैं कि वस्तुएं (ऑब्जेक्ट) अभी भी सत्य हों? यदि ऐसा है तो आपका GetHashCode बेहतर परिवर्तनशील संपत्ति पर निर्भर नहीं था जो बदला गया था।

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