有一个重要而细微的问题,它们都不直接解决。在C#中,有两种考虑类型的方式:静态类型和运行时类型。
静态类型是源代码中变量的类型。因此,它是一个编译时概念。将鼠标悬停在开发环境中的变量或属性上时,会在工具提示中看到这种类型。
您可以通过编写帮助程序泛型方法让类型推断为您处理静态类型来获取静态类型:
Type GetStaticType<T>(T x) { return typeof(T); }
运行时类型是内存中对象的类型。因此,这是一个运行时概念。这是GetType()方法返回的类型。
对象的运行时类型通常不同于保存或返回它的变量,属性或方法的静态类型。例如,您可以具有以下代码:
object o = "Some string";
变量的静态类型是object,但是在运行时,变量的引用对象的类型是string。因此,下一行将在控制台输出“ System.String”:
Console.WriteLine(o.GetType()); // prints System.String
但是,如果将鼠标悬停o在开发环境中的变量上,则会看到类型System.Object(或等效的object关键字)。您还可以从上方使用我们的辅助功能看到相同的内容:
Console.WriteLine(GetStaticType(o)); // prints System.Object
对于价值型的变量,例如int,double,System.Guid,你知道,在运行时类型将永远是一样的静态类型,因为值类型不能作为另一种类型的基类; 值类型保证是其继承链中派生最多的类型。对于密封引用类型也是如此:如果静态类型是密封引用类型,则运行时值必须是该类型的实例或null。
相反,如果变量的静态类型是抽象类型,则可以保证静态类型和运行时类型将不同。
为了说明这一点,在代码中:
// 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