如何避免反序列化无效枚举项时出现异常?
为了简单起见,我将使用 Fruit 来展示我的示例代码。事实上我正在做一些更有意义的事情(我们希望如此)。假设我们有一个枚举:
public enum FruitType
{
Apple,
Orange,
Banana
}
和一个类:
[Serializable]
public class Fruit
{
public FruitType FruitType { get; set; }
public Fruit(FruitType type)
{
this.FruitType = type;
}
}
我们可以对其进行序列化和反序列化。现在,让我们修改枚举,使其成为现在的样子:
public enum FruitType
{
GreenApple,
RedApple,
Orange,
Banana
}
当反序列化先前序列化的对象时,您会收到 System.InvalidOperation
异常,因为 Apple
(原始枚举项)是无效。该对象不会被反序列化。
我能够解决此问题的一种方法是在序列化时为 Fruit
类中的 FruitType
属性指定一个不同的名称,如下所示:
[XmlElement(ElementName = "Mode")]
public FruitType FruitType { get; set; }
现在,在反序列化期间,旧的属性将被忽略,因为找不到它。我想知道是否有一种方法可以在反序列化期间忽略/跳过无效的枚举项,以便不会引发异常并且对象仍然被反序列化。
For simplicity purposes here, I will show my sample code using fruit. In actuality I am doing something more meaningful (we hope). Let say we have an enum:
public enum FruitType
{
Apple,
Orange,
Banana
}
And a class:
[Serializable]
public class Fruit
{
public FruitType FruitType { get; set; }
public Fruit(FruitType type)
{
this.FruitType = type;
}
}
We can serialize and de-serialize it. Now, lets revise the enum, so that it is now:
public enum FruitType
{
GreenApple,
RedApple,
Orange,
Banana
}
When de-serializing previously serialized objects, you get a System.InvalidOperation
exception as Apple
(original enum item) is not valid. The object does not get de-serialized.
One way I was able to resolve this was to give the FruitType
property in the Fruit
class a different name when it gets serialized as follows:
[XmlElement(ElementName = "Mode")]
public FruitType FruitType { get; set; }
Now, during de-serialization the old property gets ignored as it is not found. I would like to know if there is a way to ignore/skip invalid enum items during de-serialization, so that no exception is thrown and the object still gets de-serialized.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
保留
Apple
并使用ObsoleteAttribute
对其进行标记。这样,任何使用Apple
的代码都会生成编译器警告。Leave
Apple
and mark it with theObsoleteAttribute
. That way, any code usingApple
will generate a compiler warning.我自己一直在寻找类似的答案,并编写此代码以在 XML 包含无效枚举值时捕获异常。它删除该元素,并尝试再次反序列化。如果该元素是必需的,您仍然会遇到异常。它并不完美,但应该能让你大部分到达你想去的地方
I've been looking for similar answers myself, and wrote this to catch the exception when the XML contains a value for an enum that is not valid. It removes that element, and tries to deserialize again. If the element is required, you still will get an exception. It's imperfect, but should get you most of the way to where you want to be
我发布了一个类似问题并且还没有找到一个简单的方法来捕获反序列化器在XML文件中遇到Apple时抛出的异常。我可以在反序列化期间捕获丢失属性或元素的一堆其他异常,但不能捕获无效的枚举值。无效的枚举值(在你的例子中是苹果)让我无法进行反序列化。
一种可能的解决方案是实施 Fruit 类上的 IXMLSerialized。当 IXMLSerailable 时。 ReadXML() 方法由反序列化器调用,您必须查看传递给您的内容。当值为“Apple”时,根据某种逻辑将枚举设置为 GreenApple 或 RedApple。
I posted a similar question and have not found a simple method to catch the exception thrown when the deserializer encounters Apple in the XML file. I can catch a bunch of other exceptions during deserialiation for missing attributes or elements, but not for an invalid enum value. The invalid enum value (in your case Apple) blows me out of the deserialization.
One possible solution is to implement IXMLSerializable on the Fruit class. When the IXMLSerailizable.ReadXML() method is called by the deserializer, you'll have to see what is being passed to you. When the value is "Apple" set the enum to GreenApple or RedApple based on some logic.