1

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 属性的属性中抛出异常是一种好习惯吗?

4

2 回答 2

2

如果您想在设置属性时验证数据,但想在反序列化过程中绕过这些验证,您可以使用DataMemberAttribute而不是属性标记属性的支持字段。这将导致DataContractSerializer直接在字段(而不是属性)中设置值,并且不会引发任何验证异常。

[DataMember]
private int positiveValue;

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

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

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

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

于 2012-09-20T12:37:06.363 回答
1

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

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

于 2012-09-19T17:41:52.627 回答