XmlSerializer:如何反序列化不再存在的枚举值
我正在使用XMLSerializer将此类保存到文件中。 该类有一个字符串和一个枚举,如下所示:
public class IOPoint { string Name {get; set;} TypeEnum {get; set;} } public enum TypeEnum { Temperature, Pressure, Humidity, }
序列化时,它看起来像这样。
Relative Humidity Humidity
我一直在序列化和反序列化这个对象,几个版本都没有问题。 我不再想支持湿度,所以我将它从枚举中删除了。 但是,这会在从XML反序列化时导致exception,因为TypeEnum字段中的值Humidity不是TypeEnum的有效值。 这是有道理的,但如何处理呢?
我想做的就是忽略这个错误。 并将值保留为null。 我已经尝试实现OnUnknownElement XmlDeserilizationEvent类。 不幸的是,这并没有发现这个错误。
关于如何捕获和忽略此错误的任何想法(我可以在反序列化完成后清理)。
米奇
您可以将成员标记为已过时
public enum TypeEnum { Temperature, Pressure, [Obsolete] Humidity }
在您的库已被使用后删除枚举成员通常被认为是不好的做法。 为什么不将会员留在原地,而是使用[Obsolete]
属性标记以防止将来使用? 如果访问标记的成员ObsoleteAttribute(string,bool)
则将ObsoleteAttribute(string,bool)
构造函数的第二个参数指定为true
将导致编译时错误。
public enum TypeEnum { Temperature, Pressure, [Obsolete("It's always sunny in Philadelphia", true)] Humidity, }
要在检查反序列化值时避免错误,可以与基础值进行比较: typeEnum == (TypeEnum)2
。
您可以使用属性来更改节点名称并隐藏xml序列化中的元素,只需手动解析一个元素:
public class IOPoint { public string Name {get; set;} [XmlIgnore] public TypeEnum TypeEnum {get; set;} [XmlElement("TypeEnum")] public string LegacyTypeEnum { get { return this.TypeEnum.ToString(); } set { try { this.TypeEnum = (TypeEnum)Enum.Parse(typeof(TypeEnum),value); } catch(ArgumentException) { // Handle "Humidity" } catch(OverflowException) { } } } }
每条评论似乎都有些混乱; 这是一个作为Visual Studio 2010项目的工作示例 。 这种方法只是手动解析对象的一个属性的简单方法(仍然利用XmlSerializer进行XML解析)。
你可以实现IXmlSerializable ,你可以在其中使用像TryParse这样的枚举。
但我同意使用Obsolete属性的其他海报。