【问题标题】:C# XML Serialization Observable CollectionC# XML 序列化 Observable 集合
【发布时间】:2015-09-21 12:55:12
【问题描述】:

我正在尝试反序列化由旧版本代码序列化的一堆数据。当数据被序列化时,类的结构与当前的类结构不同。为了让这些数据在我的新代码中正常工作,我不得不将旧的类结构添加到代码中,只是为了导入这个序列化数据。我将这些类称为“类”_oldVersions。为了反序列化,我使用了这段代码:

className_oldVersions temp_className = new className_oldVersions();

XmlSerializer testSerializer = new XmlSerializer(typeof(className_oldVersions), 
   new XmlRootAttribute { ElementName = "className" });

temp_className = (ObservedData_OldVersions)testSerializer.Deserialize(ms_MemoryStream);

这段代码运行良好,我可以使用与原始代码不同的类名来反序列化数据。我的问题是当我尝试使用相同的过程来反序列化可观察的集合时。

我创建了一个重现我的问题的代码。在这段代码中,我序列化了类 OptimizationVariables 的可观察集合,并且我想反序列化为具有与原始类相似结构的类 OptimizationVariablies_NewClass 的可观察集合。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Collections.ObjectModel;

public class OptimizationVariables
{
  public string VariableName { get; set; }    
}

public class OptimizationVariables_NewClass
{
  public string VariableName { get; set; }
}

public class ModelsCollection
{
  private ModelsCollection()
  {
  }    

  private ObservableCollection<OptimizationVariables> m_optimizationVariables =
    new ObservableCollection<OptimizationVariables>();

  public ObservableCollection<OptimizationVariables> OptimizationVariables
  {
    get { return m_optimizationVariables; }
    set { m_optimizationVariables = value; }
  }

  private ObservableCollection<OptimizationVariables_NewClass> m_optimizationVariables_NewClass =
    new ObservableCollection<OptimizationVariables_NewClass>();

  public ObservableCollection<OptimizationVariables_NewClass> OptimizationVariables_NewClass
  {
    get { return m_optimizationVariables_NewClass; }
    set { m_optimizationVariables_NewClass = value; }
  }


}
class Program
{   

  static void Main(string[] args)
  {
    //Here I serialize an ObservableCollection of 2 OptimizationVariables instances
    Serialize();

    //Here I deserialize for the same class and works fine
    Deserialize();

    //Here I try to deserialize to a new class with same structure, but different name. I a have an error.
    Deserialize2NewClass();
  }


  static void Serialize()
  {
    MemoryStream ms;

    ObservableCollection<OptimizationVariables> OptimizationVariables2Serialize = new ObservableCollection<OptimizationVariables>();

    OptimizationVariables opt_var1 = new OptimizationVariables();
    opt_var1.VariableName = "Variable Name 1";
    OptimizationVariables2Serialize.Add(opt_var1);

    OptimizationVariables opt_var2 = new OptimizationVariables();
    opt_var1.VariableName = "Variable Name 2";
    OptimizationVariables2Serialize.Add(opt_var1);

    ms = new MemoryStream();
    XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables>));
    serializer.Serialize(ms, OptimizationVariables2Serialize);

    TextWriter sw = new StreamWriter("XML_File_x64.bin");
    sw.WriteLine(Convert.ToBase64String(ms.ToArray()));
    sw.Close();
  }

  static void Deserialize()
  {
    byte[] memoryData;
    MemoryStream ms;

    TextReader sw = new StreamReader("XML_File_x64.bin");
    memoryData = Convert.FromBase64String(sw.ReadLine());
    ms = new MemoryStream(memoryData);

    ObservableCollection<OptimizationVariables> OptimizationVariablesDeserialized = new ObservableCollection<OptimizationVariables>();

    XmlSerializer deserializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables>));
    OptimizationVariablesDeserialized = (ObservableCollection<OptimizationVariables>)deserializer.Deserialize(ms);

    Console.Write(OptimizationVariablesDeserialized.Count());
    sw.Close();
  }

  static void Deserialize2NewClass()
  {
    byte[] memoryData;
    MemoryStream ms;

    TextReader sw = new StreamReader("XML_File_x64.bin");
    memoryData = Convert.FromBase64String(sw.ReadLine());
    ms = new MemoryStream(memoryData);

    ObservableCollection<OptimizationVariables_NewClass> OptimizationVariablesDeserialized = new ObservableCollection<OptimizationVariables_NewClass>();

    XmlSerializer deserializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables_NewClass>));
    OptimizationVariablesDeserialized = (ObservableCollection<OptimizationVariables_NewClass>)deserializer.Deserialize(ms);

    Console.Write(OptimizationVariablesDeserialized.Count());
    sw.Close();
  }

}

