我试图从未知类型的类中获取所有ICollection<T>
属性。此外,类型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
属性?
答案 0 :(得分:4)
事实证明,通过IsAssignableFrom检查,您无法确定界面是否是其他界面的衍生物:
Console.WriteLine(typeof(ICollection<>).IsAssignableFrom(typeof(ICollection<Int32>)));
Console.WriteLine(typeof(ICollection<Int32>).IsAssignableFrom(typeof(ICollection<>)));
都会写 false ;
在here的帮助不大的情况下,这是我能提出的最佳解决方案:
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;
}
}
答案 1 :(得分:0)
在尝试使用接受的答案后,我遇到了只返回部分匹配的情况。我的对象有3个$('#Menu').load('menu.html');
$('#CommentSection').load('comments.html');
属性,我只用2回来。我花了一些时间测试并试图找出原因,但我继续写下这个:
ICollection<T>
我已经使用相同的测试用例进行了测试,并且我从此方法返回了正确的结果。
这不会获取非通用的ICollections,但是OP确实要求public static IEnumerable<PropertyInfo> GetICollectionProperties(object entity)
{
return entity.GetType().GetProperties()
.Where(p => p.PropertyType.IsGenericType
&& p.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>));
}
属性,尽管它可以很容易地重新考虑包括在内。它也不会返回不完全属于ICollection类型的属性(即Eugene的List和IDictionary在他的测试用例中不会被返回(但是再次,OP想要的))。