通过反射获取所有 ICollection 属性 [英] Getting all ICollection properties through reflection
问题描述
我正在尝试从未知类型的类中获取所有 ICollection
属性.此外,类型 T(集合是什么)在编译时是未知的.首先,我尝试过这种方法:
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
}
}
但它不起作用(即使对于 ICollection
属性也评估 false).
but it's not working (evaluating false even for ICollection
properties).
我是这样工作的:
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
属性?
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?
推荐答案
事实证明,使用 IsAssignableFrom 检查你找不到接口是否是另一个接口的派生:
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<>)));
两者都会写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);
}
此解决方案可能会产生一些重复项(几乎不可能,但请务必使用 Distinct
),而且看起来不太好.
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;
}
}
这篇关于通过反射获取所有 ICollection 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!