通过反射确定 class 属性 是否是继承 List<T> 的对象或任何类型的集合
Determine with reflection if a class property is an object that inherits List<T> or any type of collection
我需要使用反射来过滤掉所有作为集合的对象属性。它们并不总是只是通用列表,而是继承了 List<T>
类型的 class。例如,我有一个 class foo
和 属性 类型 fooCollection
。 FooColection
如下所示:
public class foo
{
public FooCollection myCollection {get;set;}
}
public class fooCollection : List<Foo>
{
}
我不知道 List<T>
的类型是什么,但只需要知道它是否是一个集合。我怎样才能找到这个?我问了一个先前的问题,但措辞不同,结果不适用于我的特定实例。
我试过如下示例,我查看了 foo
的所有属性,并尝试找到 属性 即 fooColelction
:
typeof(IEnumerable<>).IsAssignableFrom(prop.PropertyType)
虽然这对我来说工作不正常。类型不是 IEnumerable
,尽管它是一个集合。它继承了 IEnumerable
类型。
这是一个名为 Policy
.
的 class 对象的集合 classes 之一的示例
public class PolicyCollection : List<Policy>
{
/// <summary>
/// This function takes a xml Policy collection and builds a PolicyCollection Class
/// </summary>
/// <param name="xDocPolicyCollection">XML Document of an PolicyCollection</param>
protected internal void LoadXml(XmlDocument xDocPolicyCollection)
{
foreach (XmlNode n in xDocPolicyCollection.GetElementsByTagName("Policy"))
{
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(n.OuterXml);
Policy p = new Policy();
p.LoadXml(xdoc);
Add(p);
}
}
/// <summary>
/// This function takes a datatable of Policies collection and builds a PolicyCollection Class
/// </summary>
/// <param name="dtContact">Data</param>
protected internal void LoadDB(DataTable dtPolicyCollection)
{
foreach (DataRow dr in dtPolicyCollection.Rows)
{
Policy p = new Policy();
p.LoadDB(dr);
Add(p);
}
}
}
这与之前的问题不同,因为我问的是如何检查这种情况下的 属性 类型,它是常规 class,继承 List<T>
,而不是 属性 即 List<T>
.
主要问题是非具体化的泛型类型(例如 IEnumerable<>
)永远不会 被赋值任何东西。 .NET 泛型根本无法以这种方式工作。
相反,你可以使用这样的东西:
typeof(PolicyCollection)
.GetInterfaces()
.Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))
GetInterfaces
returns all 由给定类型实现的接口,然后您只需检查是否有任何东西是 IEnumerable<>
.通过显式取消具体化找到的通用接口,我们可以与 IEnumerable<>
(或 IList<>
或您喜欢的任何一个)进行简单比较。
当然,由于 IEnumerable<>
也 "requires" IEnumerable
,您可以简单地检查它而不是通用接口:
typeof(IEnumerable).IsAssignableFrom(typeof(PolicyCollection));
我需要使用反射来过滤掉所有作为集合的对象属性。它们并不总是只是通用列表,而是继承了 List<T>
类型的 class。例如,我有一个 class foo
和 属性 类型 fooCollection
。 FooColection
如下所示:
public class foo
{
public FooCollection myCollection {get;set;}
}
public class fooCollection : List<Foo>
{
}
我不知道 List<T>
的类型是什么,但只需要知道它是否是一个集合。我怎样才能找到这个?我问了一个先前的问题,但措辞不同,结果不适用于我的特定实例。
我试过如下示例,我查看了 foo
的所有属性,并尝试找到 属性 即 fooColelction
:
typeof(IEnumerable<>).IsAssignableFrom(prop.PropertyType)
虽然这对我来说工作不正常。类型不是 IEnumerable
,尽管它是一个集合。它继承了 IEnumerable
类型。
这是一个名为 Policy
.
public class PolicyCollection : List<Policy>
{
/// <summary>
/// This function takes a xml Policy collection and builds a PolicyCollection Class
/// </summary>
/// <param name="xDocPolicyCollection">XML Document of an PolicyCollection</param>
protected internal void LoadXml(XmlDocument xDocPolicyCollection)
{
foreach (XmlNode n in xDocPolicyCollection.GetElementsByTagName("Policy"))
{
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(n.OuterXml);
Policy p = new Policy();
p.LoadXml(xdoc);
Add(p);
}
}
/// <summary>
/// This function takes a datatable of Policies collection and builds a PolicyCollection Class
/// </summary>
/// <param name="dtContact">Data</param>
protected internal void LoadDB(DataTable dtPolicyCollection)
{
foreach (DataRow dr in dtPolicyCollection.Rows)
{
Policy p = new Policy();
p.LoadDB(dr);
Add(p);
}
}
}
这与之前的问题不同,因为我问的是如何检查这种情况下的 属性 类型,它是常规 class,继承 List<T>
,而不是 属性 即 List<T>
.
主要问题是非具体化的泛型类型(例如 IEnumerable<>
)永远不会 被赋值任何东西。 .NET 泛型根本无法以这种方式工作。
相反,你可以使用这样的东西:
typeof(PolicyCollection)
.GetInterfaces()
.Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))
GetInterfaces
returns all 由给定类型实现的接口,然后您只需检查是否有任何东西是 IEnumerable<>
.通过显式取消具体化找到的通用接口,我们可以与 IEnumerable<>
(或 IList<>
或您喜欢的任何一个)进行简单比较。
当然,由于 IEnumerable<>
也 "requires" IEnumerable
,您可以简单地检查它而不是通用接口:
typeof(IEnumerable).IsAssignableFrom(typeof(PolicyCollection));