2009-07-24 49 views
5

Tôi có một phương pháp mà chấp nhận một tham số obj loại System.ObjectCách tốt nhất để kiểm tra xem một Type là một bộ sưu tập

Bây giờ tôi muốn kiểm tra xem loại thực tế của obj là:

  • Loại bộ sưu tập (IEnumerable).
  • Mọi thứ khác.

Cách đầu tiên tôi nghĩ đến là:

if (obj is IEnumerable) 
    // obj is a collection 

Nhưng System.String thực hiện IEnumerable và Tôi không muốn để điều trị chuỗi như một bộ sưu tập.

Cách thứ hai tôi nghĩ là thử nghiệm cho ICollection thay vì IEnumerable, vì IEnumerable có nhiều khả năng thu thập hơn so với thực tế. Điều này sẽ bỏ chuỗi, nhưng cũng ICollection-Of-T bởi vì nó không kế thừa ICollection (IEnumerable-Of-T là trừu tượng duy nhất bộ sưu tập chung đó là tương thích ngược - nó kế thừa IEnumerable).

Vì vậy, tôi đoán cách tốt nhất là:

if (obj is string) 
    // not a collection 
else if (obj is IEnumerable) 
    // collection 
else 
    // not a collection 

Có cách nào tốt hơn?

+0

Tôi xem có thể đếm là SEQUENCES, không phải là COLLECTIONS. Có thể có một sự khác biệt tinh tế trong ý nghĩa ở đó; vì tôi không biết ứng dụng của bạn, tôi không biết liệu đó có phải là vấn đề không. Chúng tôi phải đối mặt với vấn đề này khi thiết kế bộ khởi tạo bộ sưu tập. Có rất nhiều "bộ sưu tập" mà không thực hiện ICollection, và có rất nhiều đối tượng mà thực hiện Thêm mà không phải là bộ sưu tập. (Đối tượng toán học, thông thường.) Chúng tôi quyết định sử dụng một heuristic. Nếu một loại thực hiện cả IEnumerable và có phương thức Add public thì đó có thể là một collection. Đây là một chút ngốc nghếch, nhưng trong thực tế nó hoạt động. –

+0

Đây là tài nguyên có liên quan tốt về tóm tắt bộ sưu tập: http://blogs.msdn.com/brada/archive/2005/01/18/355755.aspx –

Trả lời

6

Tôi nghĩ bạn đã quá phức tạp một chút. Nếu bạn thực sự muốn sử dụng IEnumerable nhưng loại trừ System.String, tại sao không chỉ làm điều đó trực tiếp trong mã?

public static bool IsCollection(object obj) { 
    return obj is IEnumerable && !(obj is String); 
} 
+0

Điều này có vẻ là cách duy nhất để làm điều đó. Tôi nghĩ rằng khi những kẻ BCL thiết kế loại String họ không nhận ra IEnumerable quan trọng như thế nào sẽ trở thành cách duy nhất để chỉ bất kỳ bộ sưu tập nào. –

5

Nếu bạn thực sự chỉ muốn kiểm tra: (? Tại sao, bằng cách này)

bool isCollection = obj.GetType().GetInterfaces() 
    .Any(iface => iface.GetGenericTypeDefinition() == typeof(ICollection<>)) 

Nhưng thẳng thắn mà nói, nếu bạn thực sự chỉ muốn đặc biệt hợp cụ thể string, sau đó chỉ cần làm như vậy. Nếu bạn thử nghiệm cho ICollection<>, bạn sẽ coi kết quả của truy vấn LINQ là "không thu thập", chẳng hạn, vì không có lý do chính đáng.

+0

Hoặc 'obj.GetType(). GetInterface (" System.Collections .IEnumerable ")! = Null' – xr280xr

Các vấn đề liên quan