運算子多載
注意
此內容是由 Pearson Education, Inc. 授權轉載自架構設計指導方針:可重複使用 .NET 程式庫的慣例、慣用語和模式,第 2 版。 該版於 2008 年出版,該書自那以後已於第三版進行了全面修訂。 此頁面上的某些資訊可能已過期。
運算子多載可讓架構類型顯示為內建語言基本類型。
儘管運算子多載在某些情況下可用且相當實用,仍應謹慎使用。 運算子多載已有不少遭到濫用的情況,例如當架構設計工具開始針對應使用簡單方法的作業使用運算子時。 下列指導方針應該能協助您決定何時及如何使用運算子多載。
❌ 請避免定義運算子多載,除非在感覺像基本 (內建) 類型的類型中。
✔️ 請考慮在感覺像基本類型的類型中定義運算子多載。
例如,System.String 已定義 operator==
和 operator!=
。
✔️ 請在表示數字的結構 (例如 System.Decimal) 中定義運算子多載。
❌ 定義運算子多載時,請勿耍花招。
運算子多載在作業結果顯而易見的情況下很有用。 例如,能夠從另一個 DateTime
減去一個 DateTime 並取得 TimeSpan,十分合理。 但是,不適合使用邏輯聯合運算子來聯合兩個資料庫查詢,或使用移位運算子寫入串流。
❌ 除非至少有一個運算元是定義多載的類型,否則請勿提供運算子多載。
✔️ 請務必以對稱方式多載運算子。
例如,如果您多載 operator==
,則亦應該多載 operator!=
。 同樣地,如果您多載 operator<
,則亦應該多載 operator>
,依此類推。
✔️ 請考慮提供方法對應至每個多載運算子的自訂名稱。
許多語言不支援運算子多載。 基於這個理由,建議多載運算子的類型包含一個具有適當特定領域名稱的次要方法,以提供對等功能。
下表包含運算子清單和對應的自訂方法名稱。
C# 運算子符號 | 中繼資料名稱 | 易記名稱 |
---|---|---|
N/A |
op_Implicit |
To<TypeName>/From<TypeName> |
N/A |
op_Explicit |
To<TypeName>/From<TypeName> |
+ (binary) |
op_Addition |
Add |
- (binary) |
op_Subtraction |
Subtract |
* (binary) |
op_Multiply |
Multiply |
/ |
op_Division |
Divide |
% |
op_Modulus |
Mod or Remainder |
^ |
op_ExclusiveOr |
Xor |
& (binary) |
op_BitwiseAnd |
BitwiseAnd |
| |
op_BitwiseOr |
BitwiseOr |
&& |
op_LogicalAnd |
And |
|| |
op_LogicalOr |
Or |
= |
op_Assign |
Assign |
<< |
op_LeftShift |
LeftShift |
>> |
op_RightShift |
RightShift |
N/A |
op_SignedRightShift |
SignedRightShift |
N/A |
op_UnsignedRightShift |
UnsignedRightShift |
== |
op_Equality |
Equals |
!= |
op_Inequality |
Equals |
> |
op_GreaterThan |
CompareTo |
< |
op_LessThan |
CompareTo |
>= |
op_GreaterThanOrEqual |
CompareTo |
<= |
op_LessThanOrEqual |
CompareTo |
*= |
op_MultiplicationAssignment |
Multiply |
-= |
op_SubtractionAssignment |
Subtract |
^= |
op_ExclusiveOrAssignment |
Xor |
<<= |
op_LeftShiftAssignment |
LeftShift |
%= |
op_ModulusAssignment |
Mod |
+= |
op_AdditionAssignment |
Add |
&= |
op_BitwiseAndAssignment |
BitwiseAnd |
|= |
op_BitwiseOrAssignment |
BitwiseOr |
, |
op_Comma |
Comma |
/= |
op_DivisionAssignment |
Divide |
-- |
op_Decrement |
Decrement |
++ |
op_Increment |
Increment |
- (unary) |
op_UnaryNegation |
Negate |
+ (unary) |
op_UnaryPlus |
Plus |
~ |
op_OnesComplement |
OnesComplement |
多載運算子 ==
多載 operator ==
相當複雜。 運算子的語意必須與其他幾位成員相容,例如 Object.Equals。
轉換運算子
轉換運算子是一元運算子,可從一種類型轉換為另一種類型。 運算子必須定義為運算元或傳回型別上的靜態成員。 轉換運算子有兩種類型:隱含和明確。
❌ 如果終端使用者未明確預期此類轉換,請勿提供轉換運算子。
❌ 請勿在類型網域之外定義轉換運算子。
例如,Int32、Double 和 Decimal 都是數值型別,而 DateTime 不是。 因此,不應該有可將 Double(long)
轉換為 DateTime
的轉換運算子。 在這種情況下,建議使用建構函式。
❌ 如果轉換可能遺失,請勿提供隱含轉換運算子。
例如,不應該存在從 Double
到 Int32
的隱含轉換,因為 Double
的範圍比 Int32
大。 即使轉換可能遺失,也可以提供明確轉換運算子。
❌ 請勿從隱含轉換擲回例外狀況。
終端使用者難以理解發生什麼情況,因為他們可能不知道正在進行轉換。
✔️ 如果對轉換運算子的呼叫導致轉換遺失,而且運算子的合約不允許轉換遺失,請務必擲回 System.InvalidCastException。
Portions © 2005, 2009 Microsoft Corporation. 著作權所有,並保留一切權利。
獲 Pearson Education, Inc. 的授權再版,從 Krzysztof Cwalina 和 Brad Abrams 撰寫,並在 2008 年 10 月 22 日由 Addison-Wesley Professional 出版,作為 Microsoft Windows Development Series 一部份的 Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition 節錄。