这些代码中的哪一段更快?
if (obj is ClassA) {} if (obj.GetType() == typeof(ClassA)) {}
编辑:我知道他们不会做同样的事情.
如果他们不做同样的事情,哪个更快更重要?比较具有不同含义的陈述的表现似乎是一个坏主意.
is
告诉你对象是否ClassA
在其类型heirarchy中的任何地方实现. GetType()
告诉你最派生的类型.
不一样的事情.
这应该回答这个问题,然后是一些问题.
if (obj.GetType() == typeof(ClassA)) {}
对于那些不想阅读文章的人来说,第二行更快.
他们不做同样的事情.如果obj是ClassA类型或ClassA的某个子类,则第一个工作.第二个只匹配ClassA类型的对象.第二个会更快,因为它不必检查类层次结构.
对于那些想知道原因,但又不想阅读引用文章的人 是vs typeof.
我做了一些基准测试,他们做同样的事情 - 密封类型.
var c1 = ""; var c2 = typeof(string); object oc1 = c1; object oc2 = c2; var s1 = 0; var s2 = '.'; object os1 = s1; object os2 = s2; bool b = false; Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < 10000000; i++) { b = c1.GetType() == typeof(string); // ~60ms b = c1 is string; // ~60ms b = c2.GetType() == typeof(string); // ~60ms b = c2 is string; // ~50ms b = oc1.GetType() == typeof(string); // ~60ms b = oc1 is string; // ~68ms b = oc2.GetType() == typeof(string); // ~60ms b = oc2 is string; // ~64ms b = s1.GetType() == typeof(int); // ~130ms b = s1 is int; // ~50ms b = s2.GetType() == typeof(int); // ~140ms b = s2 is int; // ~50ms b = os1.GetType() == typeof(int); // ~60ms b = os1 is int; // ~74ms b = os2.GetType() == typeof(int); // ~60ms b = os2 is int; // ~68ms b = GetType1(c1); // ~178ms b = GetType2 (c1); // ~94ms b = Is (c1); // ~70ms b = GetType1 (c2); // ~178ms b = GetType2 (c2); // ~96ms b = Is (c2); // ~65ms b = GetType1 (oc1); // ~190ms b = Is (oc1); // ~69ms b = GetType1 (oc2); // ~180ms b = Is (oc2); // ~64ms b = GetType1 (s1); // ~230ms b = GetType2 (s1); // ~75ms b = Is (s1); // ~136ms b = GetType1 (s2); // ~238ms b = GetType2 (s2); // ~69ms b = Is (s2); // ~142ms b = GetType1 (os1); // ~178ms b = Is (os1); // ~69ms b = GetType1 (os2); // ~178ms b = Is (os2); // ~69ms } sw.Stop(); MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
用于测试泛型类型的通用函数:
static bool GetType1(T t) { return t.GetType() == typeof(S); } static bool GetType2(T t) { return typeof(T) == typeof(S); } static bool Is(T t) { return t is S; }
我也试过自定义类型,结果是一致的:
var c1 = new Class1(); var c2 = new Class2(); object oc1 = c1; object oc2 = c2; var s1 = new Struct1(); var s2 = new Struct2(); object os1 = s1; object os2 = s2; bool b = false; Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < 10000000; i++) { b = c1.GetType() == typeof(Class1); // ~60ms b = c1 is Class1; // ~60ms b = c2.GetType() == typeof(Class1); // ~60ms b = c2 is Class1; // ~55ms b = oc1.GetType() == typeof(Class1); // ~60ms b = oc1 is Class1; // ~68ms b = oc2.GetType() == typeof(Class1); // ~60ms b = oc2 is Class1; // ~68ms b = s1.GetType() == typeof(Struct1); // ~150ms b = s1 is Struct1; // ~50ms b = s2.GetType() == typeof(Struct1); // ~150ms b = s2 is Struct1; // ~50ms b = os1.GetType() == typeof(Struct1); // ~60ms b = os1 is Struct1; // ~64ms b = os2.GetType() == typeof(Struct1); // ~60ms b = os2 is Struct1; // ~64ms b = GetType1(c1); // ~178ms b = GetType2 (c1); // ~98ms b = Is (c1); // ~78ms b = GetType1 (c2); // ~178ms b = GetType2 (c2); // ~96ms b = Is (c2); // ~69ms b = GetType1 (oc1); // ~178ms b = Is (oc1); // ~69ms b = GetType1 (oc2); // ~178ms b = Is (oc2); // ~69ms b = GetType1 (s1); // ~272ms b = GetType2 (s1); // ~140ms b = Is (s1); // ~163ms b = GetType1 (s2); // ~272ms b = GetType2 (s2); // ~140ms b = Is (s2); // ~163ms b = GetType1 (os1); // ~178ms b = Is (os1); // ~64ms b = GetType1 (os2); // ~178ms b = Is (os2); // ~64ms } sw.Stop(); MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
和类型:
sealed class Class1 { } sealed class Class2 { } struct Struct1 { } struct Struct2 { }
推理:
调用GetType
的struct
s是慢. GetType
是在object
类上定义的,不能在子类型中重写,因此struct
需要将其装箱以进行调用GetType
.
在对象实例上,GetType
速度更快,但非常轻微.
在泛型类型上,如果T
是class
,则is
更快.如果T
是struct
,那么比两者is
快得多GetType
但typeof(T)
速度要快得多.在案件T
之中class
,typeof(T)
是不是因为从实际的基本类型及其不同的可靠t.GetType
.
简而言之,如果您有object
实例,请使用GetType
.如果您有通用class
类型,请使用is
.如果您有通用struct
类型,请使用typeof(T)
.如果您不确定泛型类型是引用类型还是值类型,请使用is
.如果您希望始终与一种样式保持一致(对于密封类型),请使用is
..