Reputation: 1670
I need to use reflection to filter out all object properties that are collections. They are not always just generic lists, but a class that inherits a List<T>
type. So as an example, I have a class foo
with property of type fooCollection
. FooColection
looks like the following:
public class foo
{
public FooCollection myCollection {get;set;}
}
public class fooCollection : List<Foo>
{
}
I do not know what to expect as the type of List<T>
, but only need to know if it is a collection. How can I find this out? I asked a prior question, but worded it differently, and the results were not working with my particular instance.
I have tried examples such as the following, where I look through all properties of foo
, and try to find the property that is fooColelction
:
typeof(IEnumerable<>).IsAssignableFrom(prop.PropertyType)
This is not working properly for me though. The type is not IEnumerable
, though it is a collection. It inherits an IEnumerable
type.
Here is an example of one of the Collection classes for a class object called 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);
}
}
}
This is different then a prior question because I am asking how to check this scenario for a property type that is a regular class, that Inherits List<T>
, not a property that is List<T>
.
Upvotes: 0
Views: 1425
Reputation: 63722
The main problem is that a non-reified generic type (such as IEnumerable<>
) can never be assigned anything. .NET generics simply don't work this way.
Instead, you could use something like this:
typeof(PolicyCollection)
.GetInterfaces()
.Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))
GetInterfaces
returns all the interfaces which are implemented by the given type, and then you simply check if there's anything that's an IEnumerable<>
. By explicitly un-reifying the found generic interfaces, we can do a simple comparison with IEnumerable<>
(or IList<>
or whichever you prefer).
And of course, since IEnumerable<>
also "requires" IEnumerable
, you can simply check for that instead of the generic interface:
typeof(IEnumerable).IsAssignableFrom(typeof(PolicyCollection));
Upvotes: 2