我对C#的XmlSerializer还不熟悉,可能会错过一些基本的东西。
我的问题是,我有一个类,其中包含另一个类的List。当我序列化主类时,XML看起来很漂亮,所有数据都完好无损。但是当我反序列化XML时,List中的数据消失了,只剩下一个空的List。我没有收到任何错误消息,而且序列化部分工作得很好。
请问我在反序列化过程中错过了什么?
注:下面的代码未能复现该问题,它可以正常工作。这只是真实代码的简化版本,无法复现该问题!
执行CreateAndSave()生成的XML如下所示:
有人能解释一下为什么Characters属性可以正确序列化,但无法反序列化吗?
我的问题是,我有一个类,其中包含另一个类的List。当我序列化主类时,XML看起来很漂亮,所有数据都完好无损。但是当我反序列化XML时,List中的数据消失了,只剩下一个空的List。我没有收到任何错误消息,而且序列化部分工作得很好。
请问我在反序列化过程中错过了什么?
注:下面的代码未能复现该问题,它可以正常工作。这只是真实代码的简化版本,无法复现该问题!
public class User
{
public User()
{
this.Characters = new List<Character>();
}
public string Username { get; set; }
public List<Character> Characters { get; set; }
}
public class Character
{
public Character()
{
this.Skills = new List<Skill>();
}
public string Name { get; set; }
public List<Skill> Skills { get; set; }
}
public enum Skill
{
TreeClimber,
ForkliftOperator
}
public static void Save(User user)
{
using (var textWriter = new StreamWriter("data.xml"))
{
var xmlSerializer = new XmlSerializer(typeof(User));
xmlSerializer.Serialize(textWriter, user);
}
}
public static User Restore()
{
if (!File.Exists("data.xml"))
throw new FileNotFoundException("data.xml");
using (var textReader = new StreamReader("data.xml"))
{
var xmlSerializer = new XmlSerializer(typeof(User));
return (User)xmlSerializer.Deserialize(textReader);
}
}
public void CreateAndSave()
{
var character = new Character();
character.Name = "Tranzor Z";
character.Skills.Add(Skill.TreeClimber);
var user = new User();
user.Username = "Somebody";
user.Characters.Add(character);
Save(user);
}
public void RestoreAndPrint()
{
var user = Restore();
Console.WriteLine("Username: {0}", user.Username);
Console.WriteLine("Characters: {0}", user.Characters.Count);
}
执行CreateAndSave()生成的XML如下所示:
<User>
<Username>Somebody</Username>
<Characters>
<Character>
<Name>Tranzor Z</Name>
<Skills>
<Skill>TreeClimber</Skill>
</Skills>
</Character>
<Characters>
</User>
太好了!这就是应该的样子。如果我执行RestoreAndPrint()
,我会得到一个用户对象,其中用户名属性设置正确,但角色属性为空列表:
Username: Somebody
Characters: 0
有人能解释一下为什么Characters属性可以正确序列化,但无法反序列化吗?
public T PropertyName { get; set; }
- Andy