3

Complex[]これは、オブジェクトがシリアル化されたときに取得するXML出力です。

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

Complex構造体はシリアライズ可能としてマークされており、構造体であるため、暗黙のパラメーターなしのコンストラクターがあります。では、なぜ各Complexオブジェクトはその実数部と虚数部をシリアル化しないのでしょうか。構造体の「Real」プロパティと「Imaginary」プロパティにはゲッターがありますが、セッターはありません。

ありがとう。

4

2 に答える 2

3

これは、オブジェクトのシリアル化に使用しているシリアライザーの実装によって異なります。
これを試してみると、期待どおりの結果が得られます。

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

m_realこれは、XmlSerializerがプライベートメンバーを(構造体のようm_imaginaryに)シリアル化しないという事実によるものだと思いますComplex

于 2012-05-09T20:19:40.513 に答える
2

XmlSerializer、セッターを持たないプロパティをシリアル化しません(IIRCは、パブリックゲッターとセッターの両方を使用してパブリックプロパティをシリアル化するだけです)。いくつかのオプションがあります。

  • System.Numerics.Complexタイプを自分で作成したタイプに置き換えます(「full」プロパティがあります)
  • MyClassインターフェイスを介して、複素数のシリアル化(および逆シリアル化)を処理するようにクラスを変更しIXmlSerializableます。

2番目のオプションを以下に示します。

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);
    }
}
于 2012-05-09T20:59:58.467 に答える