C#序列化与反序列化集合对象并进行版本控制

当涉及到跨进程甚至是跨域传输数据的时候,我们需要把对象序列化和反序列化。

首先可以使用Serializable特性。

    [Serializable]
  public class Person
  {
      public string _firstName;
      public string _secondName;
      //序列化
      [OnSerializing]
      internal void OnSerializing(StreamingContext context)
      {
          _firstName = _firstName.ToUpper();
          _secondName = _secondName.ToUpper();
      }
      //反序列化
      [OnDeserialized]
      internal void OnDeserialized(StreamingContext context)
      {
          _firstName = _firstName.ToLower();
          _secondName = _secondName.ToLower();
      }
  }

当然,也可以实现ISerializable接口。在接口方法GetObjectData完成序列化,把信息保存到SerializationInfo中,在构造函数中反序列化,把信息从SerializationInfo中读取出来。

   [Serializable]
  public class Person : ISerializable
  {
      public string _firstName;
      public string _secondName;
      public Person()
      {
          
      }
      //反序列化
      public Person(SerializationInfo si, StreamingContext context)
      {
          _firstName = si.GetString("first").ToLower();
          _secondName = si.GetString("second").ToLower();
      }
      //序列化
      public void GetObjectData(SerializationInfo info, StreamingContext context)
      {
          info.AddValue("first", _firstName.ToUpper());
          info.AddValue("second",_secondName.ToUpper());
      }
  }

 

对序列化和反序列化对象进行版本控制

下面的类,描述了对象的第一个版本。

[Serializable]
public class SomeClass : ISerializable
{
  private int a;
  public SomeClass(){}
  public SomeClass(SerializationInfo info, StreamingContext context)
  {
      a = info.GetInt32("myval");
  }
  public void GetObjectData(SerializationInfo, StreamingContext context)
  {
      info.AddValue("VERSION",1);
       info.AddValue("myval", a);
  }
}

现在SomeClass要增加一个私有字段,成为版本二。

[Serializable]
public class SomeClass : ISerializable
{
  private int a;
  private string b;
  public SomeClass(){}
  public SomeClass(SerializationInfo info, StreamingContext context)
  {
      int VERSION = info.GetInt32("VERSION");
      a = info.GetInt32("a");
      if(VERSION > 1)
      {
          b = info.GetString("another");
      }
      else
      {
          b = "默认值";
      }
  }
  public void GetObjectData(SerializationInfo, StreamingContext context)
  {
      info.AddValue("VERSION",2);
       info.AddValue("myval", a);
       info.AddValue("another", b);
  }
}

 

把集合对象序列化到文件并反序列化读出

如果一个集合对象需要实现序列化和反序列化,那么集合元素对象必须可以被序列化和反序列化,并且集合元素对象中的对象属性也必须可以被序列化和反序列化,依此类推。

    [Serializable]
  public class Car : ISerializable
  {
      private string _model;
      private int _year;
      private Owner _owner;
      public Car()
      {
          
      }
      public Car(SerializationInfo info, StreamingContext context)
      {
          this._model = (string) info.GetValue("Model", typeof (string));
          this._year = (int) info.GetValue("Year", typeof (int));
          this._owner = (Owner) info.GetValue("Owner", typeof (Owner));
      }
      public void GetObjectData(SerializationInfo info, StreamingContext context)
      {
          info.AddValue("Model",this._model);
          info.AddValue("Year", this._year);
          info.AddValue("Owner", this._owner);
      }
  }
  [Serializable]
  public class Owner : ISerializable
  {
      private string _name;
      public Owner()
      {
          
      }
      public Owner(SerializationInfo info, StreamingContext context)
      {
          this._name = (string) info.GetValue("Name", typeof (string));
      }
      public void GetObjectData(SerializationInfo info, StreamingContext context)
      {
          info.AddValue("Name", this._name);
      }
  }

以上,我们想序列化Car的集合到文件中,再反序列化Cars的集合读取出来。那么,我们必须让Car可以被序列化和反序列化,Car的属性对象Owner也必须可以被序列化和反序列化。

接着,用来封装Car集合的一个类。

    [Serializable]
  public class CarsList : ISerializable
  {
      private List<Car> _cars;
      public List<Car> Cars
      {
          get { return this._cars; }
          set { this._cars = value; }
      }
      public CarsList()
      {
          
      }
      public CarsList(SerializationInfo info, StreamingContext context)
      {
          this._cars = (List<Car>) info.GetValue("Cars", typeof (List<Car>));
      }
      public void GetObjectData(SerializationInfo info, StreamingContext context)
      {
          info.AddValue("Cars", this._cars);
      }
  }

针对CarsList写一个序列化和反序列化的帮助类。

    public class SerializerHelper
  {
      public SerializerHelper()
      {
          
      }
      //序列化
      public void SerializeObject(string fileName, CarsList carsList)
      {
          //根据文件名打开流
          Stream stream = File.Open(fileName, FileMode.Create);
          BinaryFormatter bFormatter = new BinaryFormatter();
          //把对象序列化到流中
          bFormatter.Serialize(stream,carsList);
          stream.Close();
      }
      //反序列化
      public CarsList DeserializeObject(string fileName)
      {
          CarsList carsList;
          //根据文件名打开流
          Stream stream = File.Open(fileName, FileMode.Open);
          BinaryFormatter bfFormatter = new BinaryFormatter();
          carsList = (CarsList)bfFormatter.Deserialize(stream);
          stream.Close();
          return carsList;
      }
  }

在客户端按如下调用:

        static void Main(string[] args)
      {
          List<Car> cars = new List<Car>();
          CarsList carsList = new CarsList();
          carsList.Cars = cars;
          SerializerHelper serializerHelper = new SerializerHelper();
          serializerHelper.SerializeObject(@"temp.txt", carsList);
          carsList = serializerHelper.DeserializeObject(@"temp.txt");
          cars = carsList.Cars;
      }

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对编程宝库的支持。如果你想了解更多相关内容请查看下面相关链接

扇形统计图绘制一个扇形原理也是基于Canvas进行绘制;ArcSegment[1]绘制弧形;绘制指示线;绘制文本;鼠标移入动画;显示详情Popup;源码Github[2]Gitee[3]示例代码1)Sec ...