Supongamos que tengo un tipo de valor inmutable como esto:¿Cómo usar protobuf-net con tipos de valores inmutables?
[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);
}
}
Funciona con BinaryFormatter o DataContractSerializer pero cuando intento usarlo con protobuf-net (http://code.google.com/p/protobuf-net/) serializador me sale este error:
Cannot apply changes to property ConsoleApplication.Program+MyValueType.X
Si aplico setters a las propiedades marcadas con el atributo DataMember funcionará, pero luego rompe la inmutabilidad de este tipo de valor y eso no es deseable para nosotros.
¿Alguien sabe lo que tengo que hacer para que funcione? Me he dado cuenta de que hay una sobrecarga del método ProtoBu.Serializer.Serialize que admite SerializationInfo y StreamingContext, pero no los he usado fuera del contexto de implementación de la interfaz ISerializable, por lo que hay ejemplos de código sobre cómo usarlos en este contexto será muy apreciado!
Gracias,
EDIT: por lo Desenterré algún artículo de MSDN de edad y tengo una mejor comprensión de dónde y cómo se utiliza SerializationInfo y StreamingContext, pero cuando traté de hacer esto:
var serializationInfo = new SerializationInfo(
typeof(MyValueType), new FormatterConverter());
ProtoBuf.Serializer.Serialize(serializationInfo, valueType);
resulta que el método Serialize<T>
solo permite tipos de referencia, ¿hay alguna razón en particular para eso? Parece un poco extraño dado que puedo serializar los tipos de valor expuestos a través de un tipo de referencia.
Lo siento por el retraso - fin de semana agitado –