比較子的重載

來源:互聯網
上載者:User
2. 比較子的重載

C#中有6個比較子,它們分為3對:

●       == 和 !=

●       > 和 <

●       >= 和 <=

C#要求成對重載比較子。如果重載了==,也必須重載!=,否則會產生編譯錯誤。另外,比較子必須返回bool類型的值。這是它們與算術運算子的根本區別。兩個數相加或相減的結果,理論上取決於數的類型。而兩個Vector的相乘會得到一個標量。另一個例子是.NET基類System.DateTime,兩個DateTime執行個體相減,得到的結果不是DateTime,而是一個System.TimeSpan執行個體,但比較運算得到的如果不是bool類型的值,就沒有任何意義。

注意:

在重載==和!=時,還應重載從System.Object中繼承的Equals()和GetHashCode()方法,否則會產生一個編譯警告。原因是Equals()方法應執行與==運算子相同的相等邏輯。

除了這些區別外,重載比較子所遵循的規則與算術運算子相同。但比較兩個數並不像想象的那麼簡單,例如,如果比較兩個對象引用,就是比較儲存物件的記憶體位址。比較子很少進行這樣的比較,所以必須編寫運算子,比較對象的值,返回相應的布爾結果。下面給Vector結構重載==和!=運算子。首先是==的執行代碼:

      public static bool operator = = (Vector lhs, Vector rhs)

      {

         if (lhs.x = = rhs.x && lhs.y = = rhs.y && lhs.z = = rhs.z)

            return true;

         else

            return false;

      }

這種方式僅根據向量組成部分的值,來對它們進行等於比較。對於大多數結構,這就是我們希望的,但在某些情況下,可能需要仔細考慮等於的含義,例如,如果有嵌入的類,是應比較對同一個對象的引用(淺度比較),還是應比較對象的值是否相等(深度比較)?

注意:

不要通過調用從System.Object中繼承的Equals()方法的執行個體版本,來重載比較子,如果這麼做,在objA是null時計算(objA==objB),這會產生一個異常,因為.NET運行庫會試圖計算null.Equals(objB)。採用其他方法(重寫Equals()方法,調用比較子)比較安全。

還需要重載運算子!=,採用的方式如下:

      public static bool operator != (Vector lhs, Vector rhs)

      {

      return ! (lhs == rhs);

      }

像往常一樣,用一些測試代碼檢查重寫方法的工作情況,這次定義3個Vector對象,並進行比較:

      static void Main()

      {

         Vector vect1, vect2, vect3;

         vect1 = new Vector(3.0, 3.0,–10.0);

         vect2 = new Vector(3.0, 3.0,–10.0);

         vect3 = new Vector(2.0, 3.0, 6.0);

         Console.WriteLine("vect1= =vect2 returns " + (vect1= =vect2));

         Console.WriteLine("vect1= =vect3 returns " + (vect1= =vect3));

         Console.WriteLine("vect2= =vect3 returns " + (vect2= =vect3));

         Console.WriteLine();

         Console.WriteLine("vect1!=vect2 returns " + (vect1!=vect2));

         Console.WriteLine("vect1!=vect3 returns " + (vect1!=vect3));

         Console.WriteLine("vect2!=vect3 returns " + (vect2!=vect3));

      }

編譯這些代碼(下載代碼中的Vectors3.cs),會得到一個編譯器警告,因為我們沒有為Vector重寫Equals(),對於本例,這是不重要的,所以忽略它。

csc Vectors3.cs

Microsoft (R) Visual C# 2005 Compiler version 8.00.50215.33

for Microsoft (R) Windows (R) Framework version 2.0.50215

Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.

 

Vectors3.cs(5,11): warning CS0660: 'Wrox.ProCSharp.OOCSharp.Vector' defines

       operator = = or operator != but does not override Object.Equals(object o)

Vectors3.cs(5,11): warning CS0661: 'Wrox.ProCSharp.OOCSharp.Vector' defines

        operator = = or operator != but does not override Object.GetHashCode()

在命令列上運行該樣本,產生如下結果:

Vectors3

vect1= =vect2 returns True

vect1= =vect3 returns False

vect2= =vect3 returns False

 

vect1!=vect2   returns False

vect1!=vect3    returns True

vect2!=vect3    returns True

3. 可以重載的運算子

並不是所有的運算子都可以重載。可以重載的運算子如表5-5所示。

表 5-5

類    別

運 算 符

限    制

算術二元運算子

+, *, /, –, %

算術一元運算子

+, –, ++, ––

按位二元運算子

&, |, ^, <<, >>

按位一元運算子

!, ~, true, false

true和false運算子必須成對重載

比較子

==, !=, >=, <, <=, >

必須成對重載

賦值運算子

+=,–=,*=,/=,>>=,<<=,%=

,&=,|=,^=

不能顯式重載這些運算子,在重寫單個運算子如+,–,%等時,它們會被隱式重寫

索引運算子

[]

不能直接重載索引運算子。第2章介紹的索引器成員類型允許在類和結構上支援索引運算子

資料類型轉換運算子

()

不能直接重載資料類型轉換運算子。使用者定義的資料類型轉換(本章的後面介紹)允許定義定製的資料類型轉換

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.