Я использую protobuf-net по соображениям производительности в сценарии, когда сборки, которые десериализуют сохраненные данные, являются теми же, что и при сериализации.
Большинство типов, которые я сериализирую, простыконтракты, которые я пометил атрибутами ProtoContract и ProtoMember , но иногда мне приходится сериализовывать странные объекты со многими подклассами (например: Exception ).
Я заставил его работать со следующим обходным решением, используя классический механизм ISerializable.
Я довольно новичок в protobuf-net и хотел бы знать, если это хорошая идея и есть ли лучше /стандартные способы сделать это.
Мой обходной путь:
Я определил универсальный суррогат, который реализует классическую сериализацию
[ProtoContract]
class BinarySerializationSurrogate<T>
{
[ProtoMember(1)]
byte[] objectData = null;
public static implicit operator T(BinarySerializationSurrogate<T> surrogate)
{
T ret = default(T);
if (surrogate == null)
return ret;
var serializer = new BinaryFormatter();
using (var serializedStream = new MemoryStream(surrogate.objectData))
ret = (T)serializer.Deserialize(serializedStream);
return ret;
}
public static implicit operator BinarySerializationSurrogate<T>(T obj)
{
if (obj == null)
return null;
var ret = new BinarySerializationSurrogate<T>();
var serializer = new BinaryFormatter();
using (var serializedStream = new MemoryStream())
{
serializer.Serialize(serializedStream, obj);
ret.objectData = serializedStream.ToArray();
}
return ret;
}
}
В коде инициализации, который я добавляюэто как суррогат для странных базовых типов
RuntimeTypeModel.Default
.Add(typeof(Exception), false)
.SetSurrogate(typeof(BinarySerializationSurrogate<Exception>));