2013-07-12 25 views
9

वैसे मैं एक छोटा सा एप्लीकेशन बनाने की कोशिश कर रहा हूं जो कुछ कर्मचारियों नाम, युग के साथ-साथ वेतन भी बचाता है। तो मैं क्रम में Dictionary उपयोग करने के लिए हर कर्मचारी के वेतन स्थापित करने का फैसला और मैं उस कोडशब्दकोश .ContainsKey हमेशा झूठी वापसी करता है

कोड

var employeeSalaryDictionary = new Dictionary<Employee, int>(); 
employeeSalaryDictionary.Add(new Employee { Name = "Chuck", Age = 37 }, 1000); 
employeeSalaryDictionary.Add(new Employee { Name = "Norris", Age = 37 }, 2000); 
employeeSalaryDictionary.Add(new Employee { Name = "Rocks", Age = 44 }, 3000); 

Employee employeeToFind = new Employee { Name = "Chuck", Age = 37 }; 
//or even 
Employee employeeToFind = new Employee { Name = "Chuck"}; 

//Always False... 
bool exists = employeeSalaryDictionary.ContainsKey(employeeToFind); 

कर्मचारी वर्ग

public class Employee 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 

हालांकि के साथ आया था के रूप में मैं बाहर या के रूप में टिप्पणी की विषय शीर्षक राज्य, .ContainsKey हमेशा मुझे False देता है हालांकि मैंने कोड में दिखाए गए दोनों तरीकों की कोशिश की।

+1

आपको अपने कर्मचारी वर्ग –

+0

के लिए समानताएं और GetHashCode ओवरराइड करना चाहिए, मुझे लगता है कि वस्तुओं की तुलना करने के तरीके के साथ कुछ करना है। चूंकि शब्दकोश में ऑब्जेक्ट्स और 'कर्मचारी टॉफ़िंड' में वस्तुएं वास्तव में अलग-अलग ऑब्जेक्ट्स हैं - उन्हें तुलना करने से तुलनात्मक रूप से झूठी –

उत्तर

18

न आप Dictionary निर्माता कि IEqualityComparer<T> में ले जाता है का उपयोग नहीं कर रहे हैं और आप पर कस्टम समानता लागू किए गए हों Employee कक्षा।

तो अभी शब्दकोश शब्दकोश संदर्भ के अनुसार कर्मचारियों की तुलना कर रहा है। जब आप new कर्मचारी होते हैं, तो आपके पास अलग-अलग संदर्भ है, भले ही उदा। नाम वही हो सकता है।

शायद आपके सबसे आसान तरीका आपके IEqualityComparer<Employee> को लागू करना होगा, जहां आप चुन सकते हैं कि कौन से सदस्यों को समानता तुलना के लिए उपयोग किया जाएगा, और इसे शब्दकोश के निर्माता के पास पास कर दिया जाएगा।

[संपादित करें] के रूप में वादा किया था, के टुकड़े:

//ReSharper's courtesy 
public sealed class NameAgeEqualityComparer : IEqualityComparer<Employee> 
{ 
    public bool Equals(Employee x, Employee y) 
    { 
     if (ReferenceEquals(x, y)) return true; 
     if (ReferenceEquals(x, null)) return false; 
     if (ReferenceEquals(y, null)) return false; 
     if (x.GetType() != y.GetType()) return false; 
     return string.Equals(x.Name, y.Name) && x.Age == y.Age; 
    } 

    public int GetHashCode(Employee obj) 
    { 
     unchecked 
     { 
      return ((obj.Name != null ? obj.Name.GetHashCode() : 0) * 397)^obj.Age; 
     } 
    } 
} 

और फिर:

var employeeSalaryDictionary = new Dictionary<Employee, int>(new NameAgeEqualityComparer()); 
employeeSalaryDictionary.Add(new Employee { Name = "Chuck", Age = 37 }, 1000); 
employeeSalaryDictionary.Add(new Employee { Name = "Norris", Age = 37 }, 2000); 
employeeSalaryDictionary.Add(new Employee { Name = "Rocks", Age = 44 }, 3000); 

Employee employeeToFind = new Employee { Name = "Chuck", Age = 37 }; 
bool exists = employeeSalaryDictionary.ContainsKey(employeeToFind); // true! 

पूर्णता के लिए, यहाँ-नाम ही comparer (भी ReSharper के सौजन्य से) है:

public sealed class NameEqualityComparer : IEqualityComparer<Employee> 
{ 
     public bool Equals(Employee x, Employee y) 
     { 
      if (ReferenceEquals(x, y)) return true; 
      if (ReferenceEquals(x, null)) return false; 
      if (ReferenceEquals(y, null)) return false; 
      if (x.GetType() != y.GetType()) return false; 
      return string.Equals(x.Name, y.Name); 
     } 

     public int GetHashCode(Employee obj) 
     { 
      return (obj.Name != null ? obj.Name.GetHashCode() : 0); 
     } 
    } 

लेकिन, जैसा कि आपने देखा है, आपको यह तय करना होगा कि जब आप एक शब्दकोश बनाते हैं तो आप तुलनात्मक कुंजी के लिए किस तुलनात्मक का उपयोग करेंगे। इसे बाद में बदला नहीं जा सकता ...

+0

लौटती है यह अच्छा है लेकिन क्या आप कोड स्निपेट जोड़कर अपना उत्तर अधिक समृद्ध बना सकते हैं कि मैं या कोई अन्य व्यक्ति जो इस प्रश्न को हल कर सकता है मेरे द्वारा पोस्ट किए गए कोड के अनुसार यह समस्या? –

+0

@RuneS निश्चित रूप से, मुझे विजुअल स्टूडियो को स्पूल करने के लिए एक सेकंड दें;) –

+0

@RuneS और किया गया। –

3

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

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