【问题讨论】:

    标签: c# xml serialization


    【解决方案1】:

    你代码中的问题是类OptimizationVariables名称在序列化时保存在xml数据中。但对于反序列化,它需要一个不在 xml 文件中的 OptimizationVariables_NewClass 名称。

    • 请考虑这样一个事实:在序列化类或结构时,不仅会使用变量名,还会使用类名...

    因此,只需更改您的代码以使其将数据保存在可读的 xml 文件中,然后将“OptimizationVariables”替换为“OptimizationVariables_NewClass”即可解决错误:

    using System;
    using System.Linq;
    using System.IO;
    using System.Xml.Serialization;
    using System.Collections.ObjectModel;
    
    public class OptimizationVariables
    {
        public string VariableName { get; set; }
    }
    
    public class OptimizationVariables_NewClass
    {
        public string VariableName { get; set; }
    }
    
    public class ModelsCollection
    {
    private ModelsCollection()
    {
    }
    
    private ObservableCollection<OptimizationVariables> m_optimizationVariables =
      new ObservableCollection<OptimizationVariables>();
    
    public ObservableCollection<OptimizationVariables> OptimizationVariables
    {
        get { return m_optimizationVariables; }
        set { m_optimizationVariables = value; }
    }
    
    private ObservableCollection<OptimizationVariables_NewClass> m_optimizationVariables_NewClass =
      new ObservableCollection<OptimizationVariables_NewClass>();
    
    public ObservableCollection<OptimizationVariables_NewClass> OptimizationVariables_NewClass
    {
        get { return m_optimizationVariables_NewClass; }
        set { m_optimizationVariables_NewClass = value; }
    }
    
    
    }
    class Program
    {
    
    static void Main(string[] args)
    {
        Serialize();
        Deserialize();
        Deserialize2NewClass();
    }
    
    static void Serialize()
    {
        ObservableCollection<OptimizationVariables> OptimizationVariables2Serialize = new ObservableCollection<OptimizationVariables>();
    
        OptimizationVariables opt_var1 = new OptimizationVariables();
        opt_var1.VariableName = "Variable Name 1";
        OptimizationVariables2Serialize.Add(opt_var1);
    
        OptimizationVariables opt_var2 = new OptimizationVariables();
        opt_var1.VariableName = "Variable Name 2";
        OptimizationVariables2Serialize.Add(opt_var1);
    
        TextWriter writer = new StreamWriter("XML_File.xml");
        XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables>));
        serializer.Serialize(writer, OptimizationVariables2Serialize);
        writer.Close();
    }
    
    static void Deserialize()
    {
        TextReader sw = new StreamReader("XML_File.xml");
    
        ObservableCollection<OptimizationVariables> OptimizationVariablesDeserialized = new ObservableCollection<OptimizationVariables>();
    
        XmlSerializer deserializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables>));
        OptimizationVariablesDeserialized = (ObservableCollection<OptimizationVariables>)deserializer.Deserialize(sw);
    
        Console.Write(OptimizationVariablesDeserialized.Count());
        sw.Close();
    }
    
    static void Deserialize2NewClass()
    {
        TextReader sw = new StreamReader("XML_File.xml");
        var str = sw.ReadToEnd();
        sw.Close();
        str = str.Replace("OptimizationVariables", "OptimizationVariables_NewClass");
        var stream = new StringReader(str);
        ObservableCollection<OptimizationVariables_NewClass> OptimizationVariablesDeserialized = new ObservableCollection<OptimizationVariables_NewClass>();
    
        XmlSerializer deserializer = new XmlSerializer(typeof(ObservableCollection<OptimizationVariables_NewClass>));
        OptimizationVariablesDeserialized = (ObservableCollection<OptimizationVariables_NewClass>)deserializer.Deserialize(stream);
    
        Console.Write(OptimizationVariablesDeserialized.Count());
    }
    
    }
    

    现在可以正常使用了!

    【讨论】:

      猜你喜欢
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多