我想像这样使用XML序列化:
class Foo {
public Foo (string name) {
Name1 = name;
Name2 = name;
}
[XmlInclude]
public string Name1 { get; private set; }
[XmlInclude]
private string Name2;
}
StreamWriter wr = new StreamWriter("path.xml");
new XmlSerializer<Foo>().Serialize (wr, new Foo ("me"));
编辑:我知道这段代码错了。这只是为了展示我想如何使用它。
但这根本不起作用:
我错过了什么,XmlSerializer实际上提供了所描述的可能性吗?是否有替代的XML序列化程序可以更复杂地处理这些情况?
如果不是:我们毕竟是在2010年,.NET已经存在多年了。通常使用XML序列化,完全标准化,并且应该非常容易执行。或者我的理解可能是错误的,并且XML序列化不应该出于充分的理由暴露所描述的特征?
编辑:遗产不是一个很好的理由imo。 List
一开始也是非通用的。
(随意调整标题或标签。如果这应该是CW,请只需删除一个注释。)
答案 0 :(得分:11)
见XmlSerializer class。你会发现你错了。 XmlInclude
的目的完全不同。
此外,从那时起,更好的技术已经到来:
将来不太可能增强XML Serializer。我建议你学习其他选择。
答案 1 :(得分:10)
首先是固定代码,然后是问题的答案:
public class Foo {
public Foo() : this("") {}
public Foo (string name) {
Name1 = name;
Name2 = name;
}
// note only this will be serialized
public string Name1 { get; private set; }
// this won't
private string Name2;
}
或3.0:
[DataContract]
class Foo {
public Foo (string name) {
Name1 = name;
Name2 = name;
}
[DataMember]
public string Name1 { get; private set; }
[DataMember]
private string Name2;
}
(并使用DataContractSerializer
代替XmlSerializer
)
XmlSerializer不是通用的。我必须对(de)序列化进行反对操作。
这对于序列化程序来说很常见。我有自己的序列化程序,最初我做了使它完全通用。结果证明这是一个很大的设计错误。巨大。不,真的。我目前正在重写每个代码行以将其切换出来。
简单;序列化程序通常涉及某种程度的反射(对于代码生成或实际工作,取决于实现)。反射和泛型不能很好地发挥作用,尤其是在像WCF这样的一些框架上。让你的代码做最后的演员是一个公平的妥协。如果您真的想要,我有一个号的博客条目
每个房产都必须完全公开。
这确实是XmlSerializer
的限制(虽然列表/集合没有一个setter是好的,如果你有一个公共获取,它将抛出私人套装)。此外,类型需要是公共的并且具有无参数构造函数。
为什么我们不只是使用Reflection访问私有设置器?
对于性能,XmlSerializer
动态构建程序集以执行您想要的操作。它无法自动访问代码的内部。有关信息,我正在做类似的事情,但我提供2级生成;完全静态(进入可部署的dll),然后只能与公共成员或内存一起使用, 仍然可以访问私有成员。我猜他们只想解决一个模型,这很有意义 - 他们需要“sgen”,它决定了第一个模型。
无法序列化私有字段。我想用属性装饰私有字段,让XmlSerializer包含它们。
然后使用DataContractSerializer
,它将序列化标记为[DataMember]
的任何成员(包括私人)。
答案 2 :(得分:7)
1:遗产。 XML Serializer早于泛型。它与.NET 1.0一样。
2:设计决定。与其他解决方案相比,XML序列化程序应该使用非常有限的权限。
3:与2相同。
您可以在部分中使用WCF DataContract序列化程序。
你的假设是“有限的错误”。 XML序列化应该用于传输文档,在我的项目中,它总是独立的类,不做其他任何事情。因此,我对所有限制没有任何问题。
答案 3 :(得分:1)
你不需要 [XmlInclude] 就像你拥有它一样。您可以使用 [的XmlElement] [XmlAttribute] ... 描述类序列化的方式。
取出[XmlInclude]并查看是否有效。
class Foo {
public Foo (string name) {
Name1 = name;
Name2 = name;
}
[XmlAttribute]
public string Name1 { get; set; }
[XmlAttribute]
public string Name2;
}
Foo myFoo = new Foo("FirstName", "LastName");
StreamWriter wr = new StreamWriter("path.xml");
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
serializer.Serialize(wr, myFoo);
更新后,序列化属性应该是公开的。
答案 4 :(得分:0)
顺便说一句,DataContract从不支持二进制序列化,它序列化为xml但支持二进制编码。