Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforce constructor called only from Serialization

In our codebase any classes that need to be saved are IXmlSerializable, this means that they all have public parameterless constructors.

The problem with this, is I have to stick a remark above each one "Only for serialization purposes" because certain members on these instances are private and required, and are therefore required when calling all the 'usable' constructors.

What would be really nice is a way of saying "This constructor must only be called by serialization code/assemblies, otherwise I'm going to explode". Anyone know if there's a nice way to do this? They only way I can think of this is checking the call stack why sounds too expensive...

like image 460
Ian Avatar asked Jan 19 '26 20:01

Ian


2 Answers

How about:

    [Obsolete("Is your name XmlSerializer? No, I didn't think so.", true)]
    public Foo() { }

Note: this won't protect you from reflection, or from generics with the where T : new() constraint, but it avoids the more likely new Foo() scenario.

like image 195
Marc Gravell Avatar answered Jan 21 '26 13:01

Marc Gravell


I have another solution for you: move your 'private' constructor out of your class, and use a serialization surrogate - that way your magic constructor will never be used outside of serialization as it's now part of the serialization process per se.

like image 26
Florian Doyon Avatar answered Jan 21 '26 13:01

Florian Doyon