Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Замечание
Это содержимое перепечатывается разрешением 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, если вызов оператора приведения приводит к преобразованию с потерями и контракт оператора не разрешает такие преобразования.
© Часть 2005, 2009 Корпорация Майкрософт. Все права защищены.
Перепечатан с разрешения Pearson Education, Inc. из Руководство по проектированию: Соглашения, идиомы и шаблоны для повторного использования библиотек .NET, 2-е издание Кшиштоф Чвалина и Брэд Абрамс, опубликованное 22 октября 2008 года Addison-Wesley Профессиональный в рамках серии разработки Microsoft Windows.