C# 中的类型检查:typeof、GetType 还是 is?全面解析

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C# 中的类型检查:typeof、GetType 还是 is?如何不在这三者中迷失

\n\n

每个 C# 开发者迟早都会遇到需要检查对象类型的情况。看起来很简单,对吧?但当面前有三个选项——typeof、GetType() 和 is——时,你会眼花缭乱,脑海中自然浮现一个问题:“到底该选哪一个?”

\n\n

这篇文章不仅仅是文档的枯燥摘录。我们将通过实际示例分析每种方法,揭示其中的陷阱,并给出明确的建议。阅读之后,你将不再犹豫,并确切知道在特定情况下该使用哪种工具。开始吧!

\n\n

为什么要在 C# 中检查类型?

\n\n

在深入细节之前,让我们先回顾一下为什么需要这样做。C# 是一种强类型语言,但这并不排除对象的类型仅在运行时才已知的情况。以下是最常见的场景:

\n\n
    \n
  • 处理接口和基类:你将对象作为 object 或基类型接收,但需要了解其真实的“本质”。
  • \n
  • 序列化和反序列化:JSON 或 XML 以字符串形式传入,需要恢复为具体的类型。
  • \n
  • 反射(Reflection):当你仅知道类型名称,需要动态创建对象或调用方法时。
  • \n
  • 日志记录和调试:有时只需在日志中输出当前正在处理的类型。
  • \n
\n\n

这时,我们的三位主角登场了。让我们逐一深入了解它们。

\n\n

typeof —— 静态地展望未来

\n\n

typeof 是一个运算符,它返回编译时已知类型的 System.Type 对象。它就像一个信息服务:“告诉我类的名称,我就给你关于它的所有信息。”

\n\n

工作原理:

\n
Type stringType = typeof(string);\nConsole.WriteLine(stringType.FullName); // 输出:System.String\n\nType intType = typeof(int);\nConsole.WriteLine(intType.FullName); // 输出:System.Int32
\n\n

关键特性:typeof 不需要对象的实例。这是一个静态操作。你对编译器说:“我有一个类型 MyClass,请给我它的元数据。”

\n\n

何时使用:

\n
    \n
  • 当你需要根据类名(而非对象)获取类型时。
  • \n
  • 在特性(Attribute)中(例如 [AttributeUsage(typeof(MyAttribute))])。
  • \n
  • 在泛型中:typeof(List<>)。
  • \n
\n\n

陷阱:typeof 始终返回你在代码中指定的确切类型。它不了解继承关系。如果你有 class Dog : Animal { },那么 typeof(Animal) 永远不会变成 typeof(Dog)。

\n\n

GetType() —— 动态调查

\n\n

与 typeof 不同,GetType() 方法是在对象的实例上调用的。它获取内存中的实际对象,并告诉你:“啊哈,原来你实际上是这个!”

\n\n

示例:

\n
object obj = "你好,世界!";\nType typeOfObj = obj.GetType();\nConsole.WriteLine(typeOfObj.FullName); // 输出:System.String\n\n// 现在来个技巧:\nobject obj2 = 42;\nType typeOfObj2 = obj2.GetType();\nConsole.WriteLine(typeOfObj2.FullName); // 输出:System.Int32
\n\n

请注意:变量 obj 被声明为 object,但 GetType() 能够“看穿”这个包装,并返回 System.String。这就是动态类型确定。

\n\n

何时使用:

\n
    \n
  • 当你需要在运行时了解对象的确切类型时。
  • \n
  • 用于类型比较:obj.GetType() == typeof(MyClass)。
  • \n

博客

书籍推荐