我如何判断一个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

上一篇: How do I tell whether a Type implements IList<>?

下一篇: Additonal button on AvalonDock control