【问题标题】:How to serialize 'System.Numerics.Complex' using an XmlSerializer?如何使用 XmlSerializer 序列化“System.Numerics.Complex”?
【发布时间】:2012-05-09 19:42:04
【问题描述】:

这是我在序列化Complex[] 对象时得到的 XML 输出:

<MyClass>               
    <Complex />
    <Complex />
    <Complex />
    <Complex />
</MyClass>

Complex 结构被标记为可序列化,并且作为一个结构,它有一个隐式的无参数构造函数。那么为什么不是每个 Complex 对象都序列化它的实部和虚部呢?这是否与结构的'Real' 和'Imaginary' 属性有getter 但没有setter 的事实有关?

谢谢。

【问题讨论】:

标签: c# xml arrays xml-serialization


【解决方案1】:

这取决于您用于序列化对象的序列化程序的实现。
如果你试试这个,你会得到你所期望的:

using System.IO;
using System.Numerics;
using System.Runtime.Serialization.Formatters.Soap;

public class Test {
    public static void Main() {
        var c = new Complex(1, 2);
        Stream stream = File.Open("data.xml", FileMode.Create);
        SoapFormatter formatter = new SoapFormatter();
        formatter.Serialize(stream, c);
        stream.Close();
    }
}

相反,如果您使用 System.Xml.Serialization 命名空间中的类,您将获得与您发布的内容类似的内容:

using System;
using System.IO;
using System.Numerics;
using System.Xml.Serialization;

public class Test {
    public static void Main() {
        var c = new Complex(1, 2);
        XmlSerializer s = new XmlSerializer(typeof(Complex));
        StringWriter sw = new StringWriter();
        s.Serialize(sw, c);
        Console.WriteLine(sw.ToString());
    }
}

我认为这是因为 XmlSerializer 不会序列化私有成员(m_realm_imaginary 结构中的 Complex 也是如此)。

【讨论】:

    【解决方案2】:

    XmlSerializer 不会序列化没有 setter 的属性(IIRC 它只序列化具有公共 getter 和 setter 的公共属性)。您有几个选择:

    • System.Numerics.Complex 类型替换为您创建的类型(并且具有“完整”属性)
    • 更改MyClass 类以通过IXmlSerializable 接口处理复数的序列化(和反序列化)。

    第二个选项如下所示。

    public class StackOverflow_10523009
    {
        public class MyClass : IXmlSerializable
        {
            public Complex[] ComplexNumbers;
    
            public XmlSchema GetSchema()
            {
                return null;
            }
    
            public void ReadXml(XmlReader reader)
            {
                reader.ReadStartElement("MyClass");
                List<Complex> numbers = new List<Complex>();
                while (reader.IsStartElement("Complex"))
                {
                    Complex c = new Complex(
                        double.Parse(reader.GetAttribute("Real")),
                        double.Parse(reader.GetAttribute("Imaginary")));
                    numbers.Add(c);
                    reader.Skip();
                }
    
                reader.ReadEndElement();
                this.ComplexNumbers = numbers.ToArray();
            }
    
            public void WriteXml(XmlWriter writer)
            {
                foreach (var complex in ComplexNumbers)
                {
                    writer.WriteStartElement("Complex");
                    writer.WriteStartAttribute("Real"); writer.WriteValue(complex.Real); writer.WriteEndAttribute();
                    writer.WriteStartAttribute("Imaginary"); writer.WriteValue(complex.Imaginary); writer.WriteEndAttribute();
                    writer.WriteEndElement();
                }
            }
    
            public override string ToString()
            {
                return "MyClass[" + string.Join(",", ComplexNumbers) + "]";
            }
        }
        public static void Test()
        {
            MyClass mc = new MyClass { ComplexNumbers = new Complex[] { new Complex(3, 4), new Complex(0, 1), new Complex(1, 0) } };
            XmlSerializer xs = new XmlSerializer(typeof(MyClass));
            MemoryStream ms = new MemoryStream();
            xs.Serialize(ms, mc);
            Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
            ms.Position = 0;
            MyClass mc2 = (MyClass)xs.Deserialize(ms);
            Console.WriteLine(mc2);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-18
      • 2019-03-13
      相关资源
      最近更新 更多