Getting all ICollection properties through reflection

I am trying to extract all properties ICollection<T>from a class of an unknown type. Also, the type T (what the collection has) is unknown at compile time. First, I 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 does not work (false value even for properties ICollection).

I started 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 do all getters. Why does the first part of the code not work? How to find properties ICollectionwithout executing all getters?

+4
source share
2 answers

It turns out that with IsAssignableFrom to check, it is not possible to determine if the interface is derived from another interface:

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

false;

, :

    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);                
    }

( , , , Distinct), .

, , :

    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;
        }
    }
+4

, . 3 ICollection<T> , 2. , , :

public static IEnumerable<PropertyInfo> GetICollectionProperties(object entity) 
{
    return entity.GetType().GetProperties()
            .Where(p => p.PropertyType.IsGenericType
            && p.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>));
}

, , .

ICollections, OP ICollection<T>, , . , ICollection (.. Eugene IDictionary ( , OP)).

0

Source: https://habr.com/ru/post/1547329/


All Articles