Jawaban:
Ini harus menjawab pertanyaan itu, dan kemudian beberapa.
Baris kedua,, if (obj.GetType() == typeof(ClassA)) {}
lebih cepat, bagi mereka yang tidak ingin membaca artikel.
(Ketahuilah bahwa mereka tidak melakukan hal yang sama)
typeof(string).TypeHandle
dengan ldtoken
instruksi CIL, tetapi sepertinya CLR mengurusnya di JIT. Masih membutuhkan beberapa opcodes tambahan tetapi ini merupakan aplikasi optimisasi yang lebih umum.
GetType
, is
selalu merupakan pilihan yang lebih aman sejauh menyangkut kinerja. Tentu saja mereka melakukan hal yang berbeda.
object obj;
variabel, bukankah sudah boxed ketika ini cenderung diuji? Apakah ada kasus di mana Anda perlu menguji jenis sesuatu dan itu belum dikotakkan sebagai objek?
Apakah penting yang lebih cepat, jika mereka tidak melakukan hal yang sama? Membandingkan kinerja pernyataan dengan makna berbeda sepertinya ide yang buruk.
is
memberi tahu Anda jika objek mengimplementasikan ClassA
di mana saja dalam jenis heirarki. GetType()
memberi tahu Anda tentang jenis yang paling diturunkan.
Bukan hal yang sama.
Mereka tidak melakukan hal yang sama. Yang pertama berfungsi jika obj adalah tipe ClassA atau beberapa subclass dari ClassA. Yang kedua hanya akan cocok dengan objek bertipe ClassA. Yang kedua akan lebih cepat karena tidak harus memeriksa hierarki kelas.
Bagi mereka yang ingin tahu alasannya, tetapi tidak ingin membaca artikel yang dirujuk adalah vs typeof .
Saya melakukan benchmarking di mana mereka melakukan jenis yang sama - disegel.
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());
Fungsi generik untuk menguji tipe generik:
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;
}
Saya mencoba jenis kustom juga dan hasilnya konsisten:
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());
Dan jenisnya:
sealed class Class1 { }
sealed class Class2 { }
struct Struct1 { }
struct Struct2 { }
Kesimpulan:
Memanggil GetType
di struct
s lebih lambat. GetType
didefinisikan pada object
kelas yang tidak dapat diganti dalam sub tipe dan dengan demikian struct
perlu dikotak untuk dipanggil GetType
.
Pada instance objek, GetType
lebih cepat, tetapi sangat marginal.
Pada jenis generik, jika T
yaitu class
, maka is
jauh lebih cepat. Jika T
ini struct
, maka is
jauh lebih cepat daripada GetType
tetapi typeof(T)
jauh lebih cepat dari keduanya. Dalam kasus T
sedang class
, typeof(T)
tidak dapat diandalkan karena berbeda dari tipe yang mendasarinya sebenarnya t.GetType
.
Singkatnya, jika Anda memiliki sebuah object
instance, gunakan GetType
. Jika Anda memiliki class
tipe generik , gunakan is
. Jika Anda memiliki struct
tipe generik , gunakan typeof(T)
. Jika Anda tidak yakin apakah tipe generik adalah tipe referensi atau tipe nilai, gunakan is
. Jika Anda ingin konsisten dengan satu gaya selalu (untuk tipe tertutup), gunakan is
..