Uno dei primi concetti teorici riguardanti l'esame 70-536 prende in
considerazione i tipi di dati messi a disposizione dal framework. Vediamo quindi
di far luce - brevemente - su cosa significano e che differenze ci sono
tra l'uno e l'altro. Lascerò la parola a tutti voi nei miei commenti per
tutte le precisazioni del caso.
Value types
Cosa sono i value types? E' un nome col quale
vengono chiamati tutti i tipi di dati semplici, ovvero variabili nella
cui cella di memoria viene memorizzato il valore stesso della variabile. Cadono
in questa categoria i tipi di dato come int, float, double, etc. I value types
sono a loro volta suddivisi in struct ed
enumerations. La caratteristica principale dei value types è
che durante un'operazione di assegnamento (leggesi operatore '='), avviene
una copia del valore: concetto banale, è vero, perchè che è importante
conoscere. Quindi, per esempio, se troviamo istruzioni di questo tipo:
int myCode = 5;
int UserCode;
float Weigth = 89.31;
UserCode = myCode;
teniamo bene a presente che ciascuna operazione comporta una copia del
valore, dall'espressione a destra dell'operatore, alla variabile presente sulla
sinistra. Inoltre, a ciascun tipo di dati può essere assegnato qualsiasi valore
consentito dal tipo di dati stesso: quindi, il bool
ammette solamente true o false; il byte ammette da 0 a
255; l'int lavora su un range che va da
-2,147,483,648 a 2,147,483,647. Dipendentemente dal tipo di dati, abbiamo a
disposizione più o meno precisione. L'unico valore che non è consentito ai value
type è il valore null. Ottima spunto per cominciare a
scrivere buon codice è quello di scegliere il tipo di dato più adatto in base
all'informazione che vogliamo memorizzare, evitando sprechi di memoria
(memory-leak) che alla lunga potrebbero causare cattive performance del
nostro software.
Nullable types
Chiariamo subito una cosa: esiste
un'eccezione. I value types possono contenere il valore null. Per far questo, è indispensabile sfruttare una delle
caratteristiche del Framework 2.0, ovvero utilizzare i nullable types. Di cosa
si tratta? Beh, banalmente, si tratta di value types che - oltre a poter
contenere i valori ammessi dal tipo di dati stesso - possono contenere
anche il valore null. Di conseguenza, avremo un nullable
int, un nullable byte, un
nullable bool, e così via.
Ad esempio, il codice corrente non verrebbe compilato...
int _Distance = 90;
bool _Shipped = true;
double Weight = null;
Le prime due istruzioni sono corrette, mentre la terza no, perchè un double
non può, normalmente, contenere il valore null. Per
dichiarare un nullable type, dobbiamo semplicemente aggiungere il carattere '?'
al tipo di dati, et voilà, il gioco è fatto. Di conseguenza...
int? _Distance = null;
bool? _Shipped = null;
double? Weight = null;
questo codice è corretto e verrebbe compilato senza problemi. Questa
caratteristica, ripetiamolo, è una prerogativa del Framework 2.0.
Reference types
I references
types di .NET sono rappresentati da tutte quelle variabili nella cui locazione
non c'è il valore effettivo, quanto un pointer che punta all'oggetto in
questione. Fanno parte di questa categoria le string e
in generale tutti gli object. Teniamo ben presente che
tutte le classi di .NET, anche se alla lontana, derivano da object, e di conseguenza tutte le classi sono references
types. La grande differenza in questo caso è che l'operatore di assegnamento
('=') non provoca una copia di un valore, ma viene copiato soltanto il
riferimento all'oggetto stesso, che in memoria rimane soltanto uno. Per
definizione, un reference type può contenere il valore null.
La differenza tra value type e reference type è un concetto
che bisogna conoscere e sapere, e che riveste una certa importanza quando si ha
a che fare con le funzioni in C#. Quando una funzione ha uno o più parametri in
ingresso, ognuno di questi può essere passato per valore o per riferimento
(by val o by ref). Nel primo caso, il parametro viene
copiato e quindi eventuali modifiche vengono perse quando si esce dalla
funzione. Nel secondo caso, il parametro non viene copiato,
pertanto all'interno della funzione possiamo modificarne il valore, che verrà
mantenuto (trattandosi fisicamente della stessa zona di memoria) all'uscita
della stessa. Un piccolo esempio lo potete trovare qui.
Questi concetti (value types e reference types) non sono concetti nuovi
relativi al mondo .NET. Gli stessi criteri vengono applicati a linguaggi come
Visual Basic 6.0 che applicano lo stesso metodo usando le keyword ByVal o ByRef.
Ma questa, come si dice, è un'altra storia.