2016-05-09 6 views
10

लघु प्रश्नसी # में एक सरणी Hashing

कैसे एक Array के लिए GetHashCode लागू करने के लिए।

this.array[n] == otherObject.array[n] 

array में सभी n के लिए:

विवरण

मैं एक वस्तु है कि Equals ओवरराइड करता है, कि जाँच की है।

स्वाभाविक रूप से मैं पूरक GetHashCode लागू करना चाहिए। मैं अगर वहाँ नेट तरीका यह है सोच रहा था, या अगर मैं की तरह

hash = hash^array[n] 

स्पष्टीकरण अपने ही, कुछ को लागू करना चाहिए

मेरे वस्तु एक सरणी शामिल है, और मैं पर इच्छुक हूँ सरणी के तत्वों के लिए GetHashCode। सरणी समतुल्यता के लिए मेरा कोड उदाहरण के लिए है - जैसे कि मेरा प्रश्न कहता है लेकिन शायद मैं स्पष्ट नहीं था, मुझे GetHashCode में रुचि है (Equals नहीं)। मैं कहता हूँ मैं स्वाभाविक रूप से पूरक GetHashCode को लागू करना चाहिए, क्योंकि यह नेट की एक आवश्यकता (Dictionary आदि के लिए सही ढंग से कार्य करने के लिए) इस बार Equals ओवरराइड की गई है लागू करने के लिए है। धन्यवाद।

+0

जवाब पर एक नज़र पोस्ट किया है [यहां] (http://stackoverflow.com/a/7244729/833070)। दूसरे शब्दों में, आप अपने खुद के विभिन्नता को लागू करने या किसी अन्य उपकरण का उपयोग कर बेहतर कर रहे हैं, आप उपयोग नहीं कर सकते 'GetHashCode()' या 'बराबर()' किसी सरणी – Draken

+0

लिए क्या कर क्यों नहीं 'this.array [n]। बराबर (अन्य ऑब्जेक्ट.एरे [एन]) ''एन' के लिए? –

+1

आप समानता के लिए दो सरणियों की तुलना करना चाहते हैं, तो आप 'SequenceEqual' विस्तार –

उत्तर

4

है एक सरणी के तत्वों का उपयोग कर एक हैश कोड की गणना के लिए, आपको IStructuralEquatable को सरणी डाल सकता है और फिर GetHashCode(IEqualityComparer) विधि कॉल, में तत्वों के प्रकार के लिए एक comparer गुजर सरणी क्योंकि सरणी वर्ग स्पष्ट रूप से विधि को लागू करता है

(डाली आवश्यक है।)

उदाहरण के लिए, यदि आपके वस्तु एक int सरणी है, तो आप GetHashCode इस तरह लागू कर सकते हैं:

public override int GetHashCode() 
{ 
    return ((IStructuralEquatable)this.array).GetHashCode(EqualityComparer<int>.Default); 
} 

मामले में आप उत्सुक हैं, तो यहां आपको सरणी वर्ग GetHashCode विधि को लागू करता है (से है Reference Source):

internal static int CombineHashCodes(int h1, int h2) { 
    return (((h1 << 5) + h1)^h2); 
} 

int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { 
    if (comparer == null) 
     throw new ArgumentNullException("comparer"); 
    Contract.EndContractBlock(); 

    int ret = 0; 

    for (int i = (this.Length >= 8 ? this.Length - 8 : 0); i < this.Length; i++) { 
     ret = CombineHashCodes(ret, comparer.GetHashCode(GetValue(i))); 
    } 

    return ret; 
} 

आप देख सकते हैं, वर्तमान कार्यान्वयन केवल सरणी के अंतिम आठ तत्वों का उपयोग करता।

2

मैं सहमत नहीं हूँ आप स्वाभाविक रूप से एक सरणी पर GetHashCode को लागू करना चाहिए
आप हर बदलाव
साथ इसे अद्यतन या
मैं उड़
SequenceEquals का उपयोग करेगा पर सीधे तुलना होगा मक्खी पर यह गणना करने के लिए होगा डिफ़ॉल्ट समानता comparer ताकि आप भी

public bool Equals 

वस्तुओं में सरणी 0n को लागू करना चाहिए

0,123,

Enumerable.SequenceEqual
एक उदाहरण

public static void SequenceEqualEx1() 
{ 
    Pet pet1 = new Pet { Name = "Turbo", Age = 2 }; 
    Pet pet2 = new Pet { Name = "Peanut", Age = 8 }; 

    // Create two lists of pets. 
    List<Pet> pets1 = new List<Pet> { pet1, pet2 }; 
    List<Pet> pets2 = new List<Pet> { pet1, pet2 }; 

    bool equal = pets1.SequenceEqual(pets2); 

    Console.WriteLine(
     "The lists {0} equal.", 
     equal ? "are" : "are not"); 
} 
+2

ओपी लागू किया गया है एक वस्तु * शामिल है जो * एक सरणी पर बराबर होती है। उस ऑब्जेक्ट पर GetHashCode को लागू करना स्वाभाविक है। –

+0

@ माइकल लियू नहीं मैं इसे कैसे पढ़ता हूं। मैं एक ऑब्जेक्ट नहीं पढ़ रहा हूं जिसमें * एक सरणी है। मैं वस्तुओं के रूप में इसे पढ़ा * में * सरणी ओवरराइड के बराबर होती है this.array [n] == otherObject.array [n]। – Paparazzi

+1

क्यों में * सरणी एक वस्तु * एक बराबर विधि का संदर्भ देता है 'this.array' पड़ेगा? इसका मतलब यह होगा कि आपके पास ऑब्जेक्ट्स की एक सरणी है जिसमें बदले में सरणी होती है। –

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