Le Custom Type Conversion sono tra le caratteristiche poco conosciute del C#, che però, una volta scoperte, possono risultare molto utili.
Per capire meglio di cosa stiamo per parlare, facciamo un breve accenno alle conversioni di tipo in genere.
Conversioni di tipo
Convertire un tipo significa assegnare una variabile di un certo tipo ad una variabile di un tipo differente, ad esempio abbiamo una variabile Integer
che ad un certo punto vogliamo assegnare ad un'altra variabile che però è Decimal
.
Per fare questo è necessario ricorrere alle conversioni di tipo che nello specifico, in C#, dal punto di vista sintattico possono essere implicite od esplicite e possono essere di tipo:
- widening
- narrowing
La modalità di conversione implicita od esplicita riguarda semplicemente il modo in cui la attuiamo se specificando esplicitamente appunto il tipo in cui convertire la variabile oppure omettendone il tipo perchè la conversione può essere attuata implicitamente.
Invece a seconda della tipologia delle due variabili la conversione può avvenire senza perdita di informazione o con il rischio di perdita di dati. Quest'ultima eventualità si può verificare nel caso in cui chiediamo di convertire una variabile ad esempio di tipo Decimal
in una variabile di tipo Integer
.
Ovviamente può accadere che il valore Decimal
sia superiore al valore massimo memorizzabile in una variabile di tipo Integer
e quindi in questo caso potrebbe esserci perdita di informazione e la conversione viene denominata narrowing. Nell'altro caso la conversione è di tipo widening perchè è certo che il valore convertito sarà interamente contenuto dalla variabile ospite.
Conversioni custom
Dopo questo breve accenno alle conversioni di tipo passiamo quindi alle conversioni tra i tipi Custom ovvero tra le classi personalizzate.
Anche in questo ambito potremmo voler assegnare una variabile di un certo tipo ad un'altra di tipo diverso. In questo caso però a meno che non ci sia una interfaccia che accomuni le due classi non sarà possibile effettuare alcun tipo di conversione né esplicita né implicita.
È a questo punto che scende in gioco la Custom Type Conversion ovvero la possibilità che ci fornisce il linguaggio C# di creare un metodo interno alla classe che si preoccupi di effettuare la conversione tra un certo tipo e quello della classe corrente.
Vediamo praticamente come fare. Immaginiamo di avere le due classi PersonaA
e PersonaB
aventi proprietà e metodi interni differenti. Possiamo fare in modo che la classe PersonaB
possa essere convertita in PersonaA
con un semplice cast (conversione esplicita) in questo modo:
class PersonaA
{
public static explicit operator PersonaA(PersonaB b)
{
PersonaA a = new PersonaA();
a.NomeCognome = b.Nome + " " + b.Cognome;
a.Via = b.Indirizzo;
return a;
}
}
Abbiamo creato un metodo statico che sarà utilizzato in fase di conversione esplicita tra i due tipi considerati. Come vediamo nel metodo non facciamo altro che mappare le proprietà di una classe su quelle dell'altra. Fatto questo possiamo effettuare la conversione in questo modo:
PersonaA pA = (PersonaA)pB;
Possiamo inoltre anche implementare una conversione implicita, in questo modo:
class PersonaA
{
public static implicit operator PersonaB(PersonaA a)
{
PersonaB b = new PersonaB();
b.Nome = a.NomeCognome;
b.Indirizzo = a.Via;
return b;
}
}
e quindi scrivere poi:
PersonaB b = a;
dove ovviamente la variabile a
è di tipo PersonaA
.
Le keyword explicit operator ed implicit operator ci permettono quindi di implementare il codice preposto alla conversione di tipo in una maniera pulita ed elegante.