如果一个类标记了DataContractAttribute,那么DataContractSerializer在反序列化时会跳过所有的变量初始值和构造函数。例如,下面定义的这个类在反序列化时会引发NullReferenceException

[DataContract]
class Person
{
    private readonly List<int> _scores = new List<int>();

    [DataMember]
    public List<int> Scores
    {
        get
        {
            if (_scores == null)
            {
                throw new NullReferenceException();
            }

            return _scores;
        }
    }
}

进行反序列化时,一个标记了DataContractAttribute的类可以用一个标记了OnDeserializingAttribute的函数来进行必要的初始化,例如:

[DataContract]
class User
{
    private List<int> _scores = new List<int>();

    [DataMember]
    public List<int> OrderIds
    {
        get
        {
            if (_scores == null)
            {
                throw new NullReferenceException();
            }

            return _scores;
        }
    }

    [OnDeserializing]
    private void OnDeserializing(StreamingContext context)
    {
        _scores = new List<int>();
    }
}

对于这个例子里的List类型的数据,也可以直接将可写的变量作为DataMember,让序列化器代为进行变量的初始化:

[DataContract]
class User
{
    [DataMember]
    private List<int> _scores = new List<int>();

    public List<int> OrderIds
    {
        get
        {
            if (_scores == null)
            {
                throw new NullReferenceException();
            }

            return _scores;
        }
    }
}