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?