C# is vs typeof
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/184681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
is vs typeof
提问by ilitirit
Which of these pieces of code is faster?
这些代码中哪一个更快?
if (obj is ClassA) {}
if (obj.GetType() == typeof(ClassA)) {}
Edit: I'm aware that they don't do the same thing.
编辑:我知道他们不做同样的事情。
采纳答案by MagicKat
This should answer that question, and then some.
The second line, if (obj.GetType() == typeof(ClassA)) {}
, is faster, for those that don't want to read the article.
第二行,if (obj.GetType() == typeof(ClassA)) {}
,对于那些不想阅读文章的人来说更快。
(Be aware that they don't do the same thing)
(请注意,他们不做同样的事情)
回答by tvanfosson
They don't do the same thing. The first one works if obj is of type ClassA or of some subclass of ClassA. The second one will only match objects of type ClassA. The second one will be faster since it doesn't have to check the class hierarchy.
他们不做同样的事情。如果 obj 是 ClassA 类型或 ClassA 的某个子类,则第一个有效。第二个将只匹配 ClassA 类型的对象。第二个会更快,因为它不必检查类层次结构。
For those who want to know the reason, but don't want to read the article referenced in is vs typeof.
对于那些想知道原因,但又不想阅读 中引用的文章的人 is vs typeof。
回答by Jay Bazuzi
Does it matter which is faster, if they don't do the same thing? Comparing the performance of statements with different meaning seems like a bad idea.
如果他们不做同样的事情,哪个更快是否重要?比较具有不同含义的语句的性能似乎是一个坏主意。
is
tells you if the object implements ClassA
anywhere in its type heirarchy. GetType()
tells you about the most-derived type.
is
告诉您对象是否ClassA
在其类型层次结构中的任何位置实现。 GetType()
告诉你最派生的类型。
Not the same thing.
不是一回事。
回答by nawfal
I did some benchmarking where they do the same - sealed types.
我做了一些基准测试,他们做同样的事情 - 密封类型。
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());
The generic functions to test for generic types:
用于测试泛型类型的泛型函数:
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;
}
I tried for custom types as well and the results were consistent:
我也尝试了自定义类型,结果是一致的:
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());
And the types:
和类型:
sealed class Class1 { }
sealed class Class2 { }
struct Struct1 { }
struct Struct2 { }
Inference:
推理:
Calling
GetType
onstruct
s is slower.GetType
is defined onobject
class which can't be overridden in sub types and thusstruct
s need to be boxed to be calledGetType
.On an object instance,
GetType
is faster, but very marginally.On generic type, if
T
isclass
, thenis
is much faster. IfT
isstruct
, thenis
is much faster thanGetType
buttypeof(T)
is much faster than both.In cases ofT
beingclass
,typeof(T)
is not reliable since its different from actual underlying typet.GetType
.
调用
GetType
的struct
s是慢。GetType
定义在object
不能在子类型中覆盖的类上,因此struct
s 需要装箱才能被调用GetType
。在对象实例上,
GetType
速度更快,但非常有限。在泛型类型上,如果
T
是class
,那么is
要快得多。如果T
是struct
,则比两者is
快得多,GetType
但typeof(T)
比两者都快得多。在案件T
之中class
,typeof(T)
是不是因为从实际的基本类型及其不同的可靠t.GetType
。
In short, if you have an object
instance, use GetType
. If you have a generic class
type, use is
. If you have a generic struct
type, use typeof(T)
. If you are unsure if generic type is reference type or value type, use is
. If you want to be consistent with one style always (for sealed types), use is
..
简而言之,如果您有object
实例,请使用GetType
. 如果您有泛型class
类型,请使用is
. 如果您有泛型struct
类型,请使用typeof(T)
. 如果您不确定泛型类型是引用类型还是值类型,请使用is
. 如果您想始终与一种样式保持一致(对于密封类型),请使用is
..