2012-03-11 7 views
5

मैं एक वर्ग Person है, यह IEquatable<Person> से बराबर है() विधि को लागू करता है (यह भी Object.Equals विधि ओवरराइड करता है, की सुविधा देता है अब के लिए विधि GetHashcode() पर ध्यान न दें)समानता कॉम्पैयर <T>। डीफॉल्ट गलतफहमी?

class Person : IEquatable<Person> 
{ 
    public string Name { get; set; } 

    public bool Equals(Person other) 
    { 
     return this.Name == other.Name; 
    } 
    public override bool Equals(object obj) 
    { 
     var person = obj as Person; 
     return person != null && person.Name == Name; 
    } 
} 

ठीक है, की सुविधा देता है शुरू:

Person p1 = new Person() { Name = "a" }; 
Person p2 = new Person() { Name = "a" }; 

List<Person> lst1 = new List<Person>() { p1 }; 
List<Person> lst2 = new List<Person>() { p2 }; 

इस लाइन के बारे में बात करने देता है:

bool b = lst1.SequenceEqual(lst2, EqualityComparer<Person>.Default); 

मैं इस पी समझने एक समस्या है कला:

EqualityComparer<Person>.Default 

मैंने सुना है अगर वर्ग IEquatable लागू कर रहा है कि EqualityComparer<Person>.Default की जाँच करेगा - यह Equals(Person other) विधि और नहीं Equals(object obj) ले जाएगा। यह मुक्केबाजी

enter image description here लेकिन

Equals(Person other) से बचने का लाभ के साथ या बिनाEqualityComparer<Person>.Default

(क्योंकि यह IEquatable को लागू है) तो क्या मुक्केबाजी के बारे में हम बात कर रहे हैं चलेंगे है ? वहाँ नहीं है!

bool b = lst1.SequenceEqual(lst2,EqualityComparer<Object>.Default); 

लेकिन मैं एक प्रोग्रामर हूँ:

केवल समय है कि Equals(object obj) चलेंगे जब है! मैं object कभी नहीं भेजूंगा जब यह वास्तव में Person होगा!

मुझे क्या याद आ रही है? मुझे EqualityComparer<Object>.Default के लाभ को समझने में परेशानी हो रही है। क्या कोई मुझे साबित करने के लिए एक उदाहरण दे सकता है कि मैं गलत हूं?

+0

आप क्या समझ नहीं सकते? 'IEqualityComparer डीफॉल्ट' को तत्काल करने का लाभ, या आप एक विशिष्ट तत्कालता क्यों चुन सकते हैं, या कुछ और? – thecoop

+0

यह इसके साथ या उसके साथ क्यों काम करता है, और मेरे पास टाइप –

+1

टाइप करने का कारण क्यों है, बॉक्सिंग केवल मूल्य प्रकारों के लिए होती है। चूंकि 'व्यक्ति' एक संदर्भ प्रकार है, इसलिए इस मामले में कोई मुक्केबाजी शामिल नहीं है। – thecoop

उत्तर

1

आप दूसरा पैरामीटर के रूप में null में पास या यदि आप सब पर एक दूसरा तर्क में उत्तीर्ण नहीं होते हैं (जो मूल रूप से एक ही है), SequenceEquals के कार्यान्वयन EqualityComparer<T>.Default ही फोन करेगा तो (इस देखने के लिए Enumerable डिकंपाइल)। यह बताता है कि आप एक अंतर क्यों नहीं देखते हैं कि आप EqualityComparer<T>.Default प्रदान करते हैं या नहीं।

तो अंत में आप एक समानता comparer EqualityComparer<T>.Default के अलावा अन्य उपयोग करना चाहते हैं दूसरा पैरामीटर केवल समझ में आता है।

+0

मैं कभी भी के साथ तुलना करने के लिए क्यों उपयोग करूंगा वास्तव में ? –

+0

आप अपने स्वयं के IEqualityComparer को लागू करना चाहते हैं, उदाहरण के लिए यदि आप इसे टी के लिए उपयोग करते हैं जो समानता को लागू करने के तरीके को लागू नहीं करता है। –

+0

मुझे केवल मूल्य प्रकार पर बताया गया था - इसलिए मुझे लगता है कि मुझे एक संरचना –

1

है कि आप IEqualityComparer<object>.Default में पारित कर सकते हैं, नेट 4.

अनिवार्य रूप से, एक IEqualityComparer<BaseType> इस्तेमाल किया जा सकता में जोड़ा जब भी एक IEqualityComparer<DerivedType> की आवश्यकता है, जहां DerivedType : BaseTypegeneric contravariance का प्रभाव है। चूंकि PersonObject से निकला है, इसका मतलब यह है कि का उपयोग कहीं भी किया जा सकता है जहां IEqualityComparer<Person> आवश्यक है।

+0

ऐसा इसलिए है क्योंकि इसका 'contravariant'। जब मैं एक व्यक्ति होता हूं तो मैं ऑब्जेक्ट तुलनाकर्ता का उपयोग क्यों करना चाहूंगा? इसके अलावा, मैंने सुना है कि इसका मुक्केबाजी से बचने का लाभ है। कौन सा मुक्केबाजी? कुछ ऐसा है: "यदि आपके पास Iequatable बराबर विधि है - मैं इसका उपयोग करूंगा, ऑब्जेक्ट नहीं। विधि विधि" .... वह कहां है? –

+1

इस विशेष उदाहरण में, सामान्य contravariance वास्तव में उपयोगी नहीं है, हालांकि ऐसी स्थितियां हैं जिनमें वास्तव में बहुत उपयोगी है। सिर्फ इसलिए कि आप कुछ करने में सक्षम हैं इसका मतलब यह नहीं है कि ऐसा करने के लिए यह सही या सही है। – thecoop

0

जवाब यहाँ है: http://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx

एक मूल्य के प्रकार के लिए, आप हमेशा IEquatable को लागू करने और बेहतर प्रदर्शन के लिए Object.Equals (वस्तु) ओवरराइड करना चाहिए। ऑब्जेक्ट। बॉक्स मूल्य मानता है और समानता के लिए दो मानों की तुलना करने के लिए प्रतिबिंब पर निर्भर करता है। आपके बराबर कार्यान्वयन और ऑब्जेक्ट के आपके ओवरराइड दोनों। एक्वाल्स को लगातार परिणाम लौटाएंगे।

यदि आप बराबर और GetHashCode ओवरराइड नहीं करते हैं, तो समानता कॉम्पैयर। डीफॉल्ट वास्तव में आपके लिए इसका ख्याल रखता है।

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