Yanıtlar:
Bu, bu soruya ve sonra bazılarına cevap vermelidir.
İkinci satır,, if (obj.GetType() == typeof(ClassA)) {}
makaleyi okumak istemeyenler için daha hızlıdır.
(Aynı şeyi yapmadıklarını unutmayın)
typeof(string).TypeHandle
etmek ldtoken
CIL talimat, ancak CLR JIT içinde bunu halleder gibi görünüyor. Yine de birkaç ekstra opcodes gerekiyor, ancak optimizasyonun daha genel bir uygulaması.
GetType
, is
performansı söz konusu olduğunda kadarıyla olarak daha güvenli bir seçim her zaman olduğunu. Elbette farklı şeyler yapıyorlar.
object obj;
değişkeni test ettiğimiz göz önüne alındığında, bu test etme eğiliminde olduğunda zaten kutulu değil mi? Bir şeyin türünü test etmeniz gereken bir durum var mı ve zaten bir nesne olarak kutulu değil mi?
Aynı şeyi yapmazlarsa hangisinin daha hızlı olduğu önemli mi? İfadelerin performanslarını farklı anlamlarla karşılaştırmak kötü bir fikir gibi görünüyor.
is
nesnenin ClassA
kendi heirarchy türünde herhangi bir yerde uygulanıp uygulanmadığını söyler . GetType()
size en türetilmiş türü anlatır.
Aynı şey değil.
Aynı şeyi yapmıyorlar. İlki, ClassA türünde veya ClassA'nın bazı alt sınıflarındaysa çalışır. İkincisi sadece ClassA türündeki nesnelerle eşleşir. İkincisi, sınıf hiyerarşisini kontrol etmek zorunda olmadığından daha hızlı olacaktır.
Nedeni bilmek isteyenler için, ancak atıfta bulunulan makaleyi okumak istemeyenler için vs typeof .
Aynı mühürlü türleri yaptıkları yerde bazı kıyaslamalar yaptım.
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());
Genel türleri test etmek için genel fonksiyonlar:
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;
}
Özel türler için de denedim ve sonuçlar tutarlıydı:
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());
Ve türleri:
sealed class Class1 { }
sealed class Class2 { }
struct Struct1 { }
struct Struct2 { }
Çıkarım:
Arama GetType
üzerinde struct
s yavaştır. alt tiplerde geçersiz kılınamayan sınıfta GetType
tanımlanır object
ve bu nedenle struct
çağrılması için kutulu olması gerekir GetType
.
Bir nesne örneğinde, GetType
daha hızlı, ama çok marjinal.
Genel türü günü, eğer T
IS class
, o zaman is
çok daha hızlıdır. Eğer T
bir struct
, daha sonra is
çok daha hızlı daha GetType
ama typeof(T)
çok daha hızlı hem daha olduğunu. Durumlarında T
varlık class
, typeof(T)
gerçek temel türünden Farklı beri güvenilir değildir t.GetType
.
Kısacası, bir object
örneğiniz varsa kullanın GetType
. Genel bir class
türünüz varsa kullanın is
. Genel bir struct
türünüz varsa kullanın typeof(T)
. Genel türün başvuru türü veya değer türü olduğundan emin değilseniz kullanın is
. Her zaman bir stil ile tutarlı olmak istiyorsanız (mühürlü tipler için), kullanın is
..