Share via


運算子多載

注意

此內容是由 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

轉換運算子

轉換運算子是一元運算子,可從一種類型轉換為另一種類型。 運算子必須定義為運算元或傳回型別上的靜態成員。 轉換運算子有兩種類型:隱含和明確。

❌ 如果終端使用者未明確預期此類轉換,請勿提供轉換運算子。

❌ 請勿在類型網域之外定義轉換運算子。

例如,Int32DoubleDecimal 都是數值型別,而 DateTime 不是。 因此,不應該有可將 Double(long) 轉換為 DateTime 的轉換運算子。 在這種情況下,建議使用建構函式。

❌ 如果轉換可能遺失,請勿提供隱含轉換運算子。

例如,不應該存在從 DoubleInt32 的隱含轉換,因為 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 節錄。

另請參閱