C# 使用XmlSerializer拒绝某些IList变量和自定义get属性的意外行为
我正在使用XmlSerializer序列化一个类的对象列表,该类也有一些列表对象C# 使用XmlSerializer拒绝某些IList变量和自定义get属性的意外行为,c#,xml,serialization,deserialization,C#,Xml,Serialization,Deserialization,我正在使用XmlSerializer序列化一个类的对象列表,该类也有一些列表对象 public class Configuration { private IList<Project> _projects = null; public IList<Project> Projects { get { return new List<Project>(_projects);
public class Configuration
{
private IList<Project> _projects = null;
public IList<Project> Projects
{
get
{
return new List<Project>(_projects);
}
set
{
_projects = value;
}
}
public void Load()
{
//Here takes place the deserialization
}
public void Save()
{
//Here takes place the serialization
}
}
public class Project
{
public string Name { get; set; }
private IList<Document> _documents = null;
public IList<Document> Documents
{
get
{
return new List<Document>(_documents);
}
set
{
_documents = value;
}
}
private IList<Test> _tests = null;
public IList<Test> Tests
{
get
{
return new List<Test>(_tests);
}
set
{
_tests = value;
}
}
}
公共类配置
{
私有IList_projects=null;
公共IList项目
{
得到
{
返回新列表(_项目);
}
设置
{
_项目=价值;
}
}
公共空荷载()
{
//这里发生反序列化
}
公共作废保存()
{
//这里发生序列化
}
}
公共类项目
{
公共字符串名称{get;set;}
私有IList_文档=null;
公共IList文件
{
得到
{
返回新列表(_文档);
}
设置
{
_文件=价值;
}
}
私有IList_测试=null;
公共IList测试
{
得到
{
返回新列表(_测试);
}
设置
{
_测试=数值;
}
}
}
此实现无法在运行时抛出关于文档或测试变量为接口类型(IList,项目中似乎没有问题的细节)的异常。如果我将文档和测试更改为列表,那么异常就消失了,但会出现另一个问题(不相关)。序列化不会序列化文档和测试数组(因此,反序列化无法还原这些变量)。如果我更改这两个属性的自定义get实现,直接返回_文档和_测试,它将按预期工作。但是,Projects属性也有一个定制的get实现,它可以按预期工作
public class Configuration
{
private IList<Project> _projects = null;
public IList<Project> Projects
{
get
{
return new List<Project>(_projects);
}
set
{
_projects = value;
}
}
public void Load()
{
//Here takes place the deserialization
}
public void Save()
{
//Here takes place the serialization
}
}
public class Project
{
public string Name { get; set; }
public List<Document> Documents { get; set; }
public List<Test> Tests { get; set; }
}
公共类配置
{
私有IList_projects=null;
公共IList项目
{
得到
{
返回新列表(_项目);
}
设置
{
_项目=价值;
}
}
公共空荷载()
{
//这里发生反序列化
}
公共作废保存()
{
//这里发生序列化
}
}
公共类项目
{
公共字符串名称{get;set;}
公共列表文档{get;set;}
公共列表测试{get;set;}
}
我当然可以接受,但我怀疑我可能做错了什么。首先,我看不出为什么我可以将项目序列化为IList而不是文档或测试。第二,我看不出项目自定义getter工作的原因,但它阻止了文档和测试的反正确序列化
我还尝试使用DataContractSerializer,它是开箱即用的,但我更喜欢XmlSerializer更清晰的xml输出
有什么提示吗
附言:完整的VS 2015解决方案以及完整的实施和测试可在以下链接中下载:您希望使DTO尽可能简单。我甚至可能会使用
Document[]
和Test[]
。问题是序列化程序不知道反序列化时在幕后使用lList
的哪个实现。@dana我可以理解,但为什么IList项目在序列化中不是问题?我同意@dana。另一个问题:为什么getter返回新列表(\u项目)代码>?每次使用复制构造函数创建时,它们都会返回新列表(不确定传递null时复制构造函数的行为,可能只是返回一个空列表),但在任何时候都肯定不会设置\u project
变量。它将始终为null
。这不太可能是预期的行为?@YeldarKurmangaliyev正如我所说的,我理解C#引发的异常,IList是一种接口类型,无法序列化。但它正在被序列化(至少在Projects属性中)。关于getters实现,这可能是另一个讨论的问题:),但这是我选择的避免无意中修改列表的方式,即列表上有哪些对象。序列化可以工作,但反序列化不会还原文档和测试数组。这在本文中有解释。