1

这是一个独立的示例程序,演示了我的问题: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 代替.Maybe<T>

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

public class AnyRandomObjectUsingMyType
{
    public Maybe<string> MaybeAString{ get; set; }
}

然后如果MaybeaString._value为空,我想要在序列化时这样做:

<AnyRandomObjectUsingMyType>
</AnyRandomObjectUsingMyType>

想要这些:

<AnyRandomObjectUsingMyType>
  <MaybeAString xsi:nil="true" />
</AnyRandomObjectUsingMyType>

<AnyRandomObjectUsingMyType>
  <MaybeAString></MaybeAString>
</AnyRandomObjectUsingMyType>

我不想配置序列化,AnyRandomObjectUsingMyType因为会有很多很多。我宁愿Maybe<T>控制它,这样到处都有相同的行为。


一些上下文

该类型Maybe<T>旨在作为T. 但是我们在几个地方使用了 XML 序列化。如果有这样的对象:

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

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

<SomethingBeingSerialized>
</SomethingBeingSerialized>

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

// Version 2 class
public class SomethingBeingSerialized
{
    public Maybe<string> SomeValue { get; set; }
}

我希望序列化的表示是相同的。如果 V1 应用程序反序列化,它会得到一个空字符串。如果 V2 应用程序反序列化,它会得到一个Maybe<string>表示无的。

我已经尝试在我的IXmlSerializable.WriteXml方法中这样做,但是当它被调用时,XmlWriter 似乎已经向它的底层流写入了这么多内容:

<SomeValue 

因此,当我的WriteXml方法被调用时,似乎为时已晚。也许还有另一种方法来控制它?

如果我可以向序列化程序指定:“一旦遇到 type 的对象Maybe<T>,就序列化它的_value属性来代替Maybe<T>”,它也将实现我的目标。

4

1 回答 1

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
}
于 2015-12-05T23:04:20.047 回答