使用GetType()和typeof()获取类型有什么区别?

25

哪种方法是获取类型的首选方式?


版主注意: 我重新打开并关闭以删除旧的重复通知。请不要将此视为我对重复内容准确性的认可。 - Machavity
4个回答

33
只有在编译时知道类型并试图获取相应的Type对象时,才能使用typeof()。 (尽管类型可以是泛型类型参数,例如,在具有类型参数T的类中使用typeof(T)。)使用typeof不需要任何该类型的实例。 typeof的操作数始终是类型或类型参数的名称。它不能是变量或类似的任何内容。
现在将其与object.GetType()进行比较。这将获取调用它的对象的实际类型。这意味着:
- 您不需要在编译时知道类型(通常不需要) - 您确实需要有该类型的实例(否则您无法调用GetType) - 实际类型不需要对您的代码可访问 - 例如,它可能是不同程序集中的内部类型
一个奇怪的地方:由于装箱的工作方式,GetType将在可空值类型上给出意外的答案。调用GetType将始终涉及装箱任何值类型,包括可空值类型,而可空值类型的装箱值是null引用或非可空值类型的实例的引用。

一个奇怪的点 - 你能展示吗? - Aarnihauta
@Aarnihauta:好吧,我已经解释了会发生什么......我不想添加一个完整的例子,因为它会使其他回答相形见绌。 - Jon Skeet

9

GetType() 在运行时起作用,typeof() 是一个编译时运算符。

因此,

// untested, schematic
void ShowType(Object x)
{
   Write(x.GetType().Name);  // depends on actual type
   // typeof(x) won't actually compile
   Write(typeof(x).Name);   // always System.Object
}

ShowType("test");

将打印System.String和System.Object。

查看此问题以获取更好的示例。


5
实际上,typeof无法用于实例,因此typeof(x)会无法编译。 - Romain Verdier
@Romain:你是对的,已添加注释。你可以使用一个通用方法来展示它,就像这样。 - H H
typeof(instance) 不会编译,对吧? - Gishu

2

GetType是Object上的一个虚方法 - 这意味着在给定一个类的实例时,可以检索相应的Type对象。

typeof是C#操作符 - 它用于执行编译时查找,即在给定表示类名的符号的情况下,检索其对应的Type对象。

if (typeof(String) == "test".GetType())

0

并不完全相同,问题出现在使用继承时。

I.e.:

WebPage1继承自Page,而Page又继承自Object,所以如果你尝试使用(new WebPage1()).GetType() == typeof(object)进行测试,结果会返回false,因为这两个类型是不同的。但是当你使用is运算符进行测试时,结果会返回true。

((new WebPage1()) is object)是true,因为(new WebPage1())是一个WebPage1类型的对象,同时也是一个Pageobject

尽管类型可能不同,但is检查的是你是否可以安全地将其转换为该类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接