我如何判断一个Type是否实现IList <>?
我想写一个使用反射的方法来判断给定的类型是否实现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
在我的用法中,我可以假设类型将始终是一个实例化的泛型类型(或者根本不是泛型的)。
不幸的是,这并不像它应该那样容易。 明显的解决方案:
public bool IsGenericList(Type type)
{
return typeof(IList<>).IsAssignableFrom(type);
}
不起作用; 它总是返回false。 显然,像IList<>
这样的非实例化的泛型类型不会像我期望的那样实现IsAssignableFile: IList<>
不能从List<T>
赋值。
我也试过这个:
public bool IsGenericList(Type type)
{
if (!type.IsGenericType)
return false;
var genericTypeDefinition = type.GetGenericTypeDefinition();
return typeof(List<>).IsAssignableFrom(genericTypeDefinition);
}
即,将type
转换为非实例化的泛型,如IList<int>
- > IList<>
,然后再次尝试IsAssignableFrom。 当type是一个实例化的IList<T>
,如IList<int>
, IList<object>
等时,它将返回true。但是,对于实现IList<T>
类,如List<int>
, ObservableCollection<double>
等等,显然IList<>
不能从List<>
赋值。 再次,不是我所期望的。
我如何着手编写IsGenericList并使它像上面的例子一样工作?
事实上,你不能拥有一个泛型类型定义的实例。 因此,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;
}
出于好奇,你需要做什么?
我也想测试一个类型是否为某些T实现了IList<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));
}
使用这个:http://msdn.microsoft.com/en-us/library/system.type.findinterfaces.aspx
我试过这个:
public class Test : IList<string>
{
//implementation left out...
}
class Program
{
static void Main(string[] args)
{
Test t = new Test();
TypeFilter myFilter = new TypeFilter(MyInterfaceFilter);
Type type = t.GetType();
Type[] x = type.FindInterfaces(myFilter, "System.Collections.Generic.IList");
Console.WriteLine(x.Length);
}
public static bool MyInterfaceFilter(Type typeObj, Object criteriaObj)
{
if (typeObj.ToString().Contains(criteriaObj.ToString()))
return true;
else
return false;
}
}
链接地址: http://www.djcxy.com/p/57399.html