添加默认值Dictionary成员后,未更新应用调用DataContract接口是否兼容?
现有标注
[DataContract, Serializable]的MyInfo类定义如下:[DataContract, Serializable] public class MyInfo { string firstName; string fullName; }该类被四个应用(app1、app2、app3、app4)所调用的
GetMyInfo(MyInfo myInfo)接口使用,当前运行正常。现需为该类新增一个
Dictionary<string, string>类型的parameter字段,并设置默认值为null,更新后的类定义为:[DataContract, Serializable] public class MyInfo { string firstName; string fullName; Dictionary<string, string> parameter = null; }其中app1、app2将基于新版本类编译,app3、app4不做更新。现询问:app3、app4不编译新类就调用
GetMyInfo接口时,序列化是否正常,功能是否不会出现异常?
放心,app3和app4在不更新编译的情况下调用接口,序列化/反序列化过程不会出问题,功能也能正常运行,具体原因如下:
DataContract序列化的向后兼容性设计:
DataContractSerializer本身就是为兼容新旧版本对象而生的——当旧版本客户端(app3、app4)接收新版本的MyInfo对象时,会自动忽略自身未定义的parameter字段;反过来,旧客户端发送旧版本MyInfo对象给服务端时,服务端的新版本类会将parameter字段保留默认的null值,不会触发任何异常。默认值设置不影响旧客户端逻辑:
你给parameter设置的默认值null,仅在新版本类的实例化过程中生效。旧客户端完全不知道这个字段的存在,序列化时根本不会涉及它,自然不会产生冲突。Serializable特性的兼容表现:
即使同时使用了Serializable(二进制序列化),也无需担心——二进制序列化器在处理未知字段时,会直接跳过这些内容,不会抛出异常,只是旧客户端无法读取新增的parameter值而已。
不过有个小提醒:如果后续你给parameter字段添加了[DataMember(IsRequired = true)]这类强制要求字段存在的属性,那旧客户端发送的对象因缺少该字段,就会触发序列化异常。但目前你的代码没有这类设置,所以完全没问题。
内容的提问来源于stack exchange,提问作者Brad Reiter

