Il y a un problème important et subtil qu'aucun d'eux ne traite directement. Il existe deux façons de considérer le type en C #: le type statique et le type au moment de l'exécution .
Le type statique est le type d'une variable dans votre code source. C'est donc un concept au moment de la compilation. Il s'agit du type que vous voyez dans une info-bulle lorsque vous survolez une variable ou une propriété dans votre environnement de développement.
Vous pouvez obtenir un type statique en écrivant une méthode générique d'assistance pour laisser l'inférence de type s'en occuper pour vous:
Type GetStaticType<T>(T x) { return typeof(T); }
Le type d'exécution est le type d'un objet en mémoire. Il s'agit donc d'un concept d'exécution. C'est le type renvoyé par la GetType()méthode.
Le type d'exécution d'un objet est souvent différent du type statique de la variable, propriété ou méthode qui le contient ou le renvoie. Par exemple, vous pouvez avoir un code comme celui-ci:
object o = "Some string";
Le type statique de la variable est object, mais au moment de l'exécution, le type du référent de la variable est string. Par conséquent, la ligne suivante affichera «System.String» sur la console:
Console.WriteLine(o.GetType()); // prints System.String
Mais, si vous survolez la variable odans votre environnement de développement, vous verrez le type System.Object(ou le objectmot-clé équivalent ). Vous voyez également la même chose en utilisant notre fonction d'assistance ci-dessus:
Console.WriteLine(GetStaticType(o)); // prints System.Object
Pour les variables de type valeur, tels que int, double, System.Guid, vous savez que le type d' exécution sera toujours le même que le type statique, car les types de valeur ne peut pas servir de la classe de base pour un autre type; il est garanti que le type valeur est le type le plus dérivé de sa chaîne d'héritage. Cela est également vrai pour les types de référence scellés: si le type statique est un type de référence scellé, la valeur d'exécution doit être une instance de ce type ou null.
Inversement, si le type statique de la variable est un type abstrait, alors il est garanti que le type statique et le type d'exécution seront différents.
Pour illustrer cela dans le code:
// 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