2012-05-09 11 views
3

これは私がオブジェクトが直列化されたときに取得するXML出力です:XmlSerializerを使用して 'System.Numerics.Complex'をシリアル化する方法は?

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

Complex構造体は、直列化可能としてマークされ、構造体であること、それは暗黙のパラメータなしのコンストラクタを持っています。だから、なぜ各Complexオブジェクトがその実数部と虚数部を直列化しないのですか?それは構造体の'Real'と 'Imaginary'プロパティにゲッターがあり、セッターはないという事実と関係がありますか?

ありがとうございました。

+0

私はmsdnトピックにリンクしました。上記がうまくいかなかった場合は、これを見てください:http://msdn.microsoft.com/en-us/library/system.numerics.complex.aspx – alhazen

+0

あなたのComplex構造体にあるものを投稿してください。 –

+0

ええ、そうです、簡単に作り直すことができます。 –

答えて

2

XmlSerializerは、セッターを持たないプロパティをシリアル化しません(IIRCは、パブリックプロパティをpublic getterとsetterの両方でシリアライザのみにします)。あなたは(「完全な」性質を持っていると)作成タイプとSystem.Numerics.Complexタイプ

  • 変更複素数のシリアライズ(とデシリアライズを)処理する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); 
        } 
    } 
    
  • 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()); 
        } 
    } 
    

    私はこれがXmlSerializerがm_realComplex構造体内のm_imaginaryであるようにプライベートメンバーをシリアル化しないという事実によると思います。