Joe*_*ite 16 .net generics reflection
我想编写一个方法,使用Reflection来判断给定的Type是否实现IList<T>.例如:
IsGenericList(typeof(int)) // should return false
IsGenericList(typeof(ArrayList)) // should return false
IsGenericList(typeof(IList<int>)) // should return true
IsGenericList(typeof(List<int>)) // should return true
IsGenericList(typeof(ObservableCollection<int>)) // should return true
Run Code Online (Sandbox Code Playgroud)
在我的用法中,我可以假设类型将始终是实例化的泛型类型(或者根本不是通用的类型).
不幸的是,这并不像它应该的那么容易.明显的解决方案:
public bool IsGenericList(Type type)
{
return typeof(IList<>).IsAssignableFrom(type);
}
Run Code Online (Sandbox Code Playgroud)
不起作用; 它总是返回false.显然,非实例化的泛型类型IList<>不会像我期望的那样实现IsAssignable:IList<>不能从中分配List<T>.
我也试过这个:
public bool IsGenericList(Type type)
{
if (!type.IsGenericType)
return false;
var genericTypeDefinition = type.GetGenericTypeDefinition();
return typeof(List<>).IsAssignableFrom(genericTypeDefinition);
}
Run Code Online (Sandbox Code Playgroud)
即,type转换为非实例化的泛型,如IList<int>- > IList<>,然后再次尝试IsAssignableFrom.当类型是一个实例化将返回true IList<T>,如IList<int>,IList<object>等,但它返回实现类错误IList<T>,如List<int>,ObservableCollection<double>等,这样显然IList<>是不分配List<>.再一次,不是我所期望的.
我如何编写IsGenericList并使其工作如上例所示?
Luc*_*ero 26
实际上,您不能拥有泛型类型定义的实例.因此,IsAssignableFrom()方法按预期工作.要实现您的目标,请执行以下操作:
public bool IsGenericList(Type type)
{
if (type == null) {
throw new ArgumentNullException("type");
}
foreach (Type @interface in type.GetInterfaces()) {
if (@interface.IsGenericType) {
if (@interface.GetGenericTypeDefinition() == typeof(ICollection<>)) {
// if needed, you can also return the type used as generic argument
return true;
}
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
出于好奇,你需要做什么?
Col*_*nic 15
我也想测试一个类型是否IList<T>为某些T 实现了.我对Lucero的答案做了明显的改变,但它引起了原始答案中不存在的微妙错误.这是我的最终编辑:
/// <summary>
/// Test if a type derives from IList of T, for any T.
/// </summary>
public bool TestIfGenericList(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
var interfaceTest = new Predicate<Type>(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>));
return interfaceTest(type) || type.GetInterfaces().Any(i => interfaceTest(i));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9744 次 |
| 最近记录: |