4

Feb

C# tips and tricks: conversione implicita ed esplicita

Ciao a tutti,

 

questo è il primo appuntamento di una serie di post dove ho pensato di ripassare alcune cose riguardanti sia il linguaggio C# ma anche il .NET Framework che, a mio avviso, possono risultare “comodi” da conoscere.

Con la parola conversione viene indicata il passaggio di un tipo (per esempio un int) ad un altro. Questa conversione può avvenire in vari modi, ma quelli analizzati in questo post sono solo il tipo implicito ed esplicito. Per conversione implicita si intende quando il passaggio da un tipo ad un altro avviene senza specificare nessuna sintassi particolare, proprio perché, da qualche parte, viene istruito il compilatore che quella conversione può avvenire in maniera sicura. Vediamo un esempio:

   1: int i = 20;
   2: double db = i;

in questo esempio stiamo convertendo un tipo int in un tipo double senza specificare niente e questo è fattibile perché la conversione non causa nessuna perdita di dati dopo la conversione. Il tutto è applicabile anche ai tipi riferimento: infatti una istanza della classe A che implementa la classe B può essere convertita in maniera implicita in una istanza della classe B nello stesso modo:

   1: HttpClient client = new HttpClient();
   2: object obj = client; //HttpClient deriva dalla classe object
   3: IDisposable d = client; //Stessa cosa vale per le interfacce, infatti HttpClient implementa la IDisposable

 

Siccome il linguaggio C# è di tipo “Type safety” il compilatore ci “protegge” da conversione implicite non sicure, quindi quando vogliamo eseguire una conversione dove potenzialmente ci potrebbero essere problemi legati alla perdita di dati e/o di incompatibilità tra i tipi, ci viene in aiuto la conversione esplicita, ovvero tramite una particolare sintassi “forziamo” il compilatore ad eseguire lo stesso quella conversione:

   1: double db = 215.9;
   2: int a = (int) db; //la variabile "a" sarà uguale a 215

Come possiamo vedere dall’esempio sopra indicato, durante la conversione c’è stata una perdita di dati.

Una cosa molto utile del linguaggio C# è la possibilità di definire, a livello di classe, la logica di conversione implicita ed esplicita tramite le keyword implicit operator e explicit operator. Bisogna ricordarsi che questi due metodi devono essere sempre static e come unico parametro devono accettare il tipo stesso!

Vediamo un esempio:

   1: public class Money
   2:   {
   3:       public decimal Amount { get; set; }
   4:  
   5:       public Money(decimal amount)
   6:       {
   7:           Amount = amount;
   8:       }
   9:  
  10:       public static implicit operator decimal(Money money)
  11:       {
  12:           return money.Amount;
  13:       }
  14:       
  15:       public static explicit operator int(Money money)
  16:       {
  17:           return (int)money.Amount;
  18:       }
  19:  
  20:   }

Grazie a queste due definizioni, ho istruito il compilatore che posso castare in maniera sicura l’istanza del mio tipo Money in un decimal, potendo così scrivere

   1: Money money = new Money(32.5M);
   2: decimal db = money; //db in questo caso varrà quanto il valore passato nel costruttore

Inoltre avendo dichiarato anche la conversione esplicita è possibile scrivere anche in questo modo in quanto la logica di conversione è tutta nel metodo della mia classe:

   1: Money money = new Money(41.9M);
   2: int i = (int)money; //la variabile i varrà 41

C# è un linguaggio veramente bello e potente e nel prossimo post scopriremo come rendere “nascosto” un metodo dichiarato in una interfaccia!!!

 

Stay tuned

Alla prossima

Carmine

by Carmine Punella on 2/4/2014
Post archive