này xảy ra vì một List<int>
không phải là một List<object>
- các loại List không hiệp biến trong tham số loại nguyên tố của nó. Đáng tiếc là bạn sẽ cần phải nhận được một phiên bản đánh máy của phương pháp chung chung và gọi nó là sử dụng phản ánh:
Type listItemType = typeof(int); // cheating for simplicity - see below for real approach
MethodInfo openMethod = typeof(Extension).GetMethod("ToDataTable", ...);
MethodInfo typedMethod = openMethod.MakeGenericMethod(typeof(listItemType));
typedMethod.Invoke(null, new object[] { list });
Một thay thế có thể để tạo ra một phiên bản của phương pháp mở rộng của bạn chấp nhận IList
hơn IList<T>
. Lớp List<T>
thực hiện giao diện này không chung chung cũng như giao diện chung, vì vậy bạn sẽ có thể gọi:
public static DataTable WeakToDataTable(this IList list) { ... }
((IList)list).WeakToDataTable();
(Trên thực tế bạn muốn có thể sử dụng một quá tải chứ không phải là một cái tên khác - chỉ cần sử dụng một tên khác nhau để gọi ra các loại khác nhau)
Thông tin thêm:. trong giải pháp phản xạ, tôi bỏ qua vấn đề làm thế nào để xác định loại nguyên tố danh sách. Điều này có thể hơi phức tạp tùy thuộc vào mức độ tinh vi mà bạn muốn nhận. Nếu bạn đang giả định rằng đối tượng sẽ là một List<T>
(đối với một số T) sau đó thật dễ dàng:
Type listItemType = list.GetType().GetGenericArguments()[0];
Nếu bạn chỉ sẵn sàng để đảm nhận IList<T>
thì đó là một chút khó khăn hơn, bởi vì bạn cần phải xác định vị trí thích hợp giao diện và nhận được đối số chung từ đó. Và bạn không thể sử dụng GetInterface() vì bạn đang tìm kiếm một cá thể được xây dựng khép kín của một giao diện chung. Vì vậy, bạn phải lăn qua tất cả các giao diện tìm kiếm một trong đó là một thể hiện của IList<T>
:
foreach (Type itf in list.GetType().GetInterfaces())
{
if (itf.IsGenericType && itf.GetGenericTypeDefinition == typeof(IList<>)) // note generic type definition syntax
{
listItemType = itf.GetGenericArguments()[0];
}
}
này sẽ làm việc cho các danh sách trống rỗng, vì nó đi ra khỏi siêu dữ liệu, không phải là nội dung danh sách.
Tại sao bạn truyền vào 'Danh sách
Bởi vì anh ta không biết tại thời gian biên dịch loại danh sách anh ta có: anh ta không biết đó là 'Danh sách'. Anh ấy đang cố gắng thu thập nó bằng cách chuyển sang một lớp cơ sở (như bạn lưu ý đúng, sẽ không hoạt động vì 'List ' không tương thích với 'List