程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Effective C#原則26:用IComparable和IComparer實現對象的順序關系(1)

Effective C#原則26:用IComparable和IComparer實現對象的順序關系(1)

編輯:關於C語言

你的類型應該有一個順序關系,以便在集合中描述它們如何存儲以及排 序。.Net框架為你提供了兩個接口來描述對象的順序關系:IComparable 和 IComparer。IComparable 為你的類定義了自然順序,而實現IComparer接口的類 可以描述其它可選的順序。你可以在實現接口時,定義並實現你自己關系操作符 (<,>,<=,>=),用於避免在運行時默認比較關系的低效問題。這 一原則將討論如何實現順序關系,以便.Net框架的核心可以通過你定義的接口對 你的類型進行排序。這樣用戶可以在些操作上得更好的效率。

IComparable接口只有一個方法:CompareTo(),這個方法沿用了傳統的C 函數庫裡的strcmp函數的實現原則:如果當前對象比目標對象小,它的返回值小 於0;如果相等就返回0;如果當前對象比目標對象大,返回值就大於0。 IComparable以System.Object做為參數,因此在使用這個函數時,你須要對運行 時的對象進行檢測。每次進行比較時,你必須重新解釋參數的類型:

public struct Customer : IComparable
{
  private readonly string _name;
 public Customer( string name )
 {
  _name = name;
 }
 #region IComparable Members
 public int CompareTo( object right )
 {
   if ( ! ( right is Customer ) )
   throw new ArgumentException( "Argument not a customer",
    "right" );
  Customer rightCustomer = ( Customer )right;
   return _name.CompareTo( rightCustomer._name );
 }
  #endregion
}

關於實現比較與IComparable接口的一致性有 很多不太喜歡的地方,首先就是你要檢測參數的運行時類型。不正確的代碼可以 用任何類型做為參數來調用CompareTo方法。還有,正確的參數還必須進行裝箱 與拆箱後才能提供實際的比較。每次比較都要進行這樣額外的開銷。在對集合進 行排序時,在對象上進行的平均比較次數為N x log(N),而每次都會產生三次裝 箱與拆箱。對於一個有1000個點的數組來說,這將會產生大概20000次的裝箱與 拆箱操作,平均計算:N x log(n) 有7000次,每次比較有3次裝箱與拆箱。因此 ,你必須自己找個可選的比較方法。你無法改變IComparable.CompareTo()的定 義,但這並不意味著你要被迫讓你的用戶在一個弱類型的實現上也要忍受性能的 損失。你可以重載CompareTo()方法,讓它只對Customer 對象操作:

public struct Customer : IComparable
{
  private string _name;
 public Customer( string name )
  {
  _name = name;
 }
 #region IComparable Members
 // IComparable.CompareTo()
 // This is not type safe. The runtime type
 // of the right parameter must be checked.
 int IComparable.CompareTo( object right )
 {
  if ( ! ( right is Customer ) )
   throw new ArgumentException( "Argument not a customer",
     "right" );
  Customer rightCustomer = ( Customer ) right;
  return CompareTo( rightCustomer );
 }
 // type-safe CompareTo.
 // Right is a customer, or derived from Customer.
 public int CompareTo( Customer right )
 {
  return _name.CompareTo( right._name );
 }
  #endregion
}

現在,IComparable.CompareTo()就是一個隱 式的接口實現,它只能通過IComparable 接口的引用才能調用。你的用戶則只能 使用一個類型安全的調用,而且不安全的比較是不可能訪問的。下面這樣無意的 錯誤就不能通過編譯了:

Customer c1;
Employee e1;
if ( c1.CompareTo( e1 ) > 0 )
 Console.WriteLine( "Customer one is greater" );

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved