[英]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方法也可以处理循环引用 - 其他序列化有时会遇到以下问题:
一些答案中提出的一些想法尚不清楚。 请让我把它们清理干净。 首先,使用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
标记类型后,将该类型转换为自动已知类型(您不需要将其作为子类型提供),并将属性和字段转换为选择加入模式。
因此,您必须使用DataMemberAttribute
装饰要序列化的每个字段或属性。 这意味着IgnoreDataMemberAttribute
是无用的。 它是,序列化程序不会查找它,因为任何未标记DataMemberAttribute
东西都会被自动忽略。
序列化未应用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.