2012-02-24 34 views
30

Làm cách nào để xác định xem thuộc tính có phải là một loại mảng hay không.Xác định xem thuộc tính có phải là loại mảng không bằng cách phản ánh

Ví dụ:

public bool IsPropertyAnArray(PropertyInfo property) 
{ 
    // return true if type is IList<T>, IEnumerable<T>, ObservableCollection<T>, etc... 
} 
+1

Vì vậy, bạn có nghĩa là, nếu thuộc tính là tập hợp? Những điều phù hợp với bình luận của bạn không phải là mảng. –

+2

Bạn có thể có nghĩa là 'IEnumerable' thay vì' IEnumerator'? – Groo

+0

@Ben: Vâng, mảng phù hợp với tiêu chí của mình (IList và IEnumerable ), nhưng không phải tất cả mọi thứ phù hợp với tiêu chí của anh đều là mảng.:) – Sven

Trả lời

54

Dường như bạn đang hỏi hai câu hỏi khác nhau: một loại có phải là một mảng hay không (ví dụ: string[]) hoặc bất kỳ loại bộ sưu tập nào.

Đối với trường hợp cũ, chỉ cần kiểm tra property.PropertyType.IsArray.

Đối với trường hợp thứ hai, bạn phải quyết định tiêu chí tối thiểu bạn muốn loại phù hợp. Ví dụ: bạn có thể kiểm tra số không chung chung IEnumerable bằng cách sử dụng typeof(IEnumerable).IsAssignableFrom(property.PropertyType). Bạn cũng có thể sử dụng điều này cho các giao diện chung nếu bạn biết loại T thực tế, ví dụ: typeof(IEnumerable<int>).IsAssignableFrom(property.PropertyType).

Kiểm tra chung IEnumerable<T> hoặc bất kỳ giao diện chung nào khác mà không biết giá trị của T có thể được thực hiện bằng cách kiểm tra xem property.PropertyType.GetInterface(typeof(IEnumerable<>).FullName) không phải là null. Lưu ý rằng tôi đã không chỉ định bất kỳ loại nào cho T trong mã đó. Bạn có thể làm tương tự cho IList<T> hoặc bất kỳ loại khác mà bạn đang quan tâm đến

Ví dụ, bạn có thể sử dụng sau đây nếu bạn muốn kiểm tra sự chung IEnumerable<T>:.

public bool IsPropertyACollection(PropertyInfo property) 
{ 
    return property.PropertyType.GetInterface(typeof(IEnumerable<>).FullName) != null; 
} 

Mảng cũng thực hiện IEnumerable, vì vậy họ cũng sẽ trả lại true từ phương thức đó.

+1

Việc triển khai này sẽ bỏ lỡ "bộ sưu tập trường học cũ", được kế thừa từ .Net 1 và thực hiện IEnumerable nhưng không phải là phiên bản chung IEnumerable . Chúng ít được sử dụng hơn, nhưng một số API mong đợi chúng, và chúng thực sự là một nỗi đau. – Falanwe

+1

@Falanwe: Sau đó, sử dụng phương pháp đầu tiên tôi đã đề cập, mà không kiểm tra IEnumerable không chung chung. Nó thực sự phụ thuộc vào yêu cầu của anh ấy là tốt nhất. – Sven

+1

Tôi thử phương pháp của bạn với một thuộc tính là một chuỗi và phương thức trả về true ... Bạn có biết tại sao không? – Melursus

11

Nếu bạn muốn biết nếu tài sản là một mảng, nó thực sự rất dễ dàng:

property.PropertyType.IsArray; 

chỉnh sửa

Nếu bạn muốn biết nếu đó là một loại thực hiện IEnumerable, cũng giống như tất cả "loại bộ sưu tập", nó cũng không phức tạp lắm:

return property.PropertyType.GetInterface("IEnumerable") != null; 
+0

Tôi không chắc chắn đó là những gì OP thực sự muốn (nhưng tôi thừa nhận đặt tên là một chút gây hiểu lầm). Loại tùy chỉnh triển khai 'IList ' sẽ trả về false từ thuộc tính này. – Groo

+0

thực sự, tôi đã đọc sai câu hỏi ban đầu. Tôi đã chỉnh sửa câu trả lời của mình để bao gồm bất kỳ IEnumerable – Falanwe

+2

@Falanwe: 'IsSubclassOf' không hoạt động cho các giao diện, chỉ có các lớp cơ sở. – Sven

2
public static bool IsGenericEnumerable(Type type) 
    { 
     return type.IsGenericType && 
      type.GetInterfaces().Any(
      ti => (ti == typeof (IEnumerable<>) || ti.Name == "IEnumerable")); 
    } 

    public static bool IsEnumerable(Type type) 
    { 
     return IsGenericEnumerable(type) || type.IsArray; 
    } 
0

Đối với tôi, đây là không làm việc,

return property.PropertyType.GetInterface(typeof(ICollection<>).FullName) != null; 

sau đây được làm việc,

typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition()) 

Đây là cách tắt để kiểm tra ICollection<IInterface> hoặc ICollection<BaseClassInTree>

var property = request as PropertyInfo; 

property.PropertyType.IsGenericType && (typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition())) && typeof().IsAssignableFrom(property.PropertyType.GenericTypeArguments[0]) 
16

Exclu ding String lớp vì nó đủ điều kiện làm bộ sưu tập vì nó triển khai IEnumerable<char>.

public bool IsPropertyACollection(this PropertyInfo property) 
{ 
    return (!typeof(String).Equals(property.PropertyType) && 
     typeof(IEnumerable).IsAssignableFrom(property.PropertyType)); 
} 
+0

typeof (Chuỗi) là séc tôi bị thiếu –

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