【问题标题】:Factory to send xml strings over the wire工厂通过网络发送 xml 字符串
【发布时间】:2011-05-05 22:00:01
【问题描述】:

代码中解释了我的目标...
但它的要点是我想读取 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);
}

【问题讨论】:

  • 你试过[XmlInclude(...)]吗?我只是想在继续之前检查...
  • 您基本上是在尝试从收到的 XML 创建任何类型;除非您努力检查 XML 并尝试解析类型,然后尝试反序列化为该类型,否则这注定会失败。
  • 不,我没有想到。我在 msdn 上查找了它,所以我会用 XmlInclude (allMyChildTypes) 修饰我的基类?重点是我想通过网络发送 xml 并在另一端重建它。

标签: c# xml xml-serialization factory xmlserializer


【解决方案1】:

泛型。这对你想做的事情有用吗?

如果您试图避免指定要反序列化的对象的类型,则不能;它决定了用于反序列化对象的代码。

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

【讨论】:

  • 我认为您不需要在这里使用通用代码。将Parent.ToXml() 中的typeof(T) 替换为GetType() 也可以。
  • 是的,适用于示例代码;但是,如果您需要创建一个可以反序列化任何类的工厂类,那么泛型是生成反序列化类型的最简单方法。
  • 对不起,这对我不起作用。工厂可以接收的唯一输入是原始 xml。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-02
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多