Les autres réponses offrent une bonne aide pour cette question, mais il y a un problème important et subtil qu'aucune d'entre elles n'aborde directement. Il existe deux façons de considérer le type en C# : type statique y type d'exécution .
Le type statique est le type d'une variable dans votre code source. Il s'agit donc d'un concept de compilation. Il s'agit du type que vous voyez dans une infobulle lorsque vous survolez une variable ou une propriété dans votre environnement de développement.
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 fonction GetType()
méthode.
Le type d'exécution d'un objet est souvent différent du type statique de la variable, de la propriété ou de la 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 de la variable référent est string
. Par conséquent, la ligne suivante imprimera "System.String" dans la console :
Console.WriteLine(o.GetType()); // prints System.String
Mais, si vous survolez la variable o
dans votre environnement de développement, vous verrez le type System.Object
(ou l'équivalent object
mot-clé).
Pour les variables de type valeur, telles que int
, double
, System.Guid
En effet, les types de valeur ne peuvent pas servir de classe de base pour un autre type ; le type de valeur est garanti comme étant le type le plus dérivé dans sa chaîne d'héritage. Ceci 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 soit une instance de ce type, soit un type de référence scellé. null
.
Inversement, si le type statique de la variable est un type abstrait, il est garanti que le type statique et le type d'exécution seront différents.
Pour illustrer cela en 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));
Un autre utilisateur a modifié cette réponse pour incorporer une fonction qui apparaît ci-dessous dans les commentaires, une méthode d'aide générique permettant d'utiliser l'inférence de type pour obtenir une référence au type statique d'une variable au moment de l'exécution, grâce à typeof
:
Type GetStaticType<T>(T x) => typeof(T);
Vous pouvez utiliser cette fonction dans l'exemple ci-dessus :
Console.WriteLine(GetStaticType(o)); // prints System.Object
Mais cette fonction est d'une utilité limitée, à moins que vous ne vouliez vous protéger contre le remaniement. Lorsque vous écrivez l'appel à GetStaticType
vous savez déjà que le type statique de o est object. Vous pourriez tout aussi bien écrire
Console.WriteLine(typeof(object)); // also prints System.Object!
Cela me rappelle un code que j'ai rencontré lorsque j'ai commencé mon travail actuel, quelque chose comme
SomeMethod("".GetType().Name);
au lieu de
SomeMethod("String");