IComparable और IEquatable इंटरफेस के बीच अंतर क्या है?


97

दोनों इंटरफेस समानता के लिए वस्तुओं की तुलना करते हैं, इसलिए उनके बीच प्रमुख अंतर क्या है?

जवाबों:


188

IEquatable परीक्षण करता है कि क्या दो वस्तुएं समान हैं।

IComparable तुलना की जा रही वस्तुओं पर कुल आदेश लागू करता है।

उदाहरण के लिए, IEquatableआपको बताएगा कि 5 7 के बराबर नहीं है। IComparableआपको बता दें कि 5 7 से पहले आता है।



10

ग्रेग डी के जवाब के अलावा:

आप उस वर्ग के लिए लागू IComparableकिए बिना लागू कर सकते हैं IEquatableजहां एक आंशिक आदेश समझ में आता है, और जहाँ आप निश्चित रूप से चाहते हैं कि उपभोक्ता केवल इस वजह से अनुमान लगा सकेCompareTo() शून्य लौटता है, इसका मतलब यह नहीं है कि ऑब्जेक्ट समान हैं (सॉर्टिंग उद्देश्यों के अलावा किसी भी चीज के लिए)।


10
यह एक विशेष मामले की तुलना में बहुत अधिक लगता है जैसे किसी वस्तु को IComparableठीक से लागू करने की तुलना में । आप एक सार्थक उदाहरण है, जहां के साथ आ सकते हैं CompareTo(…) == 0करता नहीं समानता का मतलब? मैं निश्चित रूप से नहीं कर सकता। वास्तव में, इंटरफ़ेस अनुबंध (MSDN के अनुसार) के लिए आवश्यक है कि CompareTo(…) == 0समानता का अर्थ है। इसे कुंद करने के लिए, आपके जैसे एक मामले में, एक विशेष Comparatorवस्तु का उपयोग करें , लागू न करेंIComparable
कोनराड रुडोल्फ

2
@ कोनराड - मैंने कई कैविएट का संकेत दिया - कि प्रकार IEquatable को लागू नहीं करता है (इसलिए स्पष्ट रूप से, प्रवर्तक एक समानता परीक्षण शामिल नहीं करना चाहता है), और यह कि ComparTo परिणाम का उपयोग छँटाई के लिए किया जाता है, समानता का मूल्यांकन करने के लिए नहीं । आप ऐसे प्रश्नों में भी आते हैं, जो समानता प्रासंगिक है (संदर्भ, मूल्य, "मनमानी" विशेषताओं को अनदेखा करते हुए - लंबाई में 500 पृष्ठों की एक नीली किताब, IComparable के उद्देश्यों के लिए लंबाई में 500 पृष्ठों की लाल किताब के लिए "बराबर" हो सकती है)
डेमियन_इन_अनबेलियर

4
आपका अंतिम वाक्य गलत है, और यह विशेष गलती है जिसे मैं इंगित करना चाहता था: IComparableयहां पूरी तरह से अनुचित है। आपको जो मिला है, वह एक विशेष ऑर्डर है जो केवल एक विशेष स्थिति में लागू होता है। ऐसी स्थितियों के लिए, एक सामान्य लागू IComparableकरना गलत है। यह वही है जो IComparerवहाँ के लिए हैं। उदाहरण के लिए, लोगों को सार्थक रूप से आदेश नहीं दिया जा सकता है। लेकिन उन्हें उनके वेतन, उनके जूते के आकार, उनके झाई की संख्या या उनके वजन के अनुसार आदेश दिया जा सकता है। इसलिए, हम IComparerइन सभी मामलों के लिए अलग-अलग लागू करेंगे ।
कोनराड रुडोल्फ

2
@ कोनराड रूडोल्फ: "शेड्यूल्ड ईवेंट" वर्ग के बारे में क्या है, जो किसी विशेष समय में "कुछ" करने वाला है? प्रकार का शब्दार्थ एक बहुत मजबूत प्राकृतिक शब्दार्थ क्रम आधारित होगा जब क्रिया होने वाली थी, लेकिन एक ही समय में अलग-अलग घटनाएं आसानी से हो सकती थीं। एक को मैन्युअल रूप से निर्दिष्ट IComparer के उपयोग की आवश्यकता हो सकती है, लेकिन मैं यह चाहूंगा कि कक्षा में निर्मित एक तुलनित्र अधिक सुविधाजनक होगा।
सुपरकाट

