Фабрика для отправки XML-строк по проводам - PullRequest
1 голос
/ 06 мая 2011

То, что я иду, объясняется в коде ...
но суть в том, что я хочу читать дочерние классы, сохраненные в 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);
}

1 Ответ

0 голосов
/ 06 мая 2011

Дженерики.Это работает для того, что вы пытаетесь сделать?

Если вы пытаетесь избежать указания типа объекта для десериализации, вы не можете;он определяет код, используемый для десериализации объекта.

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