2011-08-15 42 views
5

Tôi có một phương thức lấy tham số đầu vào là một đối tượng thuộc loại IEnumerable. Tôi muốn liệt kê các liệt kê và cho mỗi mục sử dụng phản ánh để có được giá trị cho mỗi tài sản.Tại sao Type.GetElementType trả về null?

Tôi có đoạn mã sau:

protected void WriteData(IEnumerable data) 
{ 
    var enumerationTypeInfo = data.GetType(); 
    var itemTypeInfo = enumerationTypeInfo.GetElementType(); 

    ... 
} 

Vấn đề là enumerationTypeInfo.GetElementType() luôn trả null. Đặc biệt, tôi đang chuyển một số List<Entry> vào WriteData, trong đó Entry là lớp tôi đã tạo. Khi tôi sử dụng trình gỡ lỗi và đặt điểm ngắt, tôi có thể thấy rằng enumerationTypeInfo hiển thị chính xác rằng đó là Danh sách loại Entry, nhưng tại sao GetElementType trả lại null?

Cảm ơn

Trả lời

7

GetElementType được sử dụng với mảng chứ không phải các lớp chung khác. Để nhận các thông số chung của một loại generic, bạn có thể sử dụng Type.GetGenericArguments.

+0

Hơn nữa - GetElementType sẽ luôn trả về giá trị rỗng nếu được sử dụng trên loại chung. Xem bài viết MSDN tại http://msdn.microsoft.com/en-us/library/system.type.getelementtype.aspx – EtherDragon

12

GetElementType() trả về loại phần tử của mảng. List<T> không phải là loại mảng và do đó không có "loại phần tử".

Nếu bạn muốn nhận được các loại của các yếu tố ngẫu nhiên IEnumerable<T> sản xuất, hãy thử một cái gì đó như thế này:

public static Type GetEnumerableType(Type type) 
{ 
    if (type == null) 
     throw new ArgumentNullException("type"); 

    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) 
     return type.GetGenericArguments()[0]; 

    var iface = (from i in type.GetInterfaces() 
       where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>) 
       select i).FirstOrDefault(); 

    if (iface == null) 
     throw new ArgumentException("Does not represent an enumerable type.", "type"); 

    return GetEnumerableType(iface); 
} 

Lưu ý rằng các loại có thể thực hiện nhiều hơn một phiên bản của giao diện chung cùng; một loại có thể thực hiện cả hai ví dụ IEnumerable<int>IEnumerable<string>. Cách bạn xử lý trường hợp đó tùy thuộc vào bạn. Phương pháp tôi cung cấp sẽ mất bất cứ kiểu giao diện nào mà thời gian chạy sẽ đưa nó trước.


Xem an example using the above method trên ideone.

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