在应用了DataMember属性的属性中抛出异常是一种好习惯吗?

时间:2012-09-19 17:35:15

标签: c# .net datacontractserializer datacontract xml-deserialization

DataContractDataMember属性也可用于通过使用DataContractSerializer将对象序列化为文件和反序列化。假设我们有一个具有以下私有字段和公共属性的类。

public class MyClass
{
    private int positiveValue;

    public int PositiveValue
    {
        get { return positiveValue; }
        set
        {
            if (value < 1)
                throw new ArgumentOutOfBoundException(...);
            positiveValue = value;
        }
    }
}

现在假设我们有一个XML文件,其中包含先前序列化对象的状态,并假设用户已修改此文件,为PositiveValue属性指定了不正确的值(即非正值)。在反序列化期间,将抛出异常,因为文件中的值无效。

假设我们要从文件中反序列化MyClass个对象的列表:如果某个对象无效,则抛出异常。是否可以确保DataContractSerializer忽略无效对象?此外,考虑到刚刚解释的问题,在应用了DataMember属性的属性中抛出异常是一种好习惯吗?

2 个答案:

答案 0 :(得分:2)

如果要在设置属性时验证数据,但希望在反序列化期间绕过这些验证,则可以使用DataMemberAttribute而不是属性标记属性的支持字段。这将导致DataContractSerializer直接在字段(而不是属性)中设置值,而不会抛出任何验证异常。

[DataMember]
private int positiveValue;

public int PositiveValue
{
    get { return positiveValue; }
    set
    {
        if (value < 1)
            throw new ArgumentOutOfBoundException(...);
        positiveValue = value;
    }
}

请注意,支持字段可以是私有的(否则,该属性没有多大意义)。这适用于DataContractSerializer

  

此外,考虑到刚才解释的问题,在应用了DataMember属性的属性中抛出异常是一种好习惯吗?

这取决于您是否允许在应用程序中包含具有无效数据的对象。不允许设置无效数据的优点是您不必在每次使用时检查对象,但在这种情况下,您必须检查任何用户输入并在加载数据时为异常做好准备。但是,我不认为在数据成员属性中抛出异常是错误的。这只是一个设计决定的问题。

答案 1 :(得分:1)

就列表而言,不能让DCS忽略无效对象。如果发生异常,则中止整个反序列化。如果它没有抛出,它将被添加到你的列表中。

我会考虑在反序列化之后检查有效性。在某些情况下,您可能只能说“忽略列表中的无效项目”,但坦率地说,在大多数情况下,如果存在任何问题,您只想拒绝整个事情。