如何使用 XmlSerializer 序列化“System.Numerics.Complex”
本文关键字:Numerics Complex System 何使用 XmlSerializer 序列化 | 更新日期: 2023-09-27 18:33:36
这是我在序列化Complex[]
对象时得到的XML输出:
<MyClass>
<Complex />
<Complex />
<Complex />
<Complex />
</MyClass>
Complex 结构被标记为可序列化,并且作为一个结构,它有一个隐式的无参数构造函数。那么为什么每个复杂对象不序列化其真实和虚部呢?它是否与结构的"实数"和"虚数"属性有getters但没有setters有关?
谢谢。
这取决于用于序列化对象的序列化程序的实现。
如果你尝试这个,你会得到你所期望的:
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 不会序列化私有成员(就像Complex
结构中的m_real
和m_imaginary
一样)。
XmlSerializer
不序列化没有 setter 的属性(IIRC 它只序列化具有公共 getter 和 setter 的公共属性)。您有以下几种选择:
- 将
System.Numerics.Complex
类型替换为您创建的类型(并且具有"full"属性) - 更改
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);
}
}