typeof 应用于编译时已知的类型或泛型类型参数的名称(作为标识符给出,而不是字符串)。 GetType 在运行时在对象上调用。在这两种情况下,结果都是 System.Type 类型的对象,其中包含有关类型的元信息。
编译时和运行时类型相等的示例
string s = "hello";
Type t1 = typeof(string);
Type t2 = s.GetType();
t1 == t2 ==> true
编译时和运行时类型不同
的示例
object obj = "hello";
Type t1 = typeof(object); // ==> object
Type t2 = obj.GetType(); // ==> string!
t1 == t2 ==> false
即变量obj的编译时类型(静态类型)与obj所引用的对象的运行时类型不同。
测试类型
但是,如果您只想知道 mycontrol 是否为 TextBox,那么您可以简单地测试
if (mycontrol is TextBox)
请注意,这并不完全等同于
if (mycontrol.GetType() == typeof(TextBox))
因为mycontrol 可能有一个派生自TextBox 的类型。在这种情况下,第一个比较产生true 和第二个false!在大多数情况下,第一个也是更简单的变体是可以的,因为从 TextBox 派生的控件继承了 TextBox 的所有内容,可能会添加更多内容,因此分配与 TextBox 兼容。
public class MySpecializedTextBox : TextBox
{
}
MySpecializedTextBox specialized = new MySpecializedTextBox();
if (specialized is TextBox) ==> true
if (specialized.GetType() == typeof(TextBox)) ==> false
选角
如果您有以下测试后跟一个强制转换并且 T 可以为空......
if (obj is T) {
T x = (T)obj; // The casting tests, whether obj is T again!
...
}
...您可以将其更改为...
T x = obj as T;
if (x != null) {
...
}
测试值是否属于给定类型和强制转换(再次涉及相同的测试)对于长继承链都可能很耗时。使用as 运算符,然后对null 进行测试,性能更高。
从 C# 7.0 开始,您可以使用模式匹配来简化代码:
if (obj is T t) {
// t is a variable of type T having a non-null value.
...
}
顺便说一句:这也适用于值类型。对于测试和拆箱非常方便。请注意,您不能测试可空值类型:
if (o is int? ni) ===> does NOT compile!
这是因为值要么是null,要么是int。这适用于int? o 以及object o = new Nullable<int>(x);:
if (o is int i) ===> OK!
我喜欢它,因为它消除了访问 Nullable<T>.Value 属性的需要。