I linguaggi supportati dal .NET framework quali C# e VB si dice che sono strongly-typed, ossia fortemente tipizzati, in parole povere ogni variabile od oggetto dichiarato all'interno del programma deve definire un tipo e lo deve rispettare (pena un errore di compilazione).
Pertanto un tipo descrive le caratteristiche dell'informazione che esso dovrà andare a rappresentare all'interno del programma a mezzo di una variabile, sia esso un numero, una sequenza di caratteri od oggetti più complessi come istanze di classi, in ogni caso ogni elemento all'interno di un programma sviluppato col .NET framework deve essere dichiarato a mezzo di un tipo e ne deve rispettare le funzionalità durante l'uso.
I tipi non si differenziano però solo per il dato che rappresentano, ma anche per la gestione che di questi se ne fà in memoria. All'interno del .NET framework, o meglio del CLR (Common Language Runtime) sono definite due categorie di tipi, i Tipi di Valore (Value Types) e Tipi di Riferimento (Value References), l'una e l'altra categoria presenta le proprie caratteristiche e soprattutto ha un diverso metodo di allocazione della memoria, per chi vuole iniziare a programmare in .NET non può prescindere dalla conoscenza di queste nozioni di base relative ai tipi per valore e per riferimento, andiamo a vedere pertanto le principali caratteristiche e differenze.
Le caratteristiche e differenze tra Tipi di Valore e Tipi di Riferimento del framework.NET prescindono dal linguaggio usato, sia esso C#, VB.NET o altro, quello che diremo vale per tutti i linguaggi managed della piattaforma .NET.
Tipi di Valore
Questi tipi rappresentano la stragrande maggioranza dei Tipi Primitivi (dati a sè stanti e non complessi, come un numero o un carattere), come System.Int16, System.Char, System.Boolean, System.DateTime.
Sono caratterizzati dal fatto che essi possiedono direttamente il valore del dato il quale viene allocato nella zona di memoria detta stack, che consente un accesso in lettura e scrittura molto veloce; inoltre i Tipi di Valore non vengono instanziati tramite l'operatore new e non possono assumere il valore null, provate infatti ad assegnare un valore null ad un'intero, state certi che il compilatore se la prenderà a male, segnalandovi l'errore a compile-time che vi dice "Cannot convert null to 'int' because it is a value type", fanno eccezione a quest'ultima specifica i tipi stringa, che sono particolari tipi di dati primitivi, usati come tipi valore ma sostanzialmente gestiti quasi come tipi di riferimento.
NOTA: Anche le strutture ed il tipo System.Object fanno parte dei Tipi Valore, in particolare quest'ultimo è il tipo alla base del .NET framework, da esso derivano tutti gli altri, si suole dire che "in .NET tutto è un'oggetto".
Tipi di Riferimento
Questi tipi rappresentano tutti quei dati espressi tramite la dichiarazione di classi per descrivere oggetti complessi, essi vengono allocati nella memoria managed heap e non contengono direttamente il valore del dato, ma un puntatore ad una locazione di memoria dove è contenuto il valore vero e proprio, infine come è facile presumere questi possono assumere valore null.
Conclusioni
Le principali differenze tra i Tipi di Valore ed i Tipi di Riferimento consistono sostanzialmente nella diversa allocazione e gestione in memoria, i primi allocati nello stack, i secondi nel managed heap (tramite uso della Garbage Collection). L'uso di uno o dell'altro tipo deve essere pensato e gestito in maniera opportuno, un'uso eccessivo dello stack, nonostante la velocità d'accesso potrebbe portare ad una saturazione con un calo notevole delle performance dell'intera applicazione, discorso analogo ma inverso vale per il managed heap.
Chiunque voglia aggiungere qualcosa o porre una domanda può farlo tramite i commenti.