GetType() 返回的实际类型是什么
gettype() 方法会返回变量在运行时实际指向的对象的 type 对象,而不是变量声明时的静态类型。对于引用类型,它反映堆中对象的真实类;对于值类型,它反映装箱前的原始结构或枚举类型。通过比较 type 实例,可以准确判断变量当前保存的具体数据类型。

using System;
public class Animal { }
public class Dog : Animal { }
public struct Point { public int X; }
class Program {
static void Main() {
// 引用类型:多态场景
Animal a = new Dog();
Console.WriteLine(a.GetType().Name); // 输出: Dog
// 值类型:直接获取
Point p = new Point { X = 10 };
Console.WriteLine(p.GetType().Name); // 输出: Point
// 装箱场景
object o = p;
Console.WriteLine(o.GetType().Name); // 输出: Point
}
}上述代码展示了三种典型情况。首先,当 Animal 类型的变量 a 实际指向一个 Dog 实例时,a.GetType() 返回的是 Dog 的类型信息,这验证了 GetType() 基于运行时对象而非编译时声明的特性。其次,值类型 Point 直接调用 GetType() 返回其自身类型。最后,当值类型被赋值给 object 发生装箱后,o.GetType() 依然能正确识别出底层是 Point 而非 Object。这些结果证明了该方法能穿透静态类型约束,揭示内存中的真实布局。
如何区分具体子类或基类
要区分变量保存的是哪个具体子类或基类,可以直接使用 Type.IsAssignableFrom() 方法或比较 Type.Name 属性。如果只需要判断是否属于某个特定类型,推荐使用 Type.IsInstanceOfType() 或者简单的 is 关键字,但 GetType() 本身提供的是精确匹配,不会考虑继承关系中的向上转型兼容。

using System;
public class Base { }
public class Derived : Base { }
class Program {
static void Main() {
Base b = new Derived();
Type t = b.GetType();
// 精确匹配
bool isDerived = t == typeof(Derived);
bool isBase = t == typeof(Base);
Console.WriteLine(isDerived); // True
Console.WriteLine(isBase); // False
// 使用 IsAssignableFrom 检查继承链
bool isAssignableToBase = typeof(Base).IsAssignableFrom(t);
Console.WriteLine(isAssignableToBase); // True
}
}在这个例子中,变量 b 声明为 Base 但实例化为 Derived。调用 b.GetType() 得到 Derived 的 Type。通过 t == typeof(Derived) 可以确认它是确切子类,而 t == typeof(Base) 返回 false,因为 GetType() 不进行继承匹配。相反,typeof(Base).IsAssignableFrom(t) 返回 true,说明虽然类型不同,但存在继承关系。这种对比明确了 GetType() 用于精确识别,而 IsAssignableFrom 用于逻辑归属判断。
当变量为 null 时 GetType 的行为
当变量为 null 时,调用 GetType() 会抛出 NullReferenceException。这是因为 GetType() 是实例方法,需要在非空对象上执行。对于可能为空的变量,必须先进行空值检查,或者使用 object.GetType() 结合空合并运算符来安全处理。
using System;
class Program {
static void Main() {
string s = null;
try {
Type t = s.GetType(); // 抛出 NullReferenceException
} catch (NullReferenceException) {
Console.WriteLine("变量为空,无法获取类型");
}
// 安全写法
string s2 = null;
Type t2 = (s2 ?? "").GetType(); // 如果为null则用空字符串代替
Console.WriteLine(t2.Name); // String
}
}第一段代码尝试对 null 字符串调用 GetType(),导致程序崩溃并捕获异常。第二段代码展示了安全处理方式:使用空合并运算符 ?? 将 null 替换为一个默认的非空字符串 "",从而避免异常。此时 t2 的类型为 String。这种方法适用于需要统一处理类型信息的场景,但需注意替换值的类型可能与原意不符,因此在严格类型检查中应优先使用 is null 判断。


















