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.

Zie ook