序列化代理(实现 ISerializationSurrogate)
实现序列化代理选择器,允许一个对象执行另一个对象的序列化和反序列化
同样允许正确序列化或反序列化本身不可序列化的类
实现 ISerializationSurrogate 接口
public class ItemSurrogate : ISerializationSurrogate
{
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
{
var item = (Item)obj;
info.AddValue("_name", item.Name);
}
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
var item = (Item)obj;
item.Name = (string)info.GetValue("_name", typeof(string));
return item;
}
}
然后你需要通过定义和初始化 SurrogateSelector 并将它分配给你的 IFormatter 来让你的 IFormatter 了解代理。
var surrogateSelector = new SurrogateSelector();
surrogateSelector.AddSurrogate(typeof(Item), new StreamingContext(StreamingContextStates.All), new ItemSurrogate());
var binaryFormatter = new BinaryFormatter
{
SurrogateSelector = surrogateSelector
};
即使该类没有标记为可序列化。
//this class is not serializable
public class Item
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
完整的解决方案
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace BinarySerializationExample
{
class Item
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
class ItemSurrogate : ISerializationSurrogate
{
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
{
var item = (Item)obj;
info.AddValue("_name", item.Name);
}
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
var item = (Item)obj;
item.Name = (string)info.GetValue("_name", typeof(string));
return item;
}
}
class Program
{
static void Main(string[] args)
{
var item = new Item
{
Name = "Orange"
};
var bytes = SerializeData(item);
var deserializedData = (Item)DeserializeData(bytes);
}
private static byte[] SerializeData(object obj)
{
var surrogateSelector = new SurrogateSelector();
surrogateSelector.AddSurrogate(typeof(Item), new StreamingContext(StreamingContextStates.All), new ItemSurrogate());
var binaryFormatter = new BinaryFormatter
{
SurrogateSelector = surrogateSelector
};
using (var memoryStream = new MemoryStream())
{
binaryFormatter.Serialize(memoryStream, obj);
return memoryStream.ToArray();
}
}
private static object DeserializeData(byte[] bytes)
{
var surrogateSelector = new SurrogateSelector();
surrogateSelector.AddSurrogate(typeof(Item), new StreamingContext(StreamingContextStates.All), new ItemSurrogate());
var binaryFormatter = new BinaryFormatter
{
SurrogateSelector = surrogateSelector
};
using (var memoryStream = new MemoryStream(bytes))
return binaryFormatter.Deserialize(memoryStream);
}
}
}