2016-12-11 146 views
3

如何C#定義+, - ,*,/運營商不具備重載運營商誰類?我已經實施了以下課程。在不重載任何操作符的情況下,所提到的操作符都可以工作,並且它們以我將要實現的方式工作! 下面的代碼:默認算術運算符

class Number 
{ 
    private float mDecimal; 
    public float Decimal 
    { 
     get { return mDecimal; } 
    } 

    private int mOrder; 
    public int Order 
    { 
     get { return mOrder; } 
    } 

    public Number(float dec, int pow) 
    { 
     mDecimal = dec; 
     mOrder = pow; 
    } 

    public Number Power(Number number) 
    { 
     throw new NotImplementedException(); 
    } 

    public static implicit operator Number(float num) 
    { 
     int pow = 0; 
     while (num > 1000) 
     { 
      num *= 0.1f; 
      ++pow; 
     } 

     return new Number(num, pow); 
    } 

    public static implicit operator float(Number num) 
    { 
     float result = num.mDecimal; 
     for (int i = 0; i < num.mOrder; ++i) 
      result *= 10; 
     return result; 
    } 
} 

現在把帳戶這一塊的用法碼:

Number n1 = 5; 
Number n2 = 10; 
Number n3 = n1 + n2; 

N3計算結果爲15!這也會發生在其他操作員身上!

+5

這是因爲你已經定義了隱式運算符float,所以'+'運算符會隱式地將你的值從'Number'轉換爲'float'('System.Single'),執行加法,然後轉換回來。 – Dai

+1

難道你甚至不嘗試在隱式運算符中放置一個斷點,這是唯一可能的原因嗎? – Andrew

+0

@Andrew我是c#的新手。我的背景是C++,它不能隱式地處理這種情況。所以不知道類型,因爲**數字**可以轉換爲浮點數,它使用浮點數?我爲另一個自定義類放置了其他轉換運算符,但它再次使用了浮點運算符。編譯器如何選擇要提供算術運算符的轉換? – Klaus

回答

6

n3 = n1 + n2如下評價:

  1. 首先,候選運營商的列表被確定,其中包括用戶定義的任何過載(ECMA-334, section 14.2.4)。沒有適用,所以候選運算符集合成爲預定義的二元運算符+。如果你定義了你自己的operator+(Number, Number)這就是它被選中的地方。 (你也許想實現它以防止背部和往復轉換舍入誤差。)
  2. 現在重載踢確定哪些+實施應使用(第14.4.2)。這可能是C#規範中最複雜的部分,但我們不需要深入研究 - 我們需要的是在選擇適當的過載(14.4.2.1)時應用隱式轉換的知識。對於準確的規則,您還需要閱讀第13.4節關於用戶定義的轉換。
  3. 語言治療上的用戶定義的隱式轉換,即使內置轉換的基礎上。在這種情況下,因爲有一個隱式轉換從Numberfloat,爲+的唯一人選重載決議後剩下的就是float operator +(float, float)與隱式轉換,讓被調用。
  4. 所得float然後隱式地通過使用其它操作者的轉換爲Number。請注意,即使沒有這個,你仍然會得到一個float加法,結果不會轉換回來。編譯器實際上並沒有「提升」操作符,但效果大致相同(提升的確發生在值類型的可爲空的版本上,但這是另一回事)。

當混合有隱式轉換類型,事情變得棘手。重載解析很難做正確的事情,並且規則是明確的,但即使如此,也很難看出何時涉及到轉換,因此不要過度使用隱式轉換運算符。顯式轉換需要更多的擊鍵次數,但是告訴哪個運算符最終被調用也更容易。當你最初開發這個類型時,這當然是真實的,所以你可以檢查你還沒有實現哪些運算符(但是出於性能或精度原因需要)。

+0

這正是一種可以從多種方式中受益的答案。 – Klaus