The previously accepted answer là đẹp, nhưng nó là sai. Rất may, lỗi là một lỗi nhỏ. Kiểm tra IEnumerable
là không đủ nếu bạn thực sự muốn biết về phiên bản chung của giao diện; có rất nhiều lớp chỉ thực hiện giao diện nongeneric. Tôi sẽ trả lời trong một phút. Thứ nhất, tuy nhiên, tôi muốn chỉ ra rằng câu trả lời được chấp nhận là quá phức tạp, vì đoạn mã sau sẽ đạt được cùng một trong các trường hợp đưa ra:
if (items[key] is IEnumerable)
này không nhiều hơn bởi vì nó hoạt động cho từng hạng mục riêng biệt (và không thuộc phân lớp chung của chúng, V
).
Bây giờ, để có giải pháp đúng. Đây là một chút phức tạp hơn bởi vì chúng ta phải lấy chung loại IEnumerable`1
(có nghĩa là, loại IEnumerable<>
với tham số một loại) và tiêm lập luận chung phải:
static bool IsGenericEnumerable(Type t) {
var genArgs = t.GetGenericArguments();
if (genArgs.Length == 1 &&
typeof(IEnumerable<>).MakeGenericType(genArgs).IsAssignableFrom(t))
return true;
else
return t.BaseType != null && IsGenericEnumerable(t.BaseType);
}
Bạn có thể kiểm tra tính chính xác của mã này một cách dễ dàng :
var xs = new List<string>();
var ys = new System.Collections.ArrayList();
Console.WriteLine(IsGenericEnumerable(xs.GetType()));
Console.WriteLine(IsGenericEnumerable(ys.GetType()));
sản lượng:
True
False
Đừng quá lo lắng bởi thực tế rằng đây sử dụng phản ánh. Trong khi đó là sự thật rằng điều này cho biết thêm chi phí thời gian chạy, do đó, việc sử dụng toán tử is
.
Tất nhiên mã trên bị hạn chế hết sức và có thể được mở rộng thành phương thức áp dụng chung hơn, IsAssignableToGenericType
. Việc triển khai sau đây hơi không chính xác và tôi sẽ để nó ở đây cho mục đích lịch sử chỉ. Không sử dụng nó.Thay vào đó, James has provided an excellent, correct implementation in his answer.
public static bool IsAssignableToGenericType(Type givenType, Type genericType) {
var interfaceTypes = givenType.GetInterfaces();
foreach (var it in interfaceTypes)
if (it.IsGenericType)
if (it.GetGenericTypeDefinition() == genericType) return true;
Type baseType = givenType.BaseType;
if (baseType == null) return false;
return baseType.IsGenericType &&
baseType.GetGenericTypeDefinition() == genericType ||
IsAssignableToGenericType(baseType, genericType);
}
Nó thất bại khi genericType
cũng giống như givenType
; vì lý do tương tự, nó không thành công đối với các loại không có giá trị, tức là
IsAssignableToGenericType(typeof(List<int>), typeof(List<>)) == false
IsAssignableToGenericType(typeof(int?), typeof(Nullable<>)) == false
Tôi đã tạo một gist with a comprehensive suite of test cases.
Đây chính xác là những gì tôi đang tìm kiếm. Cảm ơn! Nó vẫn sử dụng sự phản chiếu, nhưng tôi đang tìm cú pháp "typeof (IEnumerable <>)". Cảm ơn! –
Không có cách nào khác để thực hiện việc kiểm tra loại, ngoài việc sử dụng "là"? –
dòng cuối cùng nên đọc 'return (baseType.IsGenericType && baseType.GetGenericTypeDefinition() == genericType) || IsAssignableToGenericType (baseType, genericType); 'Bạn không thể tránh đệ quy chỉ vì lớp cơ sở là chung chung. –