繁体   English   中英

c# - DataContract序列化 - 基类,继承和覆盖

[英]c# - DataContract Serialization - Base Classes, Inheritance and Overrides

今天是个好日子,

我是一名独立游戏开发人员,过去主要与XNA合作,而另一端则是商业工具集。 然而,XNA的范围非常有限,我正在构建一个跨平台的抽象层来定位多个平台。

简而言之,我需要的xml序列化可以比[Serializable]更广泛地访问,并且我已经指出了数据合同。 我一直在做很多研究,但是找不到关于系统的一些基础知识的任何好的信息,这些信息与继承和覆盖有关。

我的问题的关键是......

[DataContract]
public class Node
{
    private string name;

    public string Name { get { return name; } set { name = value; } }
    public virtual float Rotation { get { return 0f; } set { } }
}

[DataContract]
public class FancyNode : Node
{
    private float rotation;

    public override float Rotation { get { return rotation; } set { rotation = value; } }
}

如果我序列化'FancyNode','Rotation'是否会被正确序列化,并且'Name'会被序列化吗?

后续问题:我想提前问一下,但当时无法回想起来。 序列化程序处理程序如何覆盖[IgnoreDataMember]属性? 例如...

[DataContract]
public class Simple
{
    [IgnoreDataMember]
    public virtual string Value { get { return ""; } set { } }
}

[DataContract]
public class Complex : Simple
{
    private string value;

    public override string Value { get { return value; } set { this.value = value; } }
}

“复杂”中的“价值”会被序列化吗? 一些答案表明如果没有使用[DataMember]标签,所有属性都将被序列化。 如果是这样,基类的[IgnoreDataMember]属性是否有任何影响?

据我所知,DataContract是一个'选择'序列化方法,即除非你装饰它,否则不会序列化(告诉序列化程序你要序列化它)

因此,对于上面的示例,您需要将[DataMember]添加到要序列化的属性中

使用标准的Serializable属性,序列化程序会查看所有字段,并忽略那些标记为NonSerialized的字段

这里有一些例子:

http://jamescbender.azurewebsites.net/?p=651

有关序列化的信息以及发生的事情的大致轮廓,请查看此处的注释部分:

http://msdn.microsoft.com/en-us/library/ms733127.aspx

编辑:此外,我看不出为什么任何标记为[DataMember]的字段无法正确序列化的原因。 序列化的DataContract方法也可以处理循环引用 - 其他序列化有时会遇到以下问题:

http://msdn.microsoft.com/en-us/library/hh241056.aspx

一些答案中提出的一些想法尚不清楚。 请让我把它们清理干净。 首先,使用DataContract的序列化程序可用于序列化未使用DataContract修饰的类型。 您只需要告知有关它们的问题。

例如,DataContractJsonSerializer类将一个类型序列化为一个JSON对象(通常是一个字符串。)您需要告诉它的是您要序列化的对象类型,然后是它可能引用的任何其他类型:

var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(MyClass), new Type[] { Type1, Type2, Type3 });

序列化程序将自动序列化每个公共字段和类型的属性。 有关更多信息,请参阅http://msdn.microsoft.com/en-us/ms733127

DataContractAttribute标记类型

使用DataContractAttribute标记类型后,将该类型转换为自动已知类型(您不需要将其作为子类型提供),并将属性和字段转换为选择加入模式。

因此,您必须使用DataMemberAttribute装饰要序列化的每个字段或属性。 这意味着IgnoreDataMemberAttribute是无用的。 它是,序列化程序不会查找它,因为任何未标记DataMemberAttribute东西都会被自动忽略。

未标记的DataContractAttribute类型

序列化未应用DataContractAttribute的类型时,如前所述,将序列化每个公共属性或字段。 因此,此处使用IgnoreDataMemberAttribute来防止属性或字段被序列化。

您应该在合同应公开的属性中包含[DataMember]属性。

[DataContract]
public class FancyNode : Node
{
    private float rotation;

    [DataMember]
    public override float Rotation { get { return rotation; } set { rotation = value; } }
}

请注意,Windows Communication Foundation(WCF)使用数据协定序列化程序来序列化和反序列化数据(将数据转换为XML或从XML转换)。 所以实际上你还在使用Xml序列化。

不会因为Opt-In方法而无法序列化,您必须将DataMember明确应用于您的基类。 如果您在子类中继承,则数据序列化不会自动运行

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM