通过reflection获取所有ICollection属性

我正在尝试从未知类型的类中获取所有ICollection属性。 此外,在编译时不知道类型T(集合的内容)。 首先我尝试过这种方法:

 foreach (var property in entity.GetType().GetProperties()) { if (typeof(ICollection).IsAssignableFrom(property.PropertyType) || typeof(ICollection).IsAssignableFrom(property.PropertyType)) { // do something } } 

但它不起作用(即使对于ICollection属性也要评估为false)。

我得到它像这样工作:

 foreach (var property in entity.GetType().GetProperties()) { var getMethod = property.GetGetMethod(); var test = getMethod.Invoke(entity, null); if (test is ICollection) { // do something } } 

但我不想执行所有的getter。 为什么第一段代码不起作用? 如何在不执行所有getter的情况下找到ICollection属性?

事实certificate,使用IsAssignableFrom检查您无法找到该接口是否是另一个接口的衍生物:

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

都会写错 ;

在这里没有什么帮助,这是我能得到的最佳解决方案:

  static IEnumerable 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 ListTProp { get; set; } public IDictionary IDictionaryProp { get; set; } public ICollection ICollectionProp { get; set; } public ICollection IDateTimeCollectionProp { get; set; } } 

在尝试使用接受的答案后,我遇到的情况是只返回部分匹配。 我的对象有3个ICollection属性,我只返回2.我花了一些时间测试并试图找出原因,但我继续写下这个:

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

我已经使用相同的测试用例进行了测试,并且我从此方法返回了正确的结果。

这不会获取非通用的ICollections,但OP确实要求ICollection属性,尽管它可以很容易地重新考虑包括在内。 它也不会返回不完全属于ICollection类型的属性(即,在他的测试用例中不会返回Eugene的List和IDictionary(但是再次,OP想要的是什么))。