序列化代理(實現 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);
}
}
}