2011-05-05 20 views
1

什麼我會在代碼解釋...
但它的JIST是我想讀的子類在XML中堅持:廠通過線路發送XML字符串

abstract class Parent { 
    virtual string ToXml() 
    { 
     XmlSerializer xml = XmlSerializer(typeof (this)); 
     ... 
     return xmlString; 
    } 

    virtual void FromXml(string rawXml) 
    { 
     //either memberwise copy or throw exception if wrong type 
     ... 
    } 
} 

sealed class Child1 : Parent 
{ 
    [XmlElement("Prop1")] 
    public Property1 { get; set; } 

    public Child1() { } 
} 

sealed class Child2 : Parent 
{ 
    [XmlElement("Prop2")] 
    public Property1 { get; set; } 

    public Child2() { } 
} 

static void main() 
{ 
    string flatChild1 = new Child1().ToXml(); 
    string flatChild2 = new Child2().ToXml(); 

    // some time goes by 
    ... 

    Child1 one = new Child1(); 
    Child2 two = new Child2(); 

    one.FromXml(flatChild1); //must be "child one" string or exception 
    two.FromXml(flatChild2); 

    //one.FromXml(flatChild2); !! invalid 

    /* 
     what i want is some sort of factory... 

     sealed class MyFactory 
     { 
     static Parent MyFactory.FromXml(string xmlObject); 
     } 

    */ 
    Parent obj1 = MyFactory.FromXml(flatChild1); 
    Parent obj2 = MyFactory.FromXml(flatChild2); 

    Assert.IsInstanceOfType(obj1, Child1.GetType()); 
    Assert.IsInstanceOfType(obj2, Child2.GetType()); 
} 

* *編輯**

我想發送XML通過線路,所以是這樣的:

// Server.exe Project 
server_SendChild1Message() 
{ 
    byte[] data = Encoding.UTF16.GetBytes(child1.ToXml()); 
    server.tcpClient[0].write(data, 0, data.Length); 
} 

// Seperate Client.exe 
client_ReadMessages() 
{ 
    string s = getNextXmlMessage(); 
    //needs to create a Child1 or Child2 based on xml string 
    BaseXmlObj b = Factory.objFromXml(s); 
} 
+0

你試過'[XmlInclude(...)]'?我只想在繼續之前進行檢查... – 2011-05-05 22:07:05

+0

您基本上正在嘗試從您收到的XML創建任何類型;除非通過檢查XML並嘗試解析某個類型然後嘗試將該類型反序列化,否則這注定會失敗。 – Tejs 2011-05-05 22:15:57

+0

不,我沒有想到這一點。我在msdn上查找它,所以我會用XmlInclude(allMyChildTypes)裝飾我的基類?關鍵是我想通過電線發送xml並在另一側重新構建它。 – 2011-05-06 00:14:49

回答

0

泛型。這是否適用於你想要做的事情?

如果您試圖避免指定要反序列化的對象的類型,則不能;它決定了用於反序列化對象的代碼。

abstract class Parent<T> where T : Parent<T> { 
    virtual string ToXml() 
    { 
     XmlSerializer xml = XmlSerializer(typeof (T)); 
     ... 
     return xmlString; 
    } 

    virtual void FromXml(string rawXml) 
    { 
     //either memberwise copy or throw exception if wrong type 
     ... 
    } 
} 

sealed class Child1 : Parent<Child1> 
{ 
    [XmlElement("Prop1")] 
    public Property1 { get; set; } 

    public Child1() { } 
} 

sealed class Child2 : Parent<Child1> 
{ 
    [XmlElement("Prop2")] 
    public Property1 { get; set; } 

    public Child2() { } 
} 

static void main() 
{ 
    string flatChild1 = new Child1().ToXml(); 
    string flatChild2 = new Child2().ToXml(); 

    // some time goes by 
    ... 

    Child1 one = new Child1(); 
    Child2 two = new Child2(); 

    one.FromXml(flatChild1); //must be "child one" string or exception 
    two.FromXml(flatChild2); 

    //one.FromXml(flatChild2); !! invalid 

    /* 
     what i want is some sort of factory... 

     sealed class MyFactory<T> 
     { 
     static T MyFactory.FromXml(string xmlObject); 
     } 

    */ 
    Child1 obj1 = MyFactory<Child1>.FromXml(flatChild1); 
    Child2 obj2 = MyFactory<Child2>.FromXml(flatChild2); 

    Assert.IsInstanceOfType(obj1, Child1.GetType()); 
    Assert.IsInstanceOfType(obj2, Child2.GetType()); 
} 
+0

我不認爲你需要在這裏使用通用代碼。用'GetType()'替換'Parent.ToXml()'中的'typeof(T)'也可以。 – 2011-05-05 23:06:40

+0

是的,這適用於示例代碼;但是,如果您需要創建一個將反序列化任何類的工廠類,那麼泛型是生成反序列化類型的最簡單方法。 – 2011-05-06 11:56:50

+1

對不起,這不適合我。工廠可以接收的唯一輸入是原始xml。 – 2011-05-06 13:54:12