程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#中自增、自減操作符重載是個怎麼回事兒

C#中自增、自減操作符重載是個怎麼回事兒

編輯:關於C語言
 在C++(C++培訓 )#(C#培訓中,重載自增自減操作符的語法並沒有什麼特殊之處,如下:

  public static SomeType Operator ++(SomeType some)

  {

  //具體實現

  }

  對於C#中的自增、自減操作符重載,無論前綴式或是後綴式,都統統只需要一個實現。也就是說無論我是這樣:someType++,還是這樣:++someType使用SomeType類型的自增重載,上述代碼中的實現都完全足夠完成任務。但是,前綴式++與後綴式++的行為畢竟不同,為什麼他們只需要一份同樣的實現就可以達到我們需要的目的了呢?

  另外,重載操作符的第一原則就是不應該改變操作數對象,而應該返回一個新的對象。否則不僅很可能會令那些使用我們的重載操作符的客戶產生困惑,而且更有可能會在調試代碼的時候出現意想不到的情況。那麼對於自增和自減操作符,我們是否也需要遵從此原則呢?我們又怎麼能在不修改操作數的情況下,對操作數自增或者自減呢?考慮如下的實現:

  class SomeType

  {

  public int Number

  {

  get; set;

  } public static SomeType Operator ++(SomeType s)

  {

  s.Number++; return s;

  }}

  這裡直接修改了操作數,並且直接返回了修改之後的操作數實例。

  當我們使用SomeType的前綴自增重載時:

  SomeType instance = new SomeType();

  instance.Number = 1;

  ++instance;

  如我們所預料的,操作符重載的方法體會被執行。而且instance也確實會按照理想的方式自增。我們再來看後綴自增操作:

  SomeType instance1 = new SomeType();

  instance1.Number = 1;

  SomeType instance2 = instance1++;

  不嚴謹的思維讓我們很容易認為,現在instance1的Number應該是2,而instance2的Number應該是1。但是,事不如人願,實際上現在的instance1和instance2的Number都是2!

  這到底是為什麼呢?

  其實是這樣的,相比其他我們司空見慣的重載操作符如+和-,編譯器會對重載的自增和自減操作符做一些額外的處理。在我們使用自增重載的時候,如++instance,++重載的方法體會被執行。然而我們沒有想到的是,在操作符重載方法被執行完成之後,instance會被自動賦值為操作符重載方法的返回值!而這一切都是編譯的時候就安排好了的。

  也就是說,如果SomeType是引用類型,則在執行完++instance語句之後,instatnce會指向那個被自增重載操作符方法所返回的對象實例。而如果SomeType是值類型,那麼instance會被按照C#值類型的標准賦值方式被重載操作符方法返回的值類型賦值,也就是逐字段賦值。

  當我們使用前綴式時,這一切都工作的很好。但是當我們使用後綴式時,問題就來了。在上面的使用後綴自增的例子裡,首先執行了instance1的自增操作,不過接下來,實際上是使用了instance1在執行自增操作前的一個副本(對於引用類型,使用引用的副本;對於值類型,使用整個結構的副本)來對instance2賦值的。

  因為我們在SomeType的自增重載的實現中,直接對操作數進行了修改,並且返回了原操作數。所以這樣一來,現在instance1和instance2現在指向的都是原操作數的實例,他們有同樣的Number也就不足為怪了。

  另一個SomeType的自增重載版本是這樣的:

  public static SomeType Operator ++(SomeType s)

  {

  var result = new SomeType();

  result.Number++;

  return result;

  }

  這個版本的實現遵循了“不應該在操作符重載中修改操作數”的原則。如果使用了這個版本的自增重載,在上述後綴式自增的例子中,會和我們預期的一樣:instance1的Number是2,而instance1的Number是1。

  我想,在很多情況下(特別是當SomeType是值類型時),這會是您希望得到的結果,也同樣是您代碼的消費者所預期的結果。

  好吧,對於自增和自減操作符,我們這樣理解可能會更容易一些:例如語句“instance2 = instance1++;”,並不是將自增重載方法的返回值賦值給左值instance2,而是將自增重載方法的返回值賦值給instance1。

  注意:自增重載方法的返回值是用來賦值給調用該重載方法的操作數的!(如果您有C++的背景,這一點可能不太容易接受)

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