Other answers give good help in this matter, but there is an important and subtle problem that none of them address directly. There are two ways to consider a type in C #: a static type and a runtime type.
The static type is the type of the variable in the source code. Therefore, this is the concept of compilation time. This is the type that you see in the tooltip when you hover over a variable or property in your development environment.
The runtime type is the type of object in memory. Therefore, this is the concept of runtime. This is the type returned by the GetType() method.
The runtime type of an object often differs from the static type of a variable, property, or method that holds or returns it. For example, you might have code like this:
object o = "Some string";
The static type of the variable object , but at run time, the referent type of the variable string . Therefore, the following line will print "System.String" on the console:
Console.WriteLine(o.GetType());
But if you hover over the o variable in your development environment, you will see the System.Object type (or the equivalent keyword object ).
For variables of type values, such as int , double , System.Guid , you know that the runtime type will always be the same as the static type, since value types cannot serve as a base class for another type; the value type is guaranteed to be the most derived type in the inheritance chain. This is also true for private reference types: if the static type is a private reference type, the runtime value must be either an instance of this type or null .
Conversely, if the static type of a variable is an abstract type, then it is guaranteed that the static type and the type of the runtime will be different.
To illustrate this in 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));