Cách kiểm tra xem kiểu của biến có khớp với Kiểu được lưu trữ trong một biến không


96
User u = new User();
Type t = typeof(User);

u is User -> returns true

u is t -> compilation error

Làm cách nào để kiểm tra xem một số biến thuộc loại nào đó theo cách này?

Câu trả lời:


194

Các câu trả lời khác đều có thiếu sót đáng kể.

Các isnhà điều hành không không kiểm tra xem loại thời gian chạy của các toán hạng là chính xác những loại nhất định; thay vào đó, nó sẽ kiểm tra xem kiểu thời gian chạy có tương thích với kiểu đã cho hay không:

class Animal {}
class Tiger : Animal {}
...
object x = new Tiger();
bool b1 = x is Tiger; // true
bool b2 = x is Animal; // true also! Every tiger is an animal.

Nhưng kiểm tra nhận dạng kiểu với kiểm tra phản chiếu để nhận dạng , không phải để tương thích

bool b5 = x.GetType() == typeof(Tiger); // true
bool b6 = x.GetType() == typeof(Animal); // false! even though x is an animal

or with the type variable
bool b7 = t == typeof(Tiger); // true
bool b8 = t == typeof(Animal); // false! even though x is an 

Nếu đó không phải là những gì bạn muốn, thì bạn có thể muốn IsAssignableFrom:

bool b9 = typeof(Tiger).IsAssignableFrom(x.GetType()); // true
bool b10 = typeof(Animal).IsAssignableFrom(x.GetType()); // true! A variable of type Animal may be assigned a Tiger.

or with the type variable
bool b11 = t.IsAssignableFrom(x.GetType()); // true
bool b12 = t.IsAssignableFrom(x.GetType()); // true! A 

4
Mặc dù cách tiếp cận cuối cùng được hiển thị ở đây hoạt động, nhưng nó không cần thiết phải dài dòng. typeof(Animal).IsInstanceOfType(x)ngắn hơn và đơn giản hơn typeof(Animal).IsAssignableFrom(x.GetType());(và Resharper sẽ đề xuất sử dụng cái trước nếu bạn sử dụng cái sau).
Mark Amery

XÁC NHẬN: để trả lời câu hỏi ban đầu, thay thế tcho typeof(Animal). Vì vậy, hình thức cải tiến của Mark trở thành t.IsInstanceOfType(x).
ToolmakerSteve

13

GetType()tồn tại trên mọi kiểu khuôn khổ đơn lẻ, bởi vì nó được định nghĩa trên objectkiểu cơ sở . Vì vậy, bất kể loại nào, bạn có thể sử dụng nó để trả vềType

Vì vậy, tất cả những gì bạn cần làm là:

u.GetType() == t

1
Trên thực tế câu trả lời của Eric là hữu ích và tất cả, nhưng không trả lời câu hỏi thực tế về cách kiểm tra với một loại không xác định theo cách "u là t" được mô tả trong câu hỏi ban đầu, và của bạn thì có.
Daniel

@Daniel - Không chính xác. Câu trả lời của Dave chỉ đúng nếu bạn muốn loại trừ các lớp con của t. Câu trả lời của Eric chủ yếu giải thích những việc phải làm; nó chỉ là thiếu làm rõ về nơi đặt "t". Tôi sẽ thêm một bình luận ở đó.
ToolmakerSteve

10

Bạn cần xem liệu Kiểu của cá thể của bạn có bằng Kiểu của lớp hay không. Để lấy loại phiên bản, bạn sử dụng GetType()phương pháp:

 u.GetType().Equals(t);

hoặc là

 u.GetType.Equals(typeof(User));

Hãy làm nó. Rõ ràng là bạn có thể sử dụng '==' để so sánh nếu muốn.


+1 Nhưng thích lựa chọn thứ hai hơn. u.GetType.Equals(typeof(User));
Omar

Một lý do khiến điều này kém an toàn hơn so với việc sử dụng == - là nếu GetType () bằng cách nào đó trả về null - nó sẽ ném.
Dave Bish

1
@Fuex, vâng, tôi nghĩ nó làm cho mã dễ đọc hơn nếu typeof là nội dòng, đó là lý do tại sao tôi đăng nó như vậy, mặc dù trong ví dụ OP, anh ấy đã có một biến tchứa kiểu.
Sam Holder

@DaveBish nếu GetType trả về null, thì tôi sẽ lo lắng rằng có rất nhiều thứ sẽ bắt đầu xảy ra ... nhưng thực tế là bạn đã đúng
Sam Holder

@SamHolder Yeah - Tình huống duy nhất này sẽ xảy ra, sẽ là nếu ai đó ghi đè một loại cơ sở và làm hỏng việc triển khai bằng cách nào đó. Chắc chắn là sẽ rất lạ.
Dave Bish

4

Để kiểm tra xem một đối tượng có tương thích với một biến kiểu nhất định hay không, thay vì viết

u is t

bạn nên viết

typeof(t).IsInstanceOfType(u)

1
Lợi ích của cú pháp dài dòng hơn so với cú pháp 'u là t' là gì?
Kyle Humfeld

@KyleHumfeld Nếu bạn có Type foo; Đối tượng A; bạn không thể viết "A là foo", nhưng bạn có thể viết foo.isInstanceOfType (A)
Timur Nuriyasov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.