垃圾站 生活小记 C#序列化与反序列化集合对象并进行版本控制

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

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

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;
}
上一篇
下一篇
联系我们

联系我们

返回顶部