2014-10-31 1 views
3

클래스의 속성 이름이 XML의 노드 이름과 일치하는 XML 파일에서 파생 된 클래스가있는 응용 프로그램이 있습니다. 리플렉션 (내가 채택한 stackoverflow에서 찾은 일부 코드)을 사용하여이 클래스를 채울 수 있습니다. 본질적으로 XML 노드의 모든 자식 노드를 열거하고 해당 클래스의 해당 속성 이름을 가져오고 설정하려고합니다. 이것은 충분히 잘 작동합니다. XML 직렬화가이 문제에 대한 더 나은 해결책 일 수 있다는 것을 이해하는 동안, 나는 내가 가진 것에 대해서는 괜찮습니다. 제 질문은 인구가 많은 수업에서 제가하는 일입니다.C에서 generic 클래스의 사전을 만드는 도우미 메서드

XML을 읽으면 주어진 클래스의 인스턴스 200 개로 변환되는 노드 200 개가 생깁니다. 나는 이것들을 사전에 저장하고 싶다. 그런 다음 다른 클래스의 인스턴스를 100 개 생성하는 또 다른 XML을 작성하고이를 다른 사전에 저장하려고합니다. 다음과 같이

나는 XML을 구문 분석하는 데 사용하는 코드는 다음과 같습니다

Dictionary<string, Book> oBookCollection = new Dictionary<string, Book>(); 
XML_File_Reader oDoc = new XML_File_Reader(@"C:\apps\bookList.xml"); 
if (oDoc.IsDocumentValid) 
{ 
    XmlNodeList oList = oDoc.GetList("Row"); 
    if (oList.Count !=0) 
    foreach (XmlNode xn in oList) 
    { 

     XmlNode oThisNode = xn; 
     Book oThisBook = new Book(oMyLibrary, oThisNode); 

     oDoc.MigrateXMLtoObject(oBuilding, oThisNode); 
     oBookCollection .Add(oBook.BookName, oBook); 

    } 

} 
oDoc = null; 

당신이 볼 수 있듯이,이 특정 클래스 유형에 특정 참조를 가지고있다. 책과 같이 DVD 및 완구 용 XML을 쉽게 채울 수있는 일반적인 방법을 사용할 수 있기를 원합니다.

정보의 경우, 기존의 "MigrateXMLtoObject"루틴은 다음과 같다 : 나는이 책을 만들고있다 생각했습니다

public void MigrateXMLtoObject(object myObject, XmlNode node) 
    { 
     if (node == null) 
     { 
      return; 
     } 

     PropertyInfo propertyInfo; 
     IEnumerator list = node.GetEnumerator(); 
     XmlNode tempNode; 

     while (list.MoveNext()) 
     { 
      tempNode = (XmlNode)list.Current; 

      propertyInfo = myObject.GetType().GetProperty(tempNode.Name); 


      if (propertyInfo != null) 
      { 
       if (propertyInfo.PropertyType == typeof(DateTime)) 
       { 
        DateTime val = DateTime.MinValue; 
        DateTime.TryParse(tempNode.InnerText, out val); 
        propertyInfo.SetValue(myObject, val, null); 
       } 
       else if (propertyInfo.PropertyType == typeof(Int32)) 
       { 
        int val = 0; 
        Int32.TryParse(tempNode.InnerText, out val); 
        propertyInfo.SetValue(myObject, val, null); 
       } 
       else if (propertyInfo.PropertyType == typeof(bool)) 
       { 
        bool val = false; 
        Boolean.TryParse(tempNode.InnerText, out val); 
        propertyInfo.SetValue(myObject, val, null); 
       } 
       else if (propertyInfo.PropertyType == typeof(string)) 
       { 
        string val = ""; 
        val = tempNode.InnerText; 
        propertyInfo.SetValue(myObject, val, null); 
       } 
       else 
       { 
        propertyInfo.SetValue(myObject, tempNode.Value, null); 
       } 
      } 

     } 
    } 

일을 등 DVD는 공통 기본 클래스에서 상속하지만, 생각하지 않습니다 메서드에 BaseClass를 전달하면 속성을 일치시키기 위해 리플렉션을 사용하려고 할 때 파생 클래스가 아니라 기본 클래스의 속성이됩니다.

그런 다음 여기에서 검색을 한 다음 Generics 사용에 대한 언급을 보았습니다. 불행히도, 사전 <> 및 목록 <> 개체를 사용하는 동안 불행히도, 나는 내 자신의 Generic을 작성한 적이 없으므로 사용 방법을 모르거나 실제로 찾고있는 솔루션인지는 알 수 없습니다.

