Câu trả lời:
Điều này sẽ trả lời câu hỏi đó, và sau đó một số.
Dòng thứ hai, if (obj.GetType() == typeof(ClassA)) {}
nhanh hơn, dành cho những người không muốn đọc bài viết.
(Hãy lưu ý rằng họ không làm điều tương tự)
typeof(string).TypeHandle
theo lệnh ldtoken
CIL, nhưng có vẻ như CLR quan tâm đến nó trong JIT. Nó vẫn cần thêm một vài opcodes nhưng đó là một ứng dụng tối ưu hóa tổng quát hơn.
GetType
, is
luôn luôn là một lựa chọn an toàn hơn khi có liên quan đến hiệu suất. Tất nhiên họ làm những việc khác nhau.
object obj;
biến, không phải nó đã được đóng hộp khi điều này có xu hướng được thử nghiệm? Có trường hợp nào bạn cần kiểm tra loại của một cái gì đó và nó chưa được đóng hộp như một đối tượng?
Có vấn đề nào nhanh hơn không, nếu họ không làm điều tương tự? So sánh hiệu suất của các tuyên bố với ý nghĩa khác nhau có vẻ như là một ý tưởng tồi.
is
cho bạn biết nếu đối tượng thực hiện ClassA
bất cứ nơi nào trong kiểu thừa kế của nó. GetType()
cho bạn biết về loại có nguồn gốc nhất.
Không giống nhau.
Họ không làm điều tương tự. Cái đầu tiên hoạt động nếu obj thuộc loại ClassA hoặc của một số lớp con của ClassA. Cái thứ hai sẽ chỉ khớp với các đối tượng thuộc loại ClassA. Cái thứ hai sẽ nhanh hơn vì nó không phải kiểm tra thứ bậc của lớp.
Đối với những người muốn biết lý do, nhưng không muốn đọc bài viết được tham khảo trong là vs loại .
Tôi đã làm một số điểm chuẩn trong đó họ làm tương tự - các loại niêm phong.
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());
Các hàm chung để kiểm tra các loại chung:
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;
}
Tôi cũng đã thử các loại tùy chỉnh và kết quả phù hợp:
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());
Và các loại:
sealed class Class1 { }
sealed class Class2 { }
struct Struct1 { }
struct Struct2 { }
Sự suy luận:
Gọi GetType
trên struct
s chậm hơn. GetType
được định nghĩa trên object
lớp không thể bị ghi đè trong các loại phụ và do đó struct
cần phải được đóng hộp để được gọi GetType
.
Trên một đối tượng, GetType
nhanh hơn, nhưng rất ít.
Trên loại chung, nếu T
có class
, thì is
nhanh hơn nhiều. Nếu T
là struct
, thì is
nhanh hơn nhiều GetType
nhưng typeof(T)
nhanh hơn cả hai. Trong trường hợp T
tồn tại class
, typeof(T)
không đáng tin cậy vì nó khác với loại cơ bản thực tế t.GetType
.
Tóm lại, nếu bạn có một object
ví dụ, sử dụng GetType
. Nếu bạn có một loại chung class
, sử dụng is
. Nếu bạn có một loại chung struct
, sử dụng typeof(T)
. Nếu bạn không chắc chắn nếu loại chung là loại tham chiếu hoặc loại giá trị, hãy sử dụng is
. Nếu bạn muốn luôn nhất quán với một kiểu (đối với loại kín), hãy sử dụng is
..