通过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想要的是什么))。