나는이 쓰기 않았고, 분명히 그것은 컴파일되지 않습니다/작동하지 않습니다,하지만 사람들이 올바른 방향으로 날 밀어하는 것이 유용한 조각이 될 수 있습니다

public Dictionary<string, T> MigrateXMLtoObject<T>(string xmlPath, MyLibrary oLibrary) 
    { 
     Dictionary<string, T> oDictionary = new Dictionary<string, T>(); 

     XML_File_Reader oDoc = new XML_File_Reader(xmlPath); 
     if (oDoc.IsDocumentValid) 
     { 
      XmlNodeList oList = oDoc.GetList("Row"); 
      if (oList.Count != 0) 
       foreach (XmlNode xn in oList) 
       { 

        XmlNode oThisNode = xn; 
        //T othisItem = new T(oLibrary, oThisNode); 

        oDoc.MigrateXMLtoObject(T, oThisNode); 
        oDictionary.Add(T.Type, T); 

       } 

     } 
     oDoc = null; 

     return oDictionary; 
    } 

내가 어떤 종류의가 필요하십니까 'switch'를 사용하여 T를 평가하고 해당 기본 클래스를 만드시겠습니까?

감사합니다.

답변

1

더 이상 문맥이 없으면 어떤 것이 가장 잘 작동하는지 정확히 알기가 어렵습니다. 그러나 순진, 여기에 내가 좋을 것 무엇 :이 같은 호출

public Dictionary<string, T> MigrateXMLtoObject<T>(
    string xmlPath, MyLibrary oLibrary, Func<MyLibrary, XmlNode, T> factory) 
{ 
    Dictionary<string, T> oDictionary = new Dictionary<string, T>(); 

    XML_File_Reader oDoc = new XML_File_Reader(xmlPath); 
    if (oDoc.IsDocumentValid) 
    { 
     XmlNodeList oList = oDoc.GetList("Row"); 
     if (oList.Count != 0) 
      foreach (XmlNode xn in oList) 
      { 

       XmlNode oThisNode = xn; 
       T thisItem = factory(oLibrary, oThisNode); 

       // It's not really clear to me what you wanted to do 
       // here. If the object constructor is handling applying 
       // the node data to the object, you shouldn't need to 
       // "migrate" more, right? And the dictionary seems to 
       // want to add the object as the value, with the key 
       // being some text. Where do you get the key? 
       //oDoc.MigrateXMLtoObject(T, oThisNode); 
       oDictionary.Add(objectKey, thisItem); 

      } 

    } 
    oDoc = null; 

    return oDictionary; 
} 

:

MigrateXMLtoObject(xmlPath, library, (l, n) => new Book(l, n)); 

참고 만 생성자에 전달하는 목적으로 MyLibrary 객체를 전달하는 경우 이 방법에서는 메서드 매개 변수로이 메서드가 필요하지 않습니다. 대신 팩토리 델리게이트로 빌드 할 수 있습니다. 예 :

MigrateXMLtoObject(xmlPath, node => new Book(library, n)); 

나는 "o"가 변수 이름의 접두사를 없애는 것이 좋습니다. 도움이 안되요.:)

+0

이 감사합니다 - 당신이. 나는이있는 플레이를해야하고 어디에 있는지 ..

public void SayMyType(BaseClass obj) { Console.Write(obj.GetType())//will output the type of object 'DerivedClass' not the parameter 'BaseClass ' } SayMyType(new DerivedClass()) 

때문에 상속이 길을 가야하는 것입니다 .. :(잘못된 생각 (실제로 Function Delegates를 사용하지 않았기 때문에 이것은 훌륭한 학습 경험입니다!) Key는 실제로 다행스럽게도 노드 요소이며 Book & DVD 클래스에서는 "Type"이라고 불립니다. 이것은 어리석은 이름입니다 ... XML 노드에서 새로 생성 된 클래스에서 가져 오려고하지 않고 가져옵니다. 마이그레이션 문제에서 개체 생성자가 전달됩니다. MyLibrary는 효과적으로 부모 역할을합니다. – ainwood

0

나는 내가하는 방법에 BaseClass로를 통과하면 때문에, 등 DVD는 공통 기본 클래스에서 상속,하지만 그건 아닌 것 같다 책을 만들고 간주 한 일들이 때 그것은 반사를 사용하여 속성을 일치 시키려고 시도합니다. 파생 클래스가 아니라 기본 클래스의 속성이됩니다.

미안하지만, 당신은

관련 문제