9

我正在使用 XMLSerializer 将此类保存到文件中。该类有一个字符串和一个枚举,如下所示:

public class IOPoint
{
     string Name {get; set;}
     TypeEnum {get; set;}
}


public enum TypeEnum
{
    Temperature,
    Pressure,
    Humidity,
}

序列化时看起来像这样。

<IOPoint>
  <Name>Relative Humidity</Name>
  <TypeEnum>Humidity</TypeEnum>
</IOPoint>

我一直在序列化和反序列化这个对象,几个版本都没有问题。我不再想支持 Humidity,所以我将它从枚举中删除。但是,当从 XML 反序列化时,这会导致异常,因为 TypeEnum 字段中的值 Humidity 不是 TypeEnum 的有效值。这是有道理的,但是如何处理呢?

我想做的就是忽略这个错误。并将值保留为空。我已经尝试实现 OnUnknownElement XmlDeserilizationEvent 类。不幸的是,这并没有捕捉到这个错误。

关于如何捕获和忽略此错误的任何想法(我可以在反序列化完成后进行清理)。

米奇

4

4 回答 4

5

您可以将成员标记为已过时

public enum TypeEnum
{
    Temperature,
    Pressure,
    [Obsolete]
    Humidity
}
于 2012-05-22T18:56:29.790 回答
4

在您的库已经在使用之后删除枚举成员通常被认为是不好的做法。为什么不将成员留在原处,而是用[Obsolete]属性标记它以防止将来使用?如果访问标记的成员,将ObsoleteAttribute(string,bool)构造函数的第二个参数指定为将导致编译时错误。true

public enum TypeEnum
{
    Temperature,
    Pressure,

    [Obsolete("It's always sunny in Philadelphia", true)]
    Humidity,
}

为了在检查反序列化值时规避错误,您可以与基础值进行比较:typeEnum == (TypeEnum)2.

于 2012-05-22T19:01:20.937 回答
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 解析)。

于 2012-05-22T19:45:11.050 回答
1

您可以实现IXmlSerializable,您可以在其中对枚举使用 TryParse 之类的东西。

但我同意其他使用过时属性的海报。

于 2012-05-22T19:04:00.383 回答