Getting all ICollection properties through reflection

c#, reflection

Solution

It turns out that with IsAssignableFrom check you can't find whether the interface is a derivative of another interface:

Console.WriteLine(typeof(ICollection<>).IsAssignableFrom(typeof(ICollection<Int32>)));     
Console.WriteLine(typeof(ICollection<Int32>).IsAssignableFrom(typeof(ICollection<>)));

will both write false;

With little help from here this is the best solution I can come of:

    static IEnumerable<PropertyInfo> GetICollectionOrICollectionOfTProperties(this Type type)
    {    
        // Get properties with PropertyType declared as interface
        var interfaceProps =
            from prop in type.GetProperties()
            from interfaceType in prop.PropertyType.GetInterfaces()
            where interfaceType.IsGenericType
            let baseInterface = interfaceType.GetGenericTypeDefinition()
            where (baseInterface == typeof(ICollection<>)) || (baseInterface == typeof(ICollection))
            select prop;

        // Get properties with PropertyType declared(probably) as solid types.
        var nonInterfaceProps =
            from prop in type.GetProperties()
            where typeof(ICollection).IsAssignableFrom(prop.PropertyType) || typeof(ICollection<>).IsAssignableFrom(prop.PropertyType)
            select prop;

        // Combine both queries into one resulting
        return interfaceProps.Union(nonInterfaceProps);                
    }

This solution may yield some duplicates(it is hardly possible, but to be sure use `Distinct`) and it doesn't look very nice.

But it works well on such class with properties with both the interface return types and concrete return types :

    class Collections
    {
        public List<Int32> ListTProp
        {
            get;
            set;
        }

        public IDictionary<Int32, String> IDictionaryProp
        {
            get;
            set;
        }

        public ICollection ICollectionProp
        {
            get;
            set;
        }

        public ICollection<DateTime> IDateTimeCollectionProp
        {
            get;
            set;
        }
    }

Problem

I'm trying to fetch all `ICollection<T>` properties from class of unknown type. Also, type T (what the collection is of) is not known at compile time. Firstly I've tried this approach: ``` foreach (var property in entity.GetType().GetProperties()) { if (typeof(ICollection).IsAssignableFrom(property.PropertyType) || typeof(ICollection<>).IsAssignableFrom(property.PropertyType)) { // do something } } ``` but it's not working (evaluating false even for `ICollection` properties). I got it working like this: ``` foreach (var property in entity.GetType().GetProperties()) { var getMethod = property.GetGetMethod(); var test = getMethod.Invoke(entity, null); if (test is ICollection) { // do something } } ``` but I do not want to execute all getters. Why is the first piece of code not working? How can I find `ICollection` properties without executing all getters?

Original source

Related problems