Предположим, что у меня есть неизменяемый тип значения, например:
[Serializable]
[DataContract]
public struct MyValueType : ISerializable
{
private readonly int _x;
private readonly int _z;
public MyValueType(int x, int z)
: this()
{
_x = x;
_z = z;
}
// this constructor is used for deserialization
public MyValueType(SerializationInfo info, StreamingContext text)
: this()
{
_x = info.GetInt32("X");
_z = info.GetInt32("Z");
}
[DataMember(Order = 1)]
public int X
{
get { return _x; }
}
[DataMember(Order = 2)]
public int Z
{
get { return _z; }
}
public static bool operator ==(MyValueType a, MyValueType b)
{
return a.Equals(b);
}
public static bool operator !=(MyValueType a, MyValueType b)
{
return !(a == b);
}
public override bool Equals(object other)
{
if (!(other is MyValueType))
{
return false;
}
return Equals((MyValueType)other);
}
public bool Equals(MyValueType other)
{
return X == other.X && Z == other.Z;
}
public override int GetHashCode()
{
unchecked
{
return (X * 397) ^ Z;
}
}
// this method is called during serialization
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("X", X);
info.AddValue("Z", Z);
}
public override string ToString()
{
return string.Format("[{0}, {1}]", X, Z);
}
}
Он работает с BinaryFormatter или DataContractSerializer, но когда я пытаюсь использовать его с protobuf-net (http://code.google.com/p/protobuf-net/) serializer, я получаю эту ошибку:
Невозможно применить изменения к свойству ConsoleApplication.Program + MyValueType.X
Если я применяю сеттеры к свойствам, отмеченным атрибутом DataMember, он будет работать, но тогда он нарушит неизменность этого типа значений и что нам не желательно.
Кто-нибудь знает, что мне нужно сделать, чтобы заставить его работать? Я заметил, что существует перегрузка метода ProtoBu.Serializer.Serialize, который принимает в SerializationInfo и StreamingContext, но я не использую их вне контекста реализации интерфейса ISerializable, поэтому любые примеры кода о том, как их использовать в этот контекст будет высоко оценен!
Спасибо,
EDIT: поэтому я выкопал какую-то старую статью MSDN и лучше понял, где и как используются SerializationInfo и StreamingContext, но когда я пытался это сделать:
var serializationInfo = new SerializationInfo(
typeof(MyValueType), new FormatterConverter());
ProtoBuf.Serializer.Serialize(serializationInfo, valueType);
получается, что метод Serialize<T>
допускает только ссылочные типы, есть ли для этого конкретная причина? Кажется немного странным, учитывая, что я могу сериализовать типы значений, открытые через ссылочный тип.