C#筆記 – 操作符方法
操作符****重載
- CLR對操作符的含義一無所知,但規定了語言如何公開操作符重載的方法
-
需要是public static的
-
需要包含operator關鍵字以及對應的操作符符號
-
比如 + 操作符重載
-
public sealed class Complex { public static Complex operator+(Complex c1, Complex c2) { return null; } } -
.method public hidebysig specialname static class CLR_Ch8.Complex op_Addition(class CLR_Ch8.Complex c1, class CLR_Ch8.Complex c2) cil managed { // 程式碼大小 7 (0x7) .maxstack 1 .locals init (class CLR_Ch8.Complex V_0) IL_0000: nop IL_0001: ldnull IL_0002: stloc.0 IL_0003: br.s IL_0005 IL_0005: ldloc.0 IL_0006: ret } // end of method Complex::op_Addition -
編譯器為名為op_Addition的方法生成元數據方法定義項,並設置了specialname標志
-
C#編譯器在看到 + 操作符後,會檢查是否有一個操作數的類型定義了名為 op_Addition的specialname方法
- 如果方法存在,且參數兼容於操作數的類型,就生成調用該方法的代碼
-
-
C#一元操作符及相容CLS方法名
-
C#操作符 特殊方法名 相容於CLS的方法名 + op_UnaryPlus Plus - op_UnaryNegation Negate ! op_LogicalNot Not ~ op_OnesComplement OnesComplement ++ op_Increment Increment — op_Decrement Decrement (無) op_True IsTrue{ get; } (無) op_False IsFalse{ get; }
-
-
C#二元操作符及相容CLS方法名
-
C#操作符 特殊方法名 相容於CLS的方法名 + op_Addition Add - op_Subtraction Subtract * op_Multiply Multiply / op_Division Divide % op_Modulus Mod & op_BitwiseAnd BitwiseAnd | op_BitwiseOr BitwiseOr ^ op_ExclusiveOr Xor << op_LeftShift LeftShift >> op_RightShift RightShift == op_Equality Equals != op_Inequality Equals < op_LessThan Compare > op_GreaterThan Compare <= op_LessThanOrEqual Compare >= op_GreaterThanOrEqual Compare
-
-
轉換操作符
- 如果源對象和目標都是編譯器識別的基元類型,編譯器自己就知道如何生成轉換對象所需的代碼
- 如果源對象或目標不是編譯器識別的基元類型,編譯器會生成代碼,要求CLR執行轉換(強制轉型)
- CLR會檢查源對象類型和目標類型是不是相同
- 但是如果要把一個類型轉換成完全不同的類型,就需要定義相關的轉換方法
-
這個類型要有一些成員:
- 接收一個參數的公共構造器,讓參數類型隱式轉換自己
- 無參的公共實例方法,把自己顯式轉換成其他類型
- 具體的轉換操作符重載方法
- 必須是public static
- 參數類型和返回類型二者必有其一與定義轉換方法的類型相同
- 隱式轉換方法:public static implict operator 目標類型(源類型)
- 只有在轉換不損失精度的情況下可以定義
- 顯式轉換方法:public static explict operator 目標類型(源類型)
- 如果轉換會損失精度,需要定義顯式轉換
-
C#
-
public sealed class Rational { public Rational(int num) { } public Rational(float num) { } public int ToInt() { return default; } public float ToFloat() { return default; } //int/float 隱式轉型至 Rational public static implicit operator Rational(int num) { return new Rational(num); } public static implicit operator Rational(float num) { return new Rational(num); } //Rational 顯式轉型 int/float public static explicit operator int(Rational r) { return r.ToInt(); } public static explicit operator float(Rational r) { return r.ToFloat(); } }
-
-
metadata
-

- C#編譯器檢測到代碼的轉型後,會生成IL來調用定義好的轉換操作符方法
- 如果代碼正使用某類型對象,但實際期望是另一個類型,編譯器會查找能執行這種轉換的隱式轉換操作符方法,並在IL中生成調用代碼
- 如果編譯器看到代碼存在顯式轉換,就會查找能行這種轉換的「隱式/顯式」轉換操作符方法,如果找到一個,就生成IL調用
- 使用C#的as 或 is操作符時,永遠不會調用這些定義的轉換方法
參考書目
- 《CLR via C#》(第4版) Jeffrey Richter