将嵌套列表作为变量传递不会在父列表中设置值

时间:2015-02-11 09:26:19

标签: c# list nested

请查看以下代码

public class Page
{
    public string type { get; set; }
    public List<Contains> contains { get; set; }
}

public class Contains
{
    public string type { get; set; }
    public string index {get; set;}
    public List<Contains> contains { get; set; }
}

public class PageMachine
{
    Page Page;
    List<Contains> PageContainer;

    public PageMachine(string type)
    {
        Events = new Dictionary<string, Events>();

        PageContainer = new List<Contains>();

        Page = new Page()
        {
            type = type,
            contains = PageContainer
        };
    }

    public void Add_Container(string rootIndex, string type, string index)
    {

        Contains container = new Contains()
        {
            type = type,
            index = index,
        };

        SetContainer(rootIndex, index, container, Page.contains);  
    }

    private void SetContainer(string rootIndex, string index, Contains newContainer, List<Contains> containers)
    {
        if(containers == null)
        {
            containers = new List<Contains>();
            containers.Add(newContainer);
        }
        else if(containers.Count == 0)
        {
            containers.Add(newContainer);
        }
        else if(!containers.Exists(x => x.index == rootIndex))
        {
            containers.Add(newContainer);
        }
        else
        {
            foreach (var container in containers)
            {
                if (container.index == rootIndex)
                {
                    SetContainer(index, index, newContainer, container.contains);
                }
                else
                {

                }
            }
        }
    }

实施

PageMachine page = new PageMachine("My Page");
page.Add_Container("0", "Parent 1", "0");
page.Add_Container("0", "Child 1 of Perant 1", "0.0");

这背后的想法是为页面创建容器列表,每个容器可以包含更多子容器的列表。包含的索引属性用作映射,父级0,其子级为0.0,其子级为0.0.0

我面临的问题是,当调用递归SetContainer并且在方法中传递container.contains时,Page对象并不反映List已更新。

我发现很难解释我的问题,并会澄清是否有问题。

1 个答案:

答案 0 :(得分:2)

我相信原因在于

if(containers == null)
{
    containers = new List<Contains>();
    containers.Add(newContainer);
}

您正在创建一个新的List,但您认为引用并未指出这一点,因为在通过引用传递参数时(在container.contains中为SetContainer),参考是复制

我试着说明一下。第二次调用SetContainer(递归),container.contains指向null。

container.contains --> null

此参数通过引用SetContainer传递。这意味着该参考已复制。此复制的引用是SerContainer内使用的引用,换句话说是参数containers

container.contains --> null
                       ^
                       |
containers ------------+

现在,由于containers为空,因此第一个if语句为true,并创建一个新的List,容器指向该值。

container.contains --> null

containers ----------> newList

添加项目时,会将其正确添加到newList,但container.contains未指向该项目。这就是为什么当SetContainer返回时,没有任何变化。我希望我已经清楚了。

解决此问题的一种方法是确保在调用SetContainer之前创建列表,例如将if循环中的for语句更改为

if (container.index == rootIndex)
{
    if(container.contains == null)
        container.contains = new List<Contains>();

    SetContainer(index, index, newContainer, container.contains);
}

当然从第一个containers = new List<Contains>();语句中删除if。从快速测试来看,它似乎对我有用。

有道理吗?