2010-12-13 25 views
4

我在c#中遇到了一個反射問題,我無法找到答案。對繼承的泛型類型的反思

我有一個繼承自泛型的類,我試圖從這個類中獲取T的類型,但事實證明我不能!

這裏有一個例子:

class Products : List<Product> 
{} 

的問題是,在運行時,我不知道T的類型於是,我就得到這樣的類型:

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

它沒有解決。

這裏是我的方法:

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; 
    }   

的想法是讀取XML文件,並改造它的對象:在這種情況下

<?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> 

節點產品將是我收藏的繼承從名單

有關如何做到這一點的任何想法?

TKS傢伙

回答

6

Products類是不通用的,所以GetGenericArguments不返回任何東西。

你需要得到基本類型的通用參數,就像這樣:

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

然而,這不是彈性的;如果引入中間非通用基類型,它將失敗。
而應該找到IList<T>實現的類型參數。

例如:

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

謝謝SLaks!有效! – 2010-12-13 14:12:06

1

如果你只是想弄清楚的IList的類型是什麼,你應該使用這樣的事情:

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

這裏是你如何會在代碼中使用它:

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); 
    } 
}