2010-12-13 3 views
4

C#의 리플렉션에 문제가있어 답변을 찾을 수 없습니다.상속 된 일반 형식을 통한 리플렉션

제네릭 형식에서 상속하는 클래스가 있는데이 클래스에서 T 형식을 검색하려고하지만 그럴 수 없다는 것이 밝혀졌습니다!

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

그것을 : 그래서 이런 유형을 얻기 위해 노력

class Products : List<Product> 
{} 

문제는 런타임에 내가 T.의 종류를 알 수 없다는 것입니다 : 여기

은 예입니다 잘 풀리지 않았다. 노드 제품이 상속 내 컬렉션 것,이 경우

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

:

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 파일을 읽고 객체에 변환하는 것입니다 : 여기

내 방법입니다 목록에서

어떻게하는 방법에 대한 아이디어?

TKS들

답변

6

Products 클래스는 너무 GetGenericArguments 아무것도 반환하지 않습니다 일반 없습니다.

는이 같은 기본 유형의 일반적인 인수를 얻을 필요가 :

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

그러나,이 탄력 아니다; 중개자가 아닌 일반 기본 유형이 도입되면 실패합니다.
대신 IList<T> 구현의 type 매개 변수를 찾아야합니다.

예를 들어

:

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

감사합니다 SLaks! 그것은 일했다! –

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); 
    } 
} 
관련 문제