【问题标题】:DataContract serialization of an inherited type into a base typeDataContract 将继承类型序列化为基本类型
【发布时间】:2011-05-23 13:38:01
【问题描述】:

我正在尝试将类 B 序列化为 ita 基类 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 中添加了完整的实例类型名称)并且使用起来更加笨拙。

【问题讨论】:

  • 它必须是 XML?还是只能工作?
  • 它可以正常工作。不过,最少的麻烦会很好。

标签: c# inheritance serialization datacontractserializer datacontract


【解决方案1】:
[DataContract(Name="YouCannotSeeMyName")]
[KnownTypes(typeof(B))]
public class B : A

你会得到

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

【讨论】:

  • 我认为这仍然会序列化 B 的所有成员,这不是 OP 的意图。
  • @Mark Avenius:如果 OP 没有将 [DataMember] 属性放在 B 的属性上,则不会。
  • 序列化工作正常,但是在进行反序列化的项目中没有引用 B 类型,它会引发异常。我想那是做不到的 :( 我创建了一个新的 A 实例并用 B 的实例反射性地初始化它。这相当难看,但它可以工作:(
  • 注意错字:“KnownType”,而不是“KnownTypes”。 (我对此效果的编辑被拒绝,因为我必须添加另一行以使编辑超过 6 个字符)
【解决方案2】:

我很确定您不能隐藏部分合同。这类似于处理 Web 服务,其中每个端都必须遵守合同以了解序列化/反序列化的方式和内容。

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

    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" />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    相关资源
    最近更新 更多