[英]C# XMLSerializer and sequence of attribute serialization
我对XML反序列化有问题。 好吧,假设我的课有三个属性:
public class Order
{
private string name;
[XmlAttribute("Name")]
public string Name
{
get
{
return name;
}
set
{
if (name != value)
{
name = value;
}
}
}
private string tid;
[XmlAttribute("TID")]
public string TID
{
get
{
return tid;
}
set
{
if (tid != value)
{
tid = value;
}
}
}
private Command command;
[XmlAttribute("Command")]
public string Command
{
get
{
return command.Name;
}
set
{
command = new Command(TID, Name, value);
}
}
public Order()
{
}
}
如您所见,我需要在反序列化Command属性上创建一个带有参数构造函数的Command对象,但是对此我需要TID和Name属性。 我需要确保这些字段不为空。 正如我观察到的,XmlSerializer根据用户编写序列的顺序反序列化属性。 例如:
<Order Command="SetPlus" TID="W403" Name="SomeName" />
在这种情况下,首先序列化的将是Command属性。 但是我还没有TID和Name属性! 我不能相信用户他会按正确的顺序传递属性,例如:
<Order TID="W403" Name="SomeName" Command="SetPlus" />
好吧,我需要一些事件或可以反序列化完成的东西,或者我需要确保XmlSerializer将按我想要的顺序反序列化属性。 我发现的唯一是:
[XmlElement(Order = 1)]
要么
[XmlElementAttribute(Order = 1)]
但这不适用于XmlAttribute。
有什么办法做到这一点? 希望我能清楚地解释我的问题。
如果您的Command
仅取决于TID
和Name
为什么还要序列化它? 这只是多余的信息。
您应该在Command
属性上使用[XmlIgnore]
属性。 之后,您可以为Command
属性实现一种惰性加载方法。
顺便说一句:您的代码仍然是错误的。 在Command
属性的set
部分上,甚至不使用用户传入的值。如果这样做,会更好:
private Command command;
[XmlIgnore]
public string Command
{
get
{
if (command == null)
{
command = new Command(TID, Name));
}
return command.Name;
}
}
编辑:
好的,在您更改帖子并实际使用Command
属性设置器的值之后,解决方案会有些棘手,并且有多种方法。
我可能会做什么:
CommandName
属性,这只是一个简单的字符串属性(带有getter),还向该属性添加XmlAttribute
[XmlIgnore]
添加到您的Command
属性,并从上方获取我的代码(延迟初始化),使用新的CommandName
属性( new Command(TID, Name, CommandName)
)返回命令 我个人甚至会在CommandName
属性中添加一个setter,并让Command
属性实际上返回Command
而不是string
。 在我看来,这将使代码更整洁,更易读。
为了澄清,这是我的班级样子:
public class Order
{
//todo: if Name, TID or CommandName changes you'd have to initialize a new Command objects with the new values
[XmlAttribute("Name")]
public string Name {get;set;}
[XmlAttribute("TID")]
public string TID {get;set;}
[XmlAttribute("CommandName")]
public string CommandName {get;set;}
private Command command;
[XmlIgnore]
public Command Command
{
get
{
return command ?? (command = new Command(TID, Name, CommandName));
}
}
public Order()
{
}
}
您可以在设置器中添加一些逻辑,以便在调用所有设置器后,按如下所示创建命令
public class Order
{
private string name;
[XmlAttribute("Name")]
public string Name
{
get
{
return name;
}
set
{
if (name != value)
{
name = value;
SetupCommandIfPossible();
}
}
}
private string tid;
[XmlAttribute("TID")]
public string TID
{
get
{
return tid;
}
set
{
if (tid != value)
{
tid = value;
SetupCommandIfPossible();
}
}
}
private Command command;
[XmlAttribute("Command")]
public string Command
{
get
{
return command.Name;
}
set
{
SetupCommandIfPossible();
}
}
public void SetupCommandIfPossible()
{
if (!string.IsNullOrEmpty(tid) && !string.IsNullOrEmpty(name) && command == null)
{
command = new Command(TID, Name);
}
}
public Order()
{
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.