2017-11-24 6 views
0

ファイルからオブジェクトをデシリアライズすると、等しい参照を持つフィールドには同じ参照がありません。SerializeObject/DeSerializeObject参照をエスケープします

これは一例です:

この例では、私はタイプAからオブジェクトa1を作成しました。ファイルに保存してa2という名前の新しいオブジェクトにロードしました。 a1では同じ(同じ参照)ですb1b2は私がa1.b1.x = 5;を設定する際に、a1.b2.xの値も5に変更され、そこにあるが、私はa2.b1.x = 5;を設定する際にセーブ/ロードした後、a2.b2.xの値は変更されません! !!

using System; 
using System.Xml; 
using System.Xml.Serialization; 
using System.IO; 
using System.Windows.Forms; 

namespace test 
{ 
    public class SerializeObjectTest 
    { 
     public static void Test() 
     { 
      var a1 = new A(); 
      a1.init(); 
      SerializeObject<A>(a1, "d:\\1.xml"); 
      var a2 = DeSerializeObject<A>("d:\\1.xml"); 
      a1.b1.x = 5; // this will change also the value of a1.b2.x 
      a2.b1.x = 5; // this will not!!!!! change also the value of a2.b2.x 
      MessageBox.Show(
       "a1.b1.x==a1.b2.x : " + a1.b1.x + "?=" + a1.b2.x + "\r\n" + 
       "a2.b1.1==a2.b2.x : " + a2.b1.x + "?=" + a2.b2.x + " !!\r\n", "Save.SaveAble" 
       ); 
     } 

     public class A 
     { 
      public void init() 
      { 
       b1 = new B() { x = 100 }; 
       b2 = b1; 
      } 
      public B b1; 
      public B b2; 
     } 
     public class B 
     { 
      public double x; 
     } 

     /// <summary> 
     /// Serializes an object. 
     /// </summary> 
     /// <typeparam name="T"></typeparam> 
     /// <param name="serializableObject"></param> 
     /// <param name="fileName"></param> 
     public static void SerializeObject<T>(T serializableObject, string fileName) 
     { 
      if (serializableObject == null) { return; } 

      try 
      { 
       XmlDocument xmlDocument = new XmlDocument(); 
       XmlSerializer serializer = new XmlSerializer(serializableObject.GetType()); 
       using (MemoryStream stream = new MemoryStream()) 
       { 
        serializer.Serialize(stream, serializableObject); 
        stream.Position = 0; 
        xmlDocument.Load(stream); 
        xmlDocument.Save(fileName); 
        stream.Close(); 
       } 
      } 
      catch (Exception ex) 
      { 
       //Log exception here 
      } 
     } 


     /// <summary> 
     /// Deserializes an xml file into an object list 
     /// </summary> 
     /// <typeparam name="T"></typeparam> 
     /// <param name="fileName"></param> 
     /// <returns></returns> 
     public static T DeSerializeObject<T>(string fileName) 
     { 
      if (string.IsNullOrEmpty(fileName)) { return default(T); } 

      T objectOut = default(T); 
      try 
      { 
       XmlDocument xmlDocument = new XmlDocument(); 
       xmlDocument.Load(fileName); 
       string xmlString = xmlDocument.OuterXml; 

       using (StringReader read = new StringReader(xmlString)) 
       { 
        Type outType = typeof(T); 

        XmlSerializer serializer = new XmlSerializer(outType); 
        using (XmlReader reader = new XmlTextReader(read)) 
        { 
         objectOut = (T)serializer.Deserialize(reader); 
         reader.Close(); 
        } 

        read.Close(); 
       } 
      } 
      catch (Exception ex) 
      { 
       //Log exception here 
      } 

      return objectOut; 
     } 
    } 
} 
+0

はい。これは 'XmlSerializer'がどのように動作するかです。 –

+0

これを避けるための設定はありますか? – mrbm

+0

いいえ、あなたは 'IXmlSerializable'インターフェイスを実装することで独自のカスタムXMLシリアル化を実装する必要があります。 –

答えて

0

私はC#で/ロード/クローンのオブジェクトを保存することができますプロジェクト私の自己を開発し、それがhere利用可能である、オブジェクトへの参照を保持します。

また、内部およびプライベートフィールドを保存することもできます。フィールドやタイプを保存する方法(donsave、saveas、saveifなど)にはいくつかの属性があります。

関連する問題