【发布时间】:2011-10-30 13:19:33
【问题描述】:
假设我有一个像这样的不可变值类型:
[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/) 序列化程序一起使用时,我收到此错误:
无法将更改应用于属性 ConsoleApplication.Program+MyValueType.X
如果我将 setter 应用于标有 DataMember 属性的属性,它会起作用,但它会破坏此值类型的不变性,这对我们来说是不可取的。
有人知道我需要做什么才能让它工作吗?我注意到有一个 ProtoBu.Serializer.Serialize 方法的重载,它接受一个 SerializationInfo 和一个 StreamingContext 但我没有在实现 ISerializable 接口的上下文之外使用它们,所以任何关于如何使用它们的代码示例非常感谢这个上下文!
谢谢,
编辑:所以我翻出了一些旧的 MSDN 文章,对 SerializationInfo 和 StreamingContext 的使用位置和方式有了更好的理解,但是当我尝试这样做时:
var serializationInfo = new SerializationInfo(
typeof(MyValueType), new FormatterConverter());
ProtoBuf.Serializer.Serialize(serializationInfo, valueType);
原来Serialize<T> 方法只允许引用类型,这有什么特别的原因吗?考虑到我能够序列化通过引用类型公开的值类型,这似乎有点奇怪。
【问题讨论】:
-
抱歉耽搁了 - 忙碌的周末
标签: c# serialization protocol-buffers protobuf-net