DataContract将继承类型序列化为基类型

时间:2010-12-10 15:40:42

标签: c# inheritance serialization datacontractserializer datacontract

我正在尝试将类B序列化为它的基类A的实例。 DataContractSerializer不允许我这样做。

序列化失败的示例如下:

class Program
{
    [DataContract]
    public class A
    {
        public int Id { get; set; }
    }

    [DataContract]
    public class B : A
    {

    }


    static void Main(string[] args)
    {
        A instance = new B { Id = 42 };

        var dataContractSerializer = new DataContractSerializer(typeof(A));
        var xmlOutput = new StringBuilder();
        using (var writer = XmlWriter.Create(xmlOutput))
        {
            dataContractSerializer.WriteObject(writer, instance);
        }

    }
}

我知道通过添加KnownTypes属性可以轻松解决问题。 但是我希望将类B隐藏在项目中(不添加引用)。

是否有可能实现我想要的目标?我尝试了XmlSerializer,但它给了我同样的问题(它在XML中添加了完整的实例类型名称)并且使用起来更加笨拙。

2 个答案:

答案 0 :(得分:3)

[DataContract(Name="YouCannotSeeMyName")]
[KnownTypes(typeof(B))]
public class B : A

你会得到

<A itype="YouCannotSeeMyName">
  ...
</A>

答案 1 :(得分:1)

我很确定你不能隐藏部分合同。这类似于处理Web服务,其中必须为每一端都遵守合同,以了解如何以及如何将序列化/反序列化。

此外,您可以在B内传递DataContractSerializer类型,而不是使用该属性。

    class Program
    {
        [DataContract]
        public class A
        {
            public int Id { get; set; }
        }

        [DataContract]
        public class B : A
        {

        }

        static void Main(string[] args)
        {
            A instance = new B { Id = 42 };

            var dataContractSerializer = new DataContractSerializer(typeof(A), new List<Type>() { typeof(B) });
            var xmlOutput = new StringBuilder();
            using (var writer = XmlWriter.Create(xmlOutput))
            {
                dataContractSerializer.WriteObject(writer, instance);
            }

        }
    }

哪会给你......

<Program.A xmlns:i="http://www.w3.org/2001/XMLSchema-instance" i:type="Program.B"
xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication1" />