C# 为版本控制实现ISerializable
考虑以下POD类型的类:C# 为版本控制实现ISerializable,c#,.net,version-control,versioning,C#,.net,Version Control,Versioning,考虑以下POD类型的类: public class Price { public decimal OfferPrice { get; set; } } 此类中的对象是从服务器检索的,所以让我们用Serializable来修饰它 [Serializable] public class Price { public decimal OfferPrice { get; set; } } 现在有两个客户端在不同的机器上检索这些对象。他们不会报价格。他们都有一份普莱斯的汇编 现在,这个类用BonuPr
public class Price { public decimal OfferPrice { get; set; } }
此类中的对象是从服务器检索的,所以让我们用Serializable来修饰它
[Serializable]
public class Price { public decimal OfferPrice { get; set; } }
现在有两个客户端在不同的机器上检索这些对象。他们不会报价格。他们都有一份普莱斯的汇编
现在,这个类用BonuPrice扩展
[Serializable]
public class Price {
public decimal OfferPrice { get; set; }
public decimal BonusPrice { get; set; }
}
新程序集部署到服务器,部署到其中一个客户端,但不部署到另一个客户端。
因此,旧版本的客户端在(反)序列化Price对象时将崩溃
旧版本的客户机不需要BonusPrice字段,因此当存在版本差异时,它可以继续工作。
因此,我从一开始就考虑实现ISerializable,因此第一个和第二个版本如下所示:
// version 1.0
[Serializable]
public class Price : ISerializable {
protected Price(SerializationInfo info, StreamingContext context) {
OfferPrice = info.GetDecimal("op");
}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
info.AddValue("op", OfferPrice);
}
}
// version 2.0
[Serializable]
public class Price : ISerializable {
protected Price(SerializationInfo info, StreamingContext context) {
OfferPrice = info.GetDecimal("op");
BonusPrice = info.GetDecimal("bp");
}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
info.AddValue("op", OfferPrice);
info.AddValue("bp", BonusPrice);
}
}
因此,现在当一个客户端没有更新到版本2时,它仍将继续只反序列化OfferPrice,而不会崩溃。当它在某个点更新时,它将自动使用BonuPrice
我的问题:当只读取对象时,实现ISerializable是否是版本控制的好方法?
这些问题通常是如何解决的?您可以使用来控制BinaryFormatter
和SoapFormatter
的版本控制
OptionalFieldAttribute具有VersionAdded属性。在.NET Framework的2.0版中,未使用此选项。但是,正确设置此属性非常重要,以确保该类型与将来的序列化引擎兼容
该属性指示给定字段所属类型的版本
补充。它应该每增加一次(从2开始)
修改类型的时间
还有其他方法,如序列化回调、SerializationBinder、ISerializable
等
有关更多信息,请参阅。在我看来,您试图在一份合同中混合使用两个协议版本。在您的示例中,它是有效的,但在实践中,通常很难统一新协议,所以最好将它们分开。换句话说,您的服务器必须独立支持这两个版本。请看一个好问题,正如我在回答中提到的,您可以使用
OptionalFieldAttribute
我从来没有使用过它,因为当我知道类似的东西存在时已经太晚了。FWIW我使用了ISerializable
来控制我项目中的版本控制。这当然更容易。因此,如果CLR无法通过反射找到这些字段并且没有引发异常,则不会序列化这些字段?@ServéLaurijssen Yes序列化程序在数据丢失时不会引发异常(它只会忽略),反之亦然。