这些代码中哪一段更快?
if (obj is ClassA) {} if (obj.GetType() == typeof(ClassA)) {}
编辑: 我知道他们做的不一样。
这应该能回答这个问题,还有更多。
对于那些不想阅读文章的人来说,第二行 if (obj.GetType() == typeof(ClassA)) {}更快。
if (obj.GetType() == typeof(ClassA)) {}
(要知道他们不会做同样的事情)
他们做的不一样。如果 obj 属于 ClassA 类型或 ClassA 的某个子类,则第一个函数可以工作。第二个只匹配 ClassA 类型的对象。第二个会更快,因为它不需要检查类层次结构。
对于那些想知道原因,但不想阅读 < a href = “ https://stackoverflow. com/questions/184681/is-vs-typeof # 184697”> 是 vs typeof 中引用的文章的人。
如果他们不做同样的事情,哪个更快有关系吗?比较不同含义的语句的表现似乎不是一个好主意。
is告诉您对象是否在其类型层次结构中的任何位置实现了 ClassA。GetType()告诉您最派生的类型。
is
ClassA
GetType()
这不一样。
我做了一些基准测试,他们做相同的密封类型。
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<string, string>(c1); // ~178ms b = GetType2<string, string>(c1); // ~94ms b = Is<string, string>(c1); // ~70ms b = GetType1<string, Type>(c2); // ~178ms b = GetType2<string, Type>(c2); // ~96ms b = Is<string, Type>(c2); // ~65ms b = GetType1<string, object>(oc1); // ~190ms b = Is<string, object>(oc1); // ~69ms b = GetType1<string, object>(oc2); // ~180ms b = Is<string, object>(oc2); // ~64ms b = GetType1<int, int>(s1); // ~230ms b = GetType2<int, int>(s1); // ~75ms b = Is<int, int>(s1); // ~136ms b = GetType1<int, char>(s2); // ~238ms b = GetType2<int, char>(s2); // ~69ms b = Is<int, char>(s2); // ~142ms b = GetType1<int, object>(os1); // ~178ms b = Is<int, object>(os1); // ~69ms b = GetType1<int, object>(os2); // ~178ms b = Is<int, object>(os2); // ~69ms } sw.Stop(); MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
要测试泛型类型的泛型函数:
static bool GetType1<S, T>(T t) { return t.GetType() == typeof(S); } static bool GetType2<S, T>(T t) { return typeof(T) == typeof(S); } static bool Is<S, T>(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<Class1, Class1>(c1); // ~178ms b = GetType2<Class1, Class1>(c1); // ~98ms b = Is<Class1, Class1>(c1); // ~78ms b = GetType1<Class1, Class2>(c2); // ~178ms b = GetType2<Class1, Class2>(c2); // ~96ms b = Is<Class1, Class2>(c2); // ~69ms b = GetType1<Class1, object>(oc1); // ~178ms b = Is<Class1, object>(oc1); // ~69ms b = GetType1<Class1, object>(oc2); // ~178ms b = Is<Class1, object>(oc2); // ~69ms b = GetType1<Struct1, Struct1>(s1); // ~272ms b = GetType2<Struct1, Struct1>(s1); // ~140ms b = Is<Struct1, Struct1>(s1); // ~163ms b = GetType1<Struct1, Struct2>(s2); // ~272ms b = GetType2<Struct1, Struct2>(s2); // ~140ms b = Is<Struct1, Struct2>(s2); // ~163ms b = GetType1<Struct1, object>(os1); // ~178ms b = Is<Struct1, object>(os1); // ~64ms b = GetType1<Struct1, object>(os2); // ~178ms b = Is<Struct1, object>(os2); // ~64ms } sw.Stop(); MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
类型:
sealed class Class1 { } sealed class Class2 { } struct Struct1 { } struct Struct2 { }
推论:
在 struct上调用 GetType较慢。GetType是在 object类上定义的,它不能在子类型中重写,因此需要将 struct装箱以称为 GetType。
struct
GetType
object
在对象实例上,GetType更快,但是非常有限。
在泛型类型上,如果 T是 class,那么 is会快得多。如果 T是 struct,那么 is比 GetType快得多,但是 typeof(T)比两者都快得多。在 T为 class的情况下,typeof(T)是不可靠的,因为它不同于实际的基础型 class1。
T
class
typeof(T)
简而言之,如果您有一个 object实例,请使用 GetType。如果您有一个通用的 class类型,请使用 is。如果您有一个通用的 struct类型,请使用 typeof(T)。如果不确定泛型类型是引用类型还是值类型,请使用 is。如果您希望始终与一种样式保持一致(对于密封类型) ,请使用 is。.