Here's a self-contained sample program that demonstrates my question: https://gist.github.com/jennings/46c20733df559d02b9ad
I'm writing a type Maybe<T>
which looks like this:
public struct Maybe<T> : IXmlSerializable where T : class
{
readonly T _value;
//...
}
Can I accomplish one of these two goals of the serialization?
If a property of type
Maybe<T>
is being serialized, do not emit the property at all if its_value
is null (string properties seem to have this behavior).Serialize the
_value
in place of theMaybe<T>
.
So if a class using my type looks like this:
public class AnyRandomObjectUsingMyType
{
public Maybe<string> MaybeAString{ get; set; }
}
Then if MaybeaString._value
is null, I want this when serialized:
<AnyRandomObjectUsingMyType>
</AnyRandomObjectUsingMyType>
I do not want either of these:
<AnyRandomObjectUsingMyType>
<MaybeAString xsi:nil="true" />
</AnyRandomObjectUsingMyType>
<AnyRandomObjectUsingMyType>
<MaybeAString></MaybeAString>
</AnyRandomObjectUsingMyType>
I don't want to configure the serialization on AnyRandomObjectUsingMyType
because there will be many, many of those. I'd much rather have Maybe<T>
control this so everywhere gets the same behavior.
Some context
The type Maybe<T>
is meant as a drop-in replacement for a T
. But we use XML serialization in several places. If there's an object like this:
// Version 1 class
public class SomethingBeingSerialized
{
public string SomeValue { get; set; }
}
When SomeValue is null, this class serializes to this:
<SomethingBeingSerialized>
</SomethingBeingSerialized>
I want to be able to change the class to this:
// Version 2 class
public class SomethingBeingSerialized
{
public Maybe<string> SomeValue { get; set; }
}
And I want the serialized representation to be identical. If a V1 app deserializes, it gets a null string. If a V2 app deserializes, it gets a Maybe<string>
which represents None.
I've tried doing this in my IXmlSerializable.WriteXml
method, but when it gets called, the XmlWriter seems to already have written this much to it's underlying stream:
<SomeValue
So it seems like by the time my WriteXml
method gets called, it's too late. Maybe there's another way to control this?
If I could specify to the serializer: "As soon as you encounter an object of type Maybe<T>
, serialize its _value
property in place of the Maybe<T>
", it would also accomplish my goal.