Condividi tramite


Sovraccarico degli operatori

Annotazioni

Questo contenuto viene ristampato con il permesso di Pearson Education, Inc. da Framework Design Guidelines: Conventions, Idioms e Pattern per Librerie .NET Riutilizzabili, 2a Edizione. Tale edizione è stata pubblicata nel 2008 e il libro è stato completamente rivisto nella terza edizione. Alcune informazioni in questa pagina potrebbero non essere aggiornate.

Il sovraccarico degli operatori permette ai tipi di framework di apparire come se fossero primitive del linguaggio predefinite.

Anche se consentito e utile in alcune situazioni, gli overload degli operatori devono essere usati con cautela. Esistono molti casi in cui l'overload degli operatori è stato abusato, ad esempio quando i progettisti di framework hanno iniziato a usare gli operatori per le operazioni che devono essere metodi semplici. Le linee guida seguenti consentono di decidere quando e come usare l'overload degli operatori.

❌ EVITARE di definire gli overload degli operatori, ad eccezione dei tipi che devono essere simili ai tipi primitivi (predefiniti).

✔️ CONSIDERARE la definizione di overload degli operatori in un tipo che dovrebbe somigliare a un tipo primitivo.

Ad esempio, System.String ha operator== e operator!= definito.

✔️ DO definisce gli overload degli operatori in struct che rappresentano numeri ,ad esempio System.Decimal.

❌ NON essere carino quando si definiscono gli overload degli operatori.

L'overload degli operatori è utile nei casi in cui è immediatamente ovvio quale sarà il risultato dell'operazione. Ad esempio, è opportuno essere in grado di sottrarre uno DateTime dall'altro DateTime e ottenere un oggetto TimeSpan. Non è tuttavia opportuno usare l'operatore di unione logica per unire due query di database o usare l'operatore shift per scrivere in un flusso.

❌ NON fornire overload degli operatori, a meno che almeno uno degli operandi sia del tipo che definisce l'overload.

✔️ Sovraccaricate gli operatori in modo simmetrico.

Ad esempio, se si esegue l'overload di operator==, è necessario eseguire anche l'overload di operator!=. Analogamente, se si sovraccarica il operator<, è necessario sovraccaricare anche il operator>, e così via.

✔️ VALUTARE la possibilità di fornire metodi con nomi descrittivi che corrispondono a ogni operatore di sovraccarico.

Molti linguaggi non supportano l'overload degli operatori. Per questo motivo, è consigliabile che i tipi che sovraccaricano gli operatori includano un metodo alternativo con un nome appropriato specifico del dominio che fornisca funzionalità equivalenti.

La tabella seguente contiene un elenco di operatori e i nomi amichevoli dei metodi corrispondenti.

Simbolo dell'operatore C# Nome dei metadati Nome amichevole
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

Sovraccarico operatore ==

Il sovraccarico operator == è piuttosto complicato. La semantica dell'operatore deve essere compatibile con diversi altri membri, ad esempio Object.Equals.

Operatori di conversione

Gli operatori di conversione sono operatori unari che consentono la conversione da un tipo a un altro. Gli operatori devono essere definiti come membri statici nell'operando o nel tipo restituito. Esistono due tipi di operatori di conversione: impliciti ed espliciti.

❌ NON fornire un operatore di conversione se tale conversione non è chiaramente prevista dagli utenti finali.

❌ NON definire gli operatori di conversione al di fuori del dominio di un tipo.

Ad esempio, Int32, Doublee Decimal sono tutti tipi numerici, mentre DateTime non è . Pertanto, non deve essere presente alcun operatore di conversione per convertire un oggetto Double(long) in un oggetto DateTime. Un costruttore è preferibile in questo caso.

❌ DO NOT fornire un operatore di conversione implicito se la conversione è potenzialmente in perdita.

Ad esempio, non deve essere presente una conversione implicita da Double a Int32 perché Double ha un intervallo più ampio di Int32. È possibile specificare un operatore di conversione esplicito anche se la conversione è potenzialmente in perdita.

❌ NON generare eccezioni dai cast impliciti.

È molto difficile per gli utenti finali capire cosa sta accadendo, perché potrebbero non essere consapevoli che si sta verificando una conversione.

✔️ GENERARE un'eccezione System.InvalidCastException se una chiamata a un operatore cast comporta una conversione con perdita di dati e il contratto dell'operatore non consente conversioni con perdita di dati.

© Porzioni 2005, 2009 Microsoft Corporation. Tutti i diritti riservati.

Ristampato dall'autorizzazione di Pearson Education, Inc. da Framework Design Guidelines: Conventions, Idioms e Patterns for Reusable .NET Libraries, 2nd Edition di Krzysztof Cwalina e Brad Abrams, pubblicato il 22 ottobre 2008 da Addison-Wesley Professional come parte della Serie di sviluppo di Microsoft Windows.

Vedere anche