C'è una questione importante e sottile che nessuno di loro affronta direttamente. Esistono due modi per considerare il tipo in C #: tipo statico e tipo in fase di esecuzione .
Il tipo statico è il tipo di una variabile nel codice sorgente. È quindi un concetto in fase di compilazione. Questo è il tipo visualizzato in una descrizione comando quando passi il mouse su una variabile o una proprietà nel tuo ambiente di sviluppo.
Puoi ottenere il tipo statico scrivendo un metodo generico di supporto per lasciare che l'inferenza del tipo se ne occupi per te:
Type GetStaticType<T>(T x) { return typeof(T); }
Il tipo di runtime è il tipo di un oggetto in memoria. È quindi un concetto di runtime. Questo è il tipo restituito dal GetType()metodo.
Il tipo di runtime di un oggetto è spesso diverso dal tipo statico della variabile, della proprietà o del metodo che lo contiene o lo restituisce. Ad esempio, puoi avere un codice come questo:
object o = "Some string";
Il tipo statico della variabile è object, ma in fase di esecuzione, il tipo di referente della variabile è string. Pertanto, la riga successiva stamperà "System.String" sulla console:
Console.WriteLine(o.GetType()); // prints System.String
Tuttavia, se passi il mouse sulla variabile onel tuo ambiente di sviluppo, vedrai il tipo System.Object(o la objectparola chiave equivalente ). Puoi anche vedere lo stesso usando la nostra funzione di supporto dall'alto:
Console.WriteLine(GetStaticType(o)); // prints System.Object
Per le variabili tipo valore, come ad esempio int, double, System.Guid, si sa che il tipo run-time sarà sempre lo stesso tipo statico, perché i tipi di valore non possono servire come classe base per un altro tipo; il tipo di valore è garantito come il tipo più derivato nella sua catena di ereditarietà. Questo vale anche per i tipi di riferimento sigillati: se il tipo statico è un tipo di riferimento sigillato, il valore di runtime deve essere un'istanza di quel tipo o null.
Al contrario, se il tipo statico della variabile è un tipo astratto, è garantito che il tipo statico e il tipo runtime saranno diversi.
Per illustrarlo nel codice:
// int is a value type
int i = 0;
// Prints True for any value of i
Console.WriteLine(i.GetType() == typeof(int));
// string is a sealed reference type
string s = "Foo";
// Prints True for any value of s
Console.WriteLine(s == null || s.GetType() == typeof(string));
// object is an unsealed reference type
object o = new FileInfo("C:\\f.txt");
// Prints False, but could be true for some values of o
Console.WriteLine(o == null || o.GetType() == typeof(object));
// FileSystemInfo is an abstract type
FileSystemInfo fsi = new DirectoryInfo("C:\\");
// Prints False for all non-null values of fsi
Console.WriteLine(fsi == null || fsi.GetType() == typeof(FileSystemInfo));
int