注释
此内容由 Pearson Education, Inc. 的许可从 框架设计指南:可重用 .NET 库的约定、习惯和模式(第 2 版)重新打印。 该版于2008年出版,此后该书已于 第三版全面修订。 此页上的一些信息可能已过期。
运算符重载允许框架类型显示为内置语言基元。
尽管在某些情况下允许和有用,但应谨慎使用运算符重载。 在许多情况下,运算符重载被过度使用,比如说框架设计者开始将运算符用于应为简单方法的作用。 以下准则应帮助你确定何时以及如何使用运算符重载。
❌ 请避免定义运算符重载,除非在感觉像是基元(内置)类型的类型中。
✔️ 请考虑在某种类型中定义运算符重载,使其如同基元类型一般。
例如, System.String 具有 operator==
和 operator!=
定义。
✔️ DO 在表示数字(如 System.Decimal)的结构中定义运算符重载。
❌ 定义运算符重载时不要使用花哨的手法。
操作符重载在操作结果显而易见的情况下非常有用。 例如,能够从一个DateTime减去另一个DateTime
并得到TimeSpan是有意义的。 但是,以下操作是不恰当的:使用逻辑 union 运算符来联合两个数据库查询或使用 shift 运算符写入到流中。
❌ 除非至少有一个操作数属于定义重载的类型,否则请勿提供运算符重载。
✔️ 请确保以对称方式重载运算符。
例如,如果你重载了 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) 兼容。
转换运算符
转换运算符是一元运算符,允许从一种类型转换为另一种类型。 运算符必须定义为操作数或返回类型的静态成员。 有两种类型的转换运算符:隐式和显式。
❌ 如果最终用户未明确预期此类转换,请勿提供转换运算符。
❌ 请勿在类型域之外定义转换运算符。
例如,Int32Double和Decimal都是数值类型,而DateTime不是。 因此,不应使用转换运算符将 a Double(long)
转换为 a DateTime
。 在这种情况下,首选使用构造函数。
❌ 如果转换可能丢失,请勿提供隐式转换运算符。
例如,不应将Double
隐式转换为Int32
,因为Double
的范围比Int32
更大。 即使转换可能会有损失,也可以提供显式转换运算符。
❌ 请勿从隐式强制转换引发异常。
最终用户很难了解正在发生的事情,因为他们可能不知道正在发生转换。
✔️ 如果对强制转换运算符的调用导致有损转换,而该运算符的协定不允许有损转换,请务必引发 System.InvalidCastException。
部分内容 © 2005, 2009 Microsoft 公司。 保留所有权利。
获得皮尔逊教育公司许可后重印自 框架设计准则:可重用 .NET 库的约定、习惯和模式 ,由 Krzysztof Cwalina 和 Brad Abrams 编写,并作为微软 Windows 开发系列中的出版物之一,于 2008 年 10 月 22 日由 Addison-Wesley Professional 出版。