views:

35

answers:

2

Hello,

I'm having trouble serializing an immutable instance with the DataContractSerializer, since the properties on the class I'm serializing is missing setters. The problem is that I only want to serialize the instance (just so it can be written to a log), and I will never need to deserialize it. Is there a way to bypass this behavior?

The class I'm trying to serialize:

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

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

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

The code used for serializing the class:

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();
}
+1  A: 

You can place the [DataMember] on the fields thus allowing you to have property getters. These fields can still be private. However it cannot be readonly as it needs to construct the object then set the fields.

[Edit] This will cause the field names to be used unless you use [DataMember(Name = "Name1")]

aqwert
Thank you very much. I should have thought of this before posting the question. :)
Patrik
+2  A: 

This version uses the ISerializable attribute instead of [DataContract]. I don't know how this will affect operability, but does not need a public setter.

[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);
    }
}
MrFox