使用XmlSerializer序列化类型时,如果它具有空字段

时间:2015-12-05 22:32:26

标签: c# serialization ixmlserializable

这是一个独立的示例程序,可以演示我的问题:https://gist.github.com/jennings/46c20733df559d02b9ad

我正在编写类似Maybe<T>的类型:

public struct Maybe<T> : IXmlSerializable where T : class
{
    readonly T _value;
    //...
}

我可以完成序列化这两个目标中的一个吗?

  1. 如果正在序列化类型Maybe<T>的属性,如果_value为空,则不要发出该属性(字符串属性似乎具有此行为)。

  2. 序列化_value的{​​{1}}

  3. 因此,如果使用我的类型的类看起来像这样:

    Maybe<T>

    然后如果public class AnyRandomObjectUsingMyType { public Maybe<string> MaybeAString{ get; set; } } 为null,我在序列化时想要这个:

    MaybeaString._value

    想要其中任何一个:

    <AnyRandomObjectUsingMyType>
    </AnyRandomObjectUsingMyType>
    

    我不想在<AnyRandomObjectUsingMyType> <MaybeAString xsi:nil="true" /> </AnyRandomObjectUsingMyType> <AnyRandomObjectUsingMyType> <MaybeAString></MaybeAString> </AnyRandomObjectUsingMyType> 上配置序列化,因为会有很多很多。我更倾向于AnyRandomObjectUsingMyType控制它,所以到处都有相同的行为。

    某些上下文

    Maybe<T>类型是Maybe<T>的替代品。但我们在几个地方使用XML序列化。如果有这样的对象:

    T

    当SomeValue为null时,此类序列化为:

    // Version 1 class
    public class SomethingBeingSerialized
    {
        public string SomeValue { get; set; }
    }
    

    我希望能够将课程更改为:

    <SomethingBeingSerialized>
    </SomethingBeingSerialized>
    

    我希望序列化表示相同。如果V1应用程序反序列化,它将获得一个空字符串。如果V2应用程序反序列化,则会得到// Version 2 class public class SomethingBeingSerialized { public Maybe<string> SomeValue { get; set; } } ,表示无。

    我已经尝试在我的Maybe<string>方法中执行此操作,但是当它被调用时,XmlWriter似乎已经在它的基础流中写了这么多:

    IXmlSerializable.WriteXml

    因此,当我的<SomeValue 方法被调用时,似乎为时已晚。也许有另一种控制方法吗?

    如果我可以指定序列化程序:&#34;遇到类型为WriteXml的对象时,请序列化其Maybe<T>属性以代替_value&#34 ;它也将实现我的目标。

1 个答案:

答案 0 :(得分:0)

不要使Maybe序列化,使其容器可序列化。您可以根据需要为Maybe构建XML节点的扩展方法,并且在被序列化的类中将包含扩展方法的返回值。

public static class MaybeMethods
{
    public static string SerializeValue<T>(this Maybe<T> source)
    {
         // Do the work to serialize the value in Maybe
    }
}

在托管类的序列化方法

public void WriteXml(XmlWriter writer)
{
     var maybeXml = myMaybe.SerializeValue();

     // if maybeXml is not null, include it in your writer
}