typeof 在编译时获取类型名对应的 Type 对象 ,安全高效;GetType() 在运行时通过实例获取实际类型,支持 多态 但 NULL 会抛异常。

在 C# 中,typeof 和 GetType() 都用于获取类型信息(即 Type 对象),但它们的工作时机和使用场景有本质 区别。理解它们的关键在于:一个是编译时操作,另一个是运行时行为。
typeof:编译时获取类型信息
typeof 是一个上下文关键字,用于在 编译时 获取指定类型的 Type 对象。它操作的是类型名称,而不是对象实例。
例如:
Type type = typeof(String); Console.WriteLine(type.Name); // 输出: String
特点:
- 只能作用于已知的类型名(如
typeof(int)、typeof(List<string>)</string>) - 在编译阶段就能确定结果,性能高
- 不能用于变量或表达式,除非是 泛型 中的
typeof(T) - 常用于泛型编程、反射入口点等场景
GetType():运行时获取对象的实际类型
GetType() 是 Object 类定义的一个实例方法,所有 继承 自 object 的类型都拥有该方法。它在 运行时 返回对象的实际类型(即真实类型,可能与声明类型不同)。
例如:
object obj = "Hello"; Type type = obj.GetType(); Console.WriteLine(type.Name); // 输出: String
再看一个多态的例子:
Animal animal = new Dog(); // Dog 继承自 Animal Type type = animal.GetType(); Console.WriteLine(type.Name); // 输出: Dog,而不是 Animal
特点:
- 必须通过一个对象实例调用
- 返回的是对象在运行时的“真实类型”
- 支持多态,能反映实际创建的类型
- 存在轻微性能开销,因为是在运行时执行
- 如果对象为 null,调用 GetType() 会抛出
NullReferenceException
关键 区别 总结
| 项目 | typeof | GetType() |
|---|---|---|
| 执行时机 | 编译时 | 运行时 |
| 操作目标 | 类型名 | 对象实例 |
| 是否需要实例 | 不需要 | 需要 |
| null 安全性 | 安全(不依赖实例) | 不安全(null 调用会崩溃) |
| 多态支持 | 无(只认写死的类型) | 有(能识别实际类型) |
使用建议
选择哪一个取决于你的需求:
- 如果你知道具体类型名,并且想在编译期就确定类型信息,用 typeof —— 更高效,更安全。
- 如果你想判断一个对象在运行时到底是什么类型(尤其是涉及继承、接口 或多态时),用 GetType()。
- 在泛型中,
typeof(T)仍是编译时操作,但如果 T 是由运行时传入的泛型参数,它的行为会根据实际类型而定(在泛型实例化时确定)。
基本上就这些。掌握 typeof 和 GetType() 的差异,有助于写出更准确的反射代码和类型判断逻辑。