协慌网

登录 贡献 社区

类型检查:typeof,GetType 还是?

我见过很多人使用以下代码:

Type t = typeof(obj1);
if (t == typeof(int))
    // Some code here

但我知道你也可以这样做:

if (obj1.GetType() == typeof(int))
    // Some code here

或这个:

if (obj1 is int)
    // Some code here

就个人而言,我觉得最后一个是最干净的,但有什么我想念的吗?哪一个最好用,还是个人喜好?

答案

一切都不一样。

  • typeof采用类型名称(您在编译时指定)。
  • GetType获取实例的运行时类型。
  • 如果实例位于继承树中, is返回 true。

class Animal { } 
class Dog : Animal { }

void PrintTypes(Animal a) { 
    Console.WriteLine(a.GetType() == typeof(Animal)); // false 
    Console.WriteLine(a is Animal);                   // true 
    Console.WriteLine(a.GetType() == typeof(Dog));    // true
    Console.WriteLine(a is Dog);                      // true 
}

Dog spot = new Dog(); 
PrintTypes(spot);

typeof(T)怎么样?它是否也在编译时解决了?

是。 T 总是表达式的类型。请记住,泛型方法基本上是一组具有适当类型的方法。例:

string Foo<T>(T parameter) { return typeof(T).Name; }

Animal probably_a_dog = new Dog();
Dog    definitely_a_dog = new Dog();

Foo(probably_a_dog); // this calls Foo<Animal> and returns "Animal"
Foo<Animal>(probably_a_dog); // this is exactly the same as above
Foo<Dog>(probably_a_dog); // !!! This will not compile. The parameter expects a Dog, you cannot pass in an Animal.

Foo(definitely_a_dog); // this calls Foo<Dog> and returns "Dog"
Foo<Dog>(definitely_a_dog); // this is exactly the same as above.
Foo<Animal>(definitely_a_dog); // this calls Foo<Animal> and returns "Animal". 
Foo((Animal)definitely_a_dog); // this does the same as above, returns "Animal"

如果要在编译时获取类型,请使用typeof 。如果要在执行时获取类型,请使用GetType 。很少有任何案例可以使用is因为它是一个演员,在大多数情况下,你最终还是会投射变量。

你没有考虑过第四个选项(特别是如果你要将一个对象转换为你发现的类型); 那就是as

Foo foo = obj as Foo;

if (foo != null)
    // your code here

这只使用一个演员而这种方法:

if (obj is Foo)
    Foo foo = (Foo)obj;

需要两个

1。

Type t = typeof(obj1);
if (t == typeof(int))

这是非法的,因为 typeof 仅适用于类型,而不适用于变量。我假设 obj1 是一个变量。因此,以这种方式,typeof 是静态的,并且它在编译时而不是运行时工作。

2。

if (obj1.GetType() == typeof(int))

如果 obj1 完全是 int 类型,则为 true。如果 obj1 派生自 int,则 if 条件将为 false。

3。

if (obj1 is int)

如果 obj1 是一个 int,或者它是从一个名为 int 的类派生,或者它实现了一个名为 int 的接口,那么这是真的。