Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 避免堆栈溢出异常_C#_Asp.net_Linq To Entities_Stack Overflow_Infinite Loop - Fatal编程技术网

C# 避免堆栈溢出异常

C# 避免堆栈溢出异常,c#,asp.net,linq-to-entities,stack-overflow,infinite-loop,C#,Asp.net,Linq To Entities,Stack Overflow,Infinite Loop,在这段代码中,我遇到了堆栈溢出异常,这显然是因为Customer对象调用了CustomerBackgroundLevel对象列表,每个对象都创建了一个新的Customer对象。我正试图找到解决这个问题的办法,如果有任何帮助,我将不胜感激 客户建造师- public CustomerVO(Customer item) { CustomerID = item.CustomerID; CustomerName = item.CustomerName;

在这段代码中,我遇到了堆栈溢出异常,这显然是因为Customer对象调用了CustomerBackgroundLevel对象列表,每个对象都创建了一个新的Customer对象。我正试图找到解决这个问题的办法,如果有任何帮助,我将不胜感激

客户建造师-

public CustomerVO(Customer item)
    {
        CustomerID = item.CustomerID;
        CustomerName = item.CustomerName;
        ECNNumber = item.ECNNumber;

        CustomerBackgroundLevels = item.CustomerBackgroundLevels.Select(c => new CustomerBackgroundLevelVO(c)).ToList();
    }
        public CustomerBackgroundLevelVO(CustomerBackgroundLevel item)
    {
        CustomerBackgroundLevelID = item.CustomerBackgroundLevelID;
        CustomerID = item.CustomerID;
        BackgroundLevelID = item.BackgroundLevelID;
        StartDate = item.StartDate;
        EndDate = item.EndDate;
        Customer = new CustomerVO(item.Customer);
        BackgroundLevel = new BackgroundLevelVO(item.BackgroundLevel);
    }
客户后台级构造函数-

public CustomerVO(Customer item)
    {
        CustomerID = item.CustomerID;
        CustomerName = item.CustomerName;
        ECNNumber = item.ECNNumber;

        CustomerBackgroundLevels = item.CustomerBackgroundLevels.Select(c => new CustomerBackgroundLevelVO(c)).ToList();
    }
        public CustomerBackgroundLevelVO(CustomerBackgroundLevel item)
    {
        CustomerBackgroundLevelID = item.CustomerBackgroundLevelID;
        CustomerID = item.CustomerID;
        BackgroundLevelID = item.BackgroundLevelID;
        StartDate = item.StartDate;
        EndDate = item.EndDate;
        Customer = new CustomerVO(item.Customer);
        BackgroundLevel = new BackgroundLevelVO(item.BackgroundLevel);
    }
客户获取方法-

        public CustomerVO GetByID(int id)
    {
        var item = repository.AsQueryable().Where(x => x.CustomerID == id).FirstOrDefault();
        if (item == null)
            return null;

        return new CustomerVO(item);
    }

您可以这样解决循环:

public CustomerVO(Customer item)
{
    CustomerID = item.CustomerID;
    CustomerName = item.CustomerName;
    ECNNumber = item.ECNNumber;

    **CustomerBackgroundLevels = item.CustomerBackgroundLevels.Select(c => new CustomerBackgroundLevelVO(c,this)).ToList();
}

**public CustomerBackgroundLevelVO(CustomerBackgroundLevel item, CustomerVO vocustomer)
{
    CustomerBackgroundLevelID = item.CustomerBackgroundLevelID;
    CustomerID = item.CustomerID;
    BackgroundLevelID = item.BackgroundLevelID;
    StartDate = item.StartDate;
    EndDate = item.EndDate;
    **Customer = vocustomer;
    BackgroundLevel = new BackgroundLevelVO(item.BackgroundLevel);
}

是的,正如你所说的,在这样的循环中创建新对象不会带来任何好处


与其在构造函数中创建所有这些包装器对象,不如按需包装它们?也就是说,当您执行一些需要CustomerVO对象的代码时,请在该函数中创建CustomerVO对象,然后在函数结束时将其放在范围之外。

这是复制构造函数吗?如果是这样,您需要创建一个自定义构造函数来复制该项,而不是在两种情况下都使用它,即新建一个对象并复制它

return new CustomerVO(item);
以上内容是不必要的,问题是:

Customer = new CustomerVO(item.Customer);
将上述行更改为:

Customer = item.Customer;
除非您有引用问题,这意味着您需要设计一个新的构造函数


如果item.Customer对象不是CustomerVO对象,则需要将当前CustomerVO对象的引用传递到CustomerBackgroundLevelVO的构造函数中。

作为解决方案,可以为
CustomerBackgroundLevelVO
添加构造函数重载,该重载采用
CustomerVO
。然后您可以直接将其分配给
CustomerBackgroundLevelVO.Customer
,而不是实例化一个新的。然后,
CustomerVO
构造函数中的Linq调用将如下所示:
CustomerBackgroundLevels=item.CustomerBackgroundLevels.Select(c=>new CustomerBackgroundLevelVO(c,this)).ToList()
,这将避免无限循环。这只有在A)希望重用相同的
CustomerVO
对象,B)不介意传递未完全初始化的对象时才有意义。或者更好,在他们的构造函数中放弃所有这些连接/子对象构造,并将其委托给特定的
工厂
Builder
对象,以便为您创建/连接这些对象,并完全避免所有嵌套/递归的相互依赖关系。多亏了这一点,效果非常好。但是,由于初始负载速度,现在可能必须重新考虑这种方法:(