C# 使用XmlSerializer拒绝某些IList变量和自定义get属性的意外行为

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);

我正在使用XmlSerializer序列化一个类的对象列表,该类也有一些列表对象

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实现,这可能是另一个讨论的问题:),但这是我选择的避免无意中修改列表的方式,即列表上有哪些对象。序列化可以工作,但反序列化不会还原文档和测试数组。这在本文中有解释。