Overbelasting van operatoren
Notitie
Deze inhoud wordt opnieuw afgedrukt door toestemming van Pearson Education, Inc. van Framework Design Guidelines: Conventions, Idioms en Patterns for Reusable .NET Libraries, 2nd Edition. Die editie werd in 2008 gepubliceerd en het boek is sindsdien volledig herzien in de derde editie. Sommige informatie op deze pagina is mogelijk verouderd.
Met operator overbelaste operatoren kunnen frameworktypen worden weergegeven alsof ze ingebouwde taalprimitief zijn.
Hoewel toegestaan en nuttig in sommige situaties, moet de overbelasting van de operator voorzichtig worden gebruikt. Er zijn veel gevallen waarin overbelasting van operatoren is misbruikt, zoals wanneer frameworkontwerpers operators voor bewerkingen gaan gebruiken die eenvoudige methoden moeten zijn. Aan de hand van de volgende richtlijnen kunt u bepalen wanneer en hoe u overbelasting van operatoren gebruikt.
❌ VERMIJD het definiëren van operatoroverbelastingen, behalve in typen die moeten lijken op primitieve (ingebouwde) typen.
✔️ OVERWEEG operatoroverbelastingen te definiëren in een type dat zich als een primitief type moet voelen.
Bijvoorbeeld, System.String heeft operator==
en operator!=
gedefinieerd.
✔️ DO definieert overbelasting van operatoren in structs die getallen vertegenwoordigen (zoals System.Decimal).
❌ WEES NIET schattig bij het definiëren van overbelasting van operatoren.
Overbelasting van operatoren is handig in gevallen waarin het direct duidelijk is wat het resultaat van de bewerking zal zijn. Het is bijvoorbeeld logisch om een DateTimeDateTime
van elkaar af te trekken en een TimeSpan. Het is echter niet geschikt om de operator voor logische samenvoeging te gebruiken om twee databasequery's samen te stellen of om de shift-operator te gebruiken om naar een stream te schrijven.
❌ ZORG NIET voor overbelasting van operatoren, tenzij ten minste één van de operanden van het type is dat de overbelasting definieert.
✔️ DO overload operators op een symmetrische manier.
Als u bijvoorbeeld de operator==
overbelasting gebruikt, moet u ook de operator!=
. Op dezelfde manier moet u, als u de operator<
, moet ook overbelasten operator>
, enzovoort.
✔️ OVERWEEG methoden te bieden met beschrijvende namen die overeenkomen met elke overbelaste operator.
Veel talen bieden geen ondersteuning voor overbelasting van operatoren. Daarom wordt aanbevolen dat typen overbelastingsoperators een secundaire methode bevatten met een geschikte domeinnaam die equivalente functionaliteit biedt.
De volgende tabel bevat een lijst met operators en de bijbehorende beschrijvende methodenamen.
C#-operatorsymbool | Naam van metagegevens | Beschrijvende naam |
---|---|---|
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 voor overbelasting ==
operator ==
Overbelasting is behoorlijk ingewikkeld. De semantiek van de operator moet compatibel zijn met verschillende andere leden, zoals Object.Equals.
Conversieoperators
Conversieoperators zijn unaire operators die conversie van het ene type naar het andere toestaan. De operators moeten worden gedefinieerd als statische leden op de operand of het retourtype. Er zijn twee typen conversieoperators: impliciet en expliciet.
❌ GEEF GEEN conversieoperator op als een dergelijke conversie niet duidelijk wordt verwacht door de eindgebruikers.
❌ DEFINIEER GEEN conversieoperators buiten het domein van een type.
Bijvoorbeeld, Int32Doubleen Decimal zijn alle numerieke typen, terwijl dat DateTime niet zo is. Daarom moet er geen conversieoperator zijn om een Double(long)
te converteren naar een DateTime
. In dat geval heeft een constructor de voorkeur.
❌ GEEF GEEN impliciete conversieoperator op als de conversie mogelijk verlies kan veroorzaken.
Er mag bijvoorbeeld geen impliciete conversie van Double
naar zijn Int32
omdat Double
er een groter bereik is dan Int32
. Er kan een expliciete conversieoperator worden opgegeven, zelfs als de conversie mogelijk verliesbaar is.
❌ GOOI GEEN uitzonderingen van impliciete casts.
Het is erg moeilijk voor eindgebruikers om te begrijpen wat er gebeurt, omdat ze zich mogelijk niet bewust zijn van een conversie.
✔️ DO throw System.InvalidCastException if a call to a cast operator results in a lossy conversion and the contract of the operator does not allow lossy conversions.
© Delen 2005, 2009 Microsoft Corporation. Alle rechten voorbehouden.
Herdrukt door toestemming van Pearson Education, Inc. van Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition by Krzysztof Cwalina and Brad Abrams, published oct 22, 2008 by Addison-Wesley Professional als onderdeel van de Microsoft Windows Development Series.