4
@ सुपरफ़ास्ट सुविधा महत्वपूर्ण है, लेकिन यह सब कुछ नहीं है। सुधार (जैसा कि, तार्किक स्थिरता) अधिक महत्वपूर्ण है और स्थैतिक प्रकार प्रणाली इस तार्किक स्थिरता को सत्यापित करने के लिए एक महत्वपूर्ण उपकरण है। आपके द्वारा कार्यान्वित किए गए इंटरफेस के दस्तावेज़ अनुबंध का उल्लंघन करके, आप टाइप सिस्टम को बदल रहे हैं। यह एक अच्छा विचार नहीं है, और मैं कभी भी इसकी सिफारिश नहीं करूंगा। ऐसी स्थितियों के लिए बाहरी तुलना का उपयोग करें।
कोनराड रुडोल्फ

7

जैसा कि IEDN से MSDN पेज पर कहा गया है :

IComparable इंटरफ़ेस CompareToविधि को परिभाषित करता है , जो कार्यान्वयन प्रकार के उदाहरणों के क्रम को निर्धारित करता है। IEquatable इंटरफ़ेस Equalsविधि को परिभाषित करता है , जो कार्यान्वयन प्रकार के उदाहरणों की समानता को निर्धारित करता है।

Equals बनाम CompareTo


2

IComparable <T> एक विशिष्ट प्रकार की तुलना विधि को परिभाषित करता है जिसका उपयोग वस्तुओं को क्रम या क्रमबद्ध करने के लिए किया जा सकता है।

IEquatable <T> एक सामान्यीकृत विधि को परिभाषित करता है जिसका उपयोग समानता को निर्धारित करने के लिए लागू करने के लिए किया जा सकता है।


मान लीजिए कि आपके पास व्यक्ति वर्ग है

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

Person p1 = new Person() { Name = "Person 1", Age = 34 };
Person p2 = new Person() { Name = "Person 2", Age = 31 };
Person p3 = new Person() { Name = "Person 3", Age = 33 };
Person p4 = new Person() { Name = "Person 4", Age = 26 };

List<Person> people = new List<Person> { p1, p2, p3, p4 };

इन वस्तुओं को सॉर्ट करने के लिए आप उपयोग कर सकते हैं people.Sort();

लेकिन यह एक अपवाद को फेंक देगा।

यहां छवि विवरण दर्ज करें

फ्रेमवर्क इन वस्तुओं को क्रमबद्ध करना नहीं जानता है। आपको यह बताने की आवश्यकता है कि कार्यान्वयन IComparableइंटरफ़ेस को कैसे सॉर्ट करना है।

public class Person : IComparable
{
    public string Name { get; set; }
    public int Age { get; set; }

    public int CompareTo(object obj)
    {
        Person otherPerson = obj as Person;
        if (otherPerson == null)
        {
            throw new ArgumentNullException();
        }
        else
        {
            return Age.CompareTo(otherPerson.Age);
        }
    }
}

यह सरणी को Sort()विधि के साथ ठीक से सॉर्ट करेगा ।


आगे दो वस्तुओं की तुलना करने के लिए आप Equals()विधि का उपयोग कर सकते हैं ।

var newPerson = new Person() { Name = "Person 1", Age = 34 };
var newPersonIsPerson1 = newPerson.Equals(p1);

यह वापस आ जाएगाfalse क्योंकि Equalsविधि को दो वस्तुओं की तुलना करने का तरीका नहीं पता है। इसलिए आपको IEquatableइंटरफ़ेस को लागू करने और रूपरेखा को बताने की आवश्यकता है कि तुलना कैसे करें। पिछले उदाहरण पर विस्तार से यह इस तरह दिखेगा।

public class Person : IComparable, IEquatable<Person>
{
    //Some code hidden

    public bool Equals(Person other)
    {
        if (Age == other.Age && Name == other.Name)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

1
इस बेहतरीन व्याख्या के लिए धन्यवाद। प्रश्न: IEquatableजेनेरिक का उपयोग क्यों करता है <Person>और IComparableनहीं करता है?
वीरवार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.