C# – Immutability and XML Serialization

cimmutabilityxml-serialization

I have several classes that are immutable once their initial values are set. Eric Lippert calls this write-once immutability.

Implementing write-once immutability in C# usually means setting the initial values via the constructor. These values initialize readonly fields.

But if you need to serialize a class like this to XML, using either the XmlSerializer or the DataContractSerializer, you must have a parameterless constructor.

Does anyone have suggestions for how to work around this problem? Are there other forms of immutability that work better with serialization?

EDIT: As @Todd pointed out, the DataContractSerializer does not require a parameterless constructor. According to the DataContractSerializer documentation on MSDN, DataContractSerializer "does not call the constructor of the target object."

Best Answer

Assuming this is your "immutable" object :

public class Immutable
{
    public Immutable(string foo, int bar)
    {
        this.Foo = foo;
        this.Bar = bar;
    }

    public string Foo { get; private set; }
    public int Bar { get; private set; }
}

You can create a dummy class to represent that immutable object during serialization/deserialization :

public class DummyImmutable
{
    public DummyImmutable(Immutable i)
    {
        this.Foo = i.Foo;
        this.Bar = i.Bar;
    }

    public string Foo { get; set; }
    public int Bar { get; set; }

    public Immutable GetImmutable()
    {
        return new Immutable(this.Foo, this.Bar);
    }
}

When you have a property of type Immutable, don't serialize it, and instead serialize a DummyImmutable :

[XmlIgnore]
public Immutable SomeProperty { get; set; }

[XmlElement("SomeProperty")]
public DummyImmutable SomePropertyXml
{
    get { return new DummyImmutable(this.SomeProperty); }
    set { this.SomeProperty = value != null ? value.GetImmutable() : null; }
}

OK, this is a bit long for something that looks so simple... but it should work ;)