C# 在对聚合某个类的另一个类进行序列化期间排除该类的某些属性
我正在使用XmlSerializer。一个大类实例正在被序列化,而那个大类实例聚合(我想说它几乎拥有)较小的类,并涉及一些继承。似乎在基类中,某些属性是至关重要的,用于在序列化时镜像它们的状态。但是对于它们的一些子类,这些属性应该被抑制,因为添加了其他更可读的属性 下面是一个示例(不是真正的代码示例): 输出仍然包含这两种类型的C# 在对聚合某个类的另一个类进行序列化期间排除该类的某些属性,c#,.net,xml,C#,.net,Xml,我正在使用XmlSerializer。一个大类实例正在被序列化,而那个大类实例聚合(我想说它几乎拥有)较小的类,并涉及一些继承。似乎在基类中,某些属性是至关重要的,用于在序列化时镜像它们的状态。但是对于它们的一些子类,这些属性应该被抑制,因为添加了其他更可读的属性 下面是一个示例(不是真正的代码示例): 输出仍然包含这两种类型的x属性。列表通过引用适当的子类来包含它们,所以它不像XmlSerializer看不到它们的实际类。尽管有覆盖,但示例xml输出如下所示 <?xml version=
x
属性。列表通过引用适当的子类来包含它们,所以它不像XmlSerializer
看不到它们的实际类。尽管有覆盖,但示例xml输出如下所示
<?xml version="1.0" encoding="utf-8"?>
<BigClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<List1>
<Derived1>
<x>1</x>
<!-- other stuff -->
</Derived1>
</List1>
<List2>
<Derived2>
<x>2</x> <!-- unwanted guy -->
<y>20</y>
<!-- other stuff -->
</Derived2>
</List2>
<!-- other stuff -->
</BigClass>
似乎无法修复它。在聚合层次结构中,实际上有更多的节点,从BigClass
到Derived1/2
。将它们全部从Derived2
添加到根目录没有帮助。所以我假设这个建议即使在这个简化的情况下也不能解决它。(更新2。它不会)
(免责声明。有些人可能会说,序列化字段类似于所讨论的类的公共接口,因此将它们隐藏在派生类中有点代码味道。但我不会在这里讨论接口含义,只有实现上述目标的方法。)
XmlSerializer
有两个功能,允许从输出文件中排除某些属性:
指定的
模式(也称为旧模式),例如,如:
应该序列化()
模式,例如:
在删除继承树中的冗余字段方面,两者都有一些优点和缺点。让我们看看:
指定的
模式。用法:
public class Example
{
public int x { get; set; }
[XmlIgnore]
public bool xSpecified;
public Example()
{
xSpecified = <set your value for this class>;
}
}
public class Example
{
public int x { get; set; }
public virtual bool ShouldSerializex()
{
return <your logic expression here>;
}
}
公共类示例
{
公共整数x{get;set;}
[XmlIgnore]
指定的公共布尔值;
公共示例()
{
xsspecified=;
}
}
优点:
- 如果逻辑需要,可以在其他类中设置
缺点:
- 破坏所讨论类的封装
- 有助于对象在内存中的大小,每个对象每个属性一个布尔值
- 您必须记住将其设置为适当的值,例如在构造函数中
应该序列化()
模式。用法:
public class Example
{
public int x { get; set; }
[XmlIgnore]
public bool xSpecified;
public Example()
{
xSpecified = <set your value for this class>;
}
}
public class Example
{
public int x { get; set; }
public virtual bool ShouldSerializex()
{
return <your logic expression here>;
}
}
公共类示例
{
公共整数x{get;set;}
公共虚拟bool应序列化x()
{
返回;
}
}
优点:
- 保持类的封装,允许包含逻辑
- 每个属性没有额外的内存
- 总体上更灵活
缺点:
- 在这种情况下,必须使其成为虚拟的,以便它也可以与派生类一起工作,因此可能需要为每个对象中的vtable指针提供额外的内存
对于我的特殊问题,我在不同的地方使用了这两种方法。需要隐藏多个属性的自给自足类可以从#2中获得更多优势,特别是当项目有大量实例的列表时。小类曾经是组成大类的“砖石”,可能“愚蠢”到不知道是否序列化某些内容,这使得#1成为一种可能的选择。我不完全确定,但我认为这是正确的:重写.Add(typeof(List),“x”,ignore)代码>但是,我不确定这是否有效,因为typeof()将返回泛型集合…@MaxOvrdrv实际情况下有更多的“深度”。我添加了一些代码,比如overrides.Add(typeof(List),“x”,ignore)代码>对于我要“向上”聚合层次结构的每个节点,但它没有帮助。我将更新问题说明。其他问题的说明可能会有所帮助。它提到了附加属性XmlArrayAttribute
和XmlArrayItemAttribute
@dialogicusXmlArrayItemAttribute
有八个属性,但我不明白更改节点名称、名称空间、类型、类型ID等在这里有什么帮助。。。请你详细说明一下好吗?我也不知道。对我来说,这就像一条通往解决之路。这就是我为什么写评论而不是回答的原因。
public class Example
{
public int x { get; set; }
public virtual bool ShouldSerializex()
{
return <your logic expression here>;
}
}