2009-11-14 149 views

回答

9

IComparable定義順序(小於,大於)。由它定義的方法是CompareTo可以確定兩個元素之間的順序。

IEquatable定義了相等性。它定義的方法是等於,它可以讓你確定兩個元素是否相等。

比較例,按年齡排序

public class Person : IComparable<Person> 
{ 
    public int Age { get; set; } 
    public int ID { get; set; } 

    public int CompareTo(Person other) 
    { 

     return Math.Sign(Age - other.Age); // -1 other greater than this 
              // 0 if same age 
              // 1 if this greater than other 
    } 
} 

排序用法:

[Test] 
public void SortTest() 
{ 
    var persons = new List<Person> 
         { 
          new Person { Age = 0 }, 
          new Person { Age = 2 }, 
          new Person { Age = 1 } 
         }; 

    persons.Sort(); 

    Assert.AreEqual(0, persons[0].Age); 
    Assert.AreEqual(1, persons[1].Age); 
    Assert.AreEqual(2, persons[2].Age); 
} 

平等例如用於通過ID識別人:

public class Person : IEquatable<Person> 
{ 
    public int Age { get; set; } 
    public int ID { get; set; } 

    public bool Equals(Person other) 
    { 
     return ID == other.ID; 
    } 
} 
+0

難道我們不能像STL那樣做「<」嗎? 'bool equals =!((a 2009-11-14 17:01:08

+0

如果你重載了operator <等等,但是請記住,並非所有的.NET語言(如VB.Net)都支持運算符重載,爲什麼框架不能依賴於此。另外有一個接口允許你將對象傳遞給接受該接口的任何方法。對您的類型一無所知的方法無法知道它有任何運算符重載。 – shf301 2009-11-14 17:15:59

+0

使用'Math.Sign'來實現'CompareTo' *真的非常糟糕。溢出/下溢FTW。 – 2013-01-18 16:18:19

2

如果您正在對IEnumerable<T>,進行排序,則使用IComparable<T>,如果比較兩個實例的相等性; IEquatable<T>

1

一般來說,任何排序的東西都會使用類的接口,如果可用的話,將使用類的接口.Net將應用默認排序,這可能是完全意想不到的。
如果你沒有定義一個默認值將被使用 - 如果你繼承的東西是IComparable那麼如果某個基類實現了這個,那麼排序順序將是基類定義的。

IEquatable定義了相等性,並讓您定義.Net如何確定類的實例是否與Equals方法相同。如果你沒有定義一個,那麼默認情況下,平等基於引用相等。這意味着,除非您將兩個引用與一個類的同一個實例進行比較,否則即使您希望它們相等,它們也不會相等。同樣,如果你從一個實現了接口的基類繼承而來,並且你沒有在你的類中自己實現它,你將會使用基類相等性計算。

一般來說,如果您打算將常見的.Net功能與它們結合使用,實施這些功能就很重要。例如,如果你使用載有()函數在您的類的集合,然後它會嘗試使用IEquatable接口

從MSDN:

的IEquatable <(中<(T>)>)接口 使用由通用對象集合 諸如字典<(中<(TKEY的, TValue>中)>),列表<(OF <(T>)>),並 鏈表<(中<(T>)> )當測試 在這樣的平等方法如 Contains,IndexOf,LastIndexOf和 刪除。對於可能存儲在 通用集合中的任何對象,應該執行 。

了IComparable <(中<(T>)>)接口 提供了一種用於訂購 泛型集合對象的成員強類型比較 方法。由於 這個,它通常不直接從開發者代碼調用 。相反, 它會自動方法 如List <(中 <(T>)>).. ::。排序()()(),並添加

調用。