Přetížení operátoru
Přetížení operátoru umožňuje, aby se typy architektur jeví jako předdefinování primitiv jazyka.
Přestože jsou v některých situacích povolená a užitečná, přetížení operátorů by se měla používat opatrně. Existuje mnoho případů, kdy bylo přetěžování operátorů zneužívána, například když návrháři architektury začali používat operátory pro operace, které by měly být jednoduchými metodami. Následující pokyny by vám měly pomoci při rozhodování, kdy a jak použít přetížení operátoru.
❌ VYHNĚTE se definování přetížení operátoru s výjimkou typů, které by měly vypadat jako primitivní (vestavěné) typy.
✔️ ZVAŽTE definování přetížení operátoru v typu, který by měl vypadat jako primitivní typ.
Například má a System.Stringoperator==
definované operator!=
.
✔️ DEFINUJTE přetížení operátoru ve strukturách, které představují čísla (například System.Decimal).
❌ PŘI definování přetížení operátoru BUĎTE ROZTOMILÍ.
Přetížení operátoru je užitečné v případech, kdy je okamžitě zřejmé, jaký bude výsledek operace. Například dává smysl, aby bylo možné odečíst DateTime od druhého DateTime
a získat TimeSpan. Není však vhodné použít operátor logického sjednotání ke sjednocení dvou databázových dotazů nebo použít operátor shift k zápisu do datového proudu.
❌ NEPOSKYTUJTE přetížení operátoru, pokud alespoň jeden z operandů není typu definující přetížení.
✔️ Operátory přetížení DO symetrickým způsobem.
Pokud například přetížíte operator==
, měli byste také přetížit operator!=
. Podobně pokud přetížíte operator<
, měli byste také přetížit operator>
, a tak dále.
✔️ ZVAŽTE poskytnutí metod s popisných názvů, které odpovídají jednotlivým přetíženým operátorem.
Mnoho jazyků nepodporuje přetížení operátoru. Z tohoto důvodu se doporučuje, aby typy, které přetěžují operátory, zahrnovaly sekundární metodu s příslušným názvem specifickým pro doménu, která poskytuje ekvivalentní funkce.
Následující tabulka obsahuje seznam operátorů a odpovídající popisné názvy metod.
Symbol operátoru jazyka C# | Název metadat | Popisný název |
---|---|---|
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 |
Přetěžování – operátor ==
Přetížení je operator ==
poměrně složité. Sémantika operátoru musí být kompatibilní s několika dalšími členy, například Object.Equals.
Operátory převodu
Operátory převodu jsou unární operátory, které umožňují převod z jednoho typu na jiný. Operátory musí být definovány jako statické členy na operandu nebo návratový typ. Existují dva typy operátorů převodu: implicitní a explicitní.
❌ NEPOSKYTOVAT operátor převodu, pokud koncový uživatel takový převod jasně neočekává.
❌ NEDEFINUJTE operátory převodu mimo doménu typu.
Například , Int32a jsou všechny Decimal číselné typy, zatímco DateTimeDoublenení. Proto by neměl být k dispozici žádný operátor převodu pro převod Double(long)
typu na DateTime
. V takovém případě je upřednostňovaný konstruktor.
❌ NEPOSKYTOVAT implicitní operátor převodu, pokud je převod potenciálně ztrátový.
Například by neměl být implicitní převod z Double
na , protože Double
má širší rozsah než Int32
Int32
. Explicitní operátor převodu lze poskytnuta i v případě, že převod může být ztrátový.
❌ NEVYHAZUJTE výjimky z implicitního přetypování.
Pro koncové uživatele je velmi obtížné pochopit, co se děje, protože nemusí vědět, že probíhá převod.
✔️ POKUD volání System.InvalidCastException operátoru přetypování vede ke ztrátě převodu a kontrakt operátoru neumožňuje ztrátové převody.
© Části 2005, 2009 Microsoft Corporation. All rights reserved.
Reprinted by permission of Pearson Education, Inc. from Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition by Krzysszof Cwa zachycuje a Brad Abrams, publikovaný 22. října 2008 společností Addison-Wesley Professional v rámci programu Microsoft Windows Development Series.