Reflection over inherited generic types

I have a reflection problem in C # and I can not find the answer.

I have a class that inherits from a generic type, and I'm trying to extract type T from this class, but it turns out I can't!

Here is an example:

class Products : List<Product> {} 

The problem is that at runtime I don't know the type of T. So I tried to get this type:

 Type itemsType = destObject.GetType().GetGenericArguments()[0] 

This did not work.

Here is my method:

 public static object Deserialize(Type destType, XmlNode xmlNode) { object destObject = Activator.CreateInstance(destType); foreach (PropertyInfo property in destType.GetProperties()) foreach (object att in property.GetCustomAttributes(false)) if (att is XmlAttributeAttribute) property.SetValue(destObject, xmlNode.Attributes[property.Name].Value, null); else if (att is XmlNodeAttribute) { object retObject = Deserialize(property.PropertyType, xmlNode.Nodes[property.Name]); property.SetValue(destObject, retObject, null); } if (destObject is IList) { Type itemsType = destObject.GetType().GetGenericArguments()[0]; foreach (XmlNode xmlChildNode in xmlNode.Nodes) { object retObject = Deserialize(itemsType, xmlNode); ((IList)destObject).Add(retObject); } } return destObject; } 

The idea is to read the xml file and convert it to an object:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <SETTINGS> <PRODUCTS> <PRODUCT NAME="ANY" VERSION="ANY" ISCURRENT="TRUE" /> <PRODUCT NAME="TEST1" VERSION="ANY" ISCURRENT="FALSE" /> <PRODUCT NAME="TEST2" VERSION="ANY" ISCURRENT="FALSE" /> </PRODUCTS> <DISTRIBUTIONS> <DISTRIBUTION NAME="5.32.22" /> </DISTRIBUTIONS> </SETTINGS> 

in this case node PRODUCT will be my collection that inherits from List

any ideas on how to do this?

tks guys

+4
source share
2 answers

The Products class is not common, so GetGenericArguments nothing.

You need to get general arguments of the base type, for example:

 Type itemType = destObject.GetType().BaseType.GetGenericArguments()[0]; 

However, this is not resilient; if an intermediate non-generic base type is introduced, it will fail.
Instead, you should find an implementation type parameter IList<T> .

For instance:

 Type listImplementation = destObject.GetType().GetInterface(typeof(IList<>).Name); if (listImplementation != null) { Type itemType = listImplementation.GetGenericArguments()[0]; ... } 
+6
source

If you are just trying to figure out what the IList type is, you should use something like this:

Type itemsType = destType.GetInterface(typeof(IList<>).Name).GetGenericArguments()[0];

Here is how you could use it in your code:

 var interface = destType.GetInterface(typeof(IList<>).Name); var destList = destObject as IList; // make sure that the destination is both IList and IList<T> if (interface != null && destList != null) { Type itemsType = interface.GetGenericArguments()[0]; foreach (XmlNode xmlChildNode in xmlNode.Nodes) { object retObject = Deserialize(itemsType, xmlNode); destList.Add(retObject); } } 
+1
source

All Articles