Возникли проблемы с использованием DataContractSerializer

У меня возникли проблемы с сериализацией неизменяемого экземпляра с помощью DataContractSerializer, поскольку в свойствах сериализуемого класса отсутствуют сеттеры. Проблема в том, что я хочу только сериализовать экземпляр (чтобы его можно было записать в журнал), и мне никогда не нужно его десериализовать. Есть ли способ обойти такое поведение?

Класс, который я пытаюсь сериализовать:

[DataContract]
public class Person
{
    private readonly string _name;

    [DataMember]
    public string Name
    {
        get { return _name; }
    }

    public Person(string name)
    {
        _name = name;
    }
}

Код, используемый для сериализации класса:

public string Serialize()
{
    var serializer = new DataContractSerializer(typeof(Person));
    StringBuilder stringBuilder = new StringBuilder();
    using (XmlWriter writer = XmlWriter.Create(stringBuilder)) {
        serializer.WriteObject(writer, this);
    }
    return stringBuilder.ToString();
}

person Patrik Svensson    schedule 29.06.2010    source источник


Ответы (2)


Вы можете разместить [DataMember] в полях, что позволит вам получить средства получения свойств. Эти поля все еще могут быть закрытыми. Однако это не может быть readonly, поскольку необходимо построить объект, а затем установить поля.

[Edit] Это приведет к использованию имен полей, если вы не используете [DataMember(Name = "Name1")]

person aqwert    schedule 29.06.2010
comment
Большое Вам спасибо. Я должен был подумать об этом, прежде чем размещать вопрос. :) - person Patrik Svensson; 29.06.2010
comment
не знаю, изменилось ли это, но в .net 4.5.1 вы можете сериализовать и десериализовать поля только для чтения - person serine; 22.09.2013

В этой версии вместо [DataContract] используется атрибут ISerializable. Не знаю, как это повлияет на работоспособность, но публичный сеттер не нужен.

[Serializable]
public class Person : ISerializable
{
    private readonly string _name;

    public string Name
    {
        get { return _name; }
    }

    public Person(string name)
    {
        _name = name;
    }

    public string Serialize()
    {
        DataContractSerializer serializer = new DataContractSerializer(typeof(Person));
        System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
        using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(stringBuilder))
        {
            serializer.WriteObject(writer, this);
        }
        return stringBuilder.ToString();
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Name", _name);
    }
}
person MrFox    schedule 29.06.2010