IComparable& IC之间有什么区别? IEquatable接口?

时间:2010-03-09 15:21:04

标签: c# interface icomparable iequatable

两个接口似乎都在比较对象是否相等,那么它们之间的主要区别是什么?

5 个答案:

答案 0 :(得分:177)

IEquatable测试两个对象是否相等。

IComparable对要比较的对象施加总排序。

例如,IEquatable会告诉您5不等于7. IComparable会告诉您5在7之前。

答案 1 :(得分:15)

IEquatable<T>表示平等。

IComparable<T>订购。

答案 2 :(得分:10)

除了Greg D的回答:

您可以实现IComparable而不为部分排序有意义的类实现IEquatable,并且非常肯定您希望消费者绘制推理,因为CompareTo()返回零,此不会暗示对象是相等的(除了排序目的之外的其他任何东西)。

答案 3 :(得分:7)

正如MSDN Page for IEquatable所述:

  

IComparable接口定义   CompareTo方法确定   。实例的排序顺序   实施类型。 IEquatable   interface定义了Equals方法,   这决定了平等   实现类型的实例。

EqualsCompareTo

答案 4 :(得分:0)

IComparable <T>定义了一种特定于类型的比较方法,该方法可用于对对象进行排序或排序。

IEquatable <T>定义了一种通用方法,可用于实现确定相等性的方法。


假设您有Person类

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();

但这会引发异常。

enter image description here

框架不知道如何对这些对象进行排序。您需要说明如何对实现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;
        }
    }
}