2013-03-26 443 views
1

我在代碼的這一部分遇到堆棧溢出異常,這顯然是因爲Customer對象調用CustomerBackgroundLevel對象的列表,每個對象都創建一個新的客戶對象。我試圖找到解決這個問題的一種方式,任何幫助,將不勝感激..避免堆棧溢出異常

客戶構造 -

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); 
    } 
+0

作爲一種解決方案,可能需要爲CustomerVO添加一個構造函數重載,該Customer重載需要一個CustomerVO。然後,您可以直接將其分配給「CustomerBackgroundLevelVO.Customer」,而不是實例化一個新的。然後,在CustomerVO構造函數中的Linq調用看起來像:CustomerBackgroundLevels = item.CustomerBackgroundLevels.Select(c => new CustomerBackgroundLevelVO(c,this))。ToList()'這將避免無限循環。這隻有在你想要重複使用同一個'CustomerVO'對象時纔有意義,並且B)不介意傳遞一個未完全初始化的對象。 – 2013-03-26 13:13:04

+0

或者更好的是,在構造函數中拋棄所有這些佈線/子對象構造,並將其委託給特定的'Factory'或'Builder'對象,以便爲這些對象創建/佈線並避免所有嵌套/遞歸相互依賴。 – 2013-03-26 13:14:44

回答

1

你可以像這樣解決你的循環:

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); 
} 
+0

感謝你的工作,非常好。可能現在不得不重新考慮這種方法,由於初始加載速度:( – user1948635 2013-03-26 17:04:25

2

是啊,正如您在這樣的一個循環陳述創建新的對象是會導致什麼好。

而不是在您的構造函數中創建所有這些包裝對象,爲什麼不按需要包裝它們?也就是說,當您執行一些需要CustomerVO對象的代碼時,請在該函數內創建CustomerVO對象,然後在函數結束時讓它超出範圍。

0

這是一個複製構造函數嗎?如果是這樣,您需要創建一個用於複製項目的自定義構造函數,而不是在新建對象並複製它的兩種場景中使用它。

return new CustomerVO(item); 

以上是不必要的,並且該問題行是:

Customer = new CustomerVO(item.Customer); 

更改上面的行到這樣的:

Customer = item.Customer; 

除非你具有參考問題,這意味着需要設計一個新的構造函數。

如果item.Customer對象不是CustomerVO對象,則需要將當前CustomerVO對象的引用傳遞給CustomerBackgroundLevelVO的構造函數。