Hay un tema importante y sutil que ninguno de ellos aborda directamente. Hay dos formas de considerar el tipo en C #: tipo estático y tipo en tiempo de ejecución .
El tipo estático es el tipo de variable en su código fuente. Por tanto, es un concepto en tiempo de compilación. Este es el tipo que ve en una información sobre herramientas cuando pasa el cursor sobre una variable o propiedad en su entorno de desarrollo.
Puede obtener un tipo estático escribiendo un método genérico auxiliar para permitir que la inferencia de tipo se encargue de ello por usted:
Type GetStaticType<T>(T x) { return typeof(T); }
El tipo de tiempo de ejecución es el tipo de un objeto en la memoria. Por tanto, es un concepto de tiempo de ejecución. Este es el tipo devuelto por el GetType()método.
El tipo de tiempo de ejecución de un objeto suele ser diferente del tipo estático de la variable, propiedad o método que lo contiene o lo devuelve. Por ejemplo, puede tener un código como este:
object o = "Some string";
El tipo estático de la variable es object, pero en tiempo de ejecución, el tipo de referencia de la variable es string. Por lo tanto, la siguiente línea imprimirá "System.String" en la consola:
Console.WriteLine(o.GetType()); // prints System.String
Pero, si pasa el cursor sobre la variable oen su entorno de desarrollo, verá el tipo System.Object(o la objectpalabra clave equivalente ). También ve lo mismo usando nuestra función auxiliar desde arriba:
Console.WriteLine(GetStaticType(o)); // prints System.Object
Para las variables de tipo valor, tales como int, double, System.Guid, usted sabe que el tipo de tiempo de ejecución siempre será el mismo que el tipo estático, debido a los tipos de valor no pueden servir como clase base para otro tipo; se garantiza que el tipo de valor será el tipo más derivado en su cadena de herencia. Esto también es cierto para los tipos de referencia sellados: si el tipo estático es un tipo de referencia sellada, el valor de tiempo de ejecución debe ser una instancia de ese tipo o null.
Por el contrario, si el tipo estático de la variable es un tipo abstracto, se garantiza que el tipo estático y el tipo de tiempo de ejecución serán diferentes.
Para ilustrar eso en el código:
// 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