2012-08-22 34 views
0
public class ModelInfo 
{ 
    public int AssignedCount { get; set; } 
    public int UnassignedCount { get; set; } 
    public int TotalCount { get { return UnassignedCount + TotalCount; } } 
} 

* 編輯: * 當我使TOTALCOUNT屬性添加UnassignedCount +的TOTALCOUNT把這個代碼,我意識到(我的意思是添加其他兩項罪名一起)。有人可以提供關於SO錯誤發生的原因的全面解釋嗎?我的意思是,低級別的東西。C# - 屬性導致的StackOverflow

Stackoverflowing!

+3

你想知道爲什麼會發生堆棧溢出?無限遞歸就是答案。 'TotalCount'''調用''TotalCount''調用''TotalCount'哪個...你明白了。 –

回答

13

你打電話TotalCountTotalCount,不這樣做。

您可以使用另一個屬性值的字段。

雖然,我懷疑你的代碼應閱讀:

public int TotalCount { get { return UnassignedCount + AssignedCount ; } } 

編輯: 至於爲什麼會出現計算器,那是因爲當你使用屬性時,.NET編譯器將實際產生2個功能,set_PropertyNameget_PropertyName。所以在本質上,它會導致來自get_PropertyName方法調用的堆棧溢出變得無限深。

0

因爲您指的是TotalCount中的TotalCount獲得者。發生無限循環直到達到堆棧溢出。

0

你是循環一圈又一圈的時候試圖獲得價值TotalCount

所以粗略,用於獲取TOTALCOUNT的邏輯是:

  • 爲UnassignedCount
  • 獲得價值爲TOTALCOUNT
  • 獲得價值

重複,沖洗和洗滌。

編輯:至於爲什麼,看看Wiki

0

你在無限循環,屬性自稱

0

由於調用棧是會得到(理論上)無限深。而且你沒有無限的堆棧來保存你需要的所有數據。

1

有一種稱爲「堆棧」的機制,用於跟蹤嵌套調用。當你調用一個方法或函數時,當前的「棧幀」(當你調用的方法返回的時候控件將要傳遞的地址,以及方法中的任何參數和方法局部變量)被壓入堆棧。當控制權返回到您的方法時,此堆棧框將彈出,並且CPU寄存器將恢復到其先前的狀態,以便您的方法可以繼續執行。

堆棧是一個固定分配的內存,因此,你只能叫這麼多層次深,你跑出來的地方來存儲要恢復CPU寄存器的狀態時,你的功能是信息之前返回。此時,會發生堆棧溢出錯誤,因爲您溢出堆棧。你做了很多嵌套調用,你用盡內存來記錄它們。

這就是發生異常的原因。你無限遞歸:你的財產獲取者一遍又一遍地調用自己,直到堆棧中沒有更多空間。

3

有人可以提供一個關於爲什麼SO錯誤發生儘管通過解釋嗎?

肯定的:爲了計算TotalCount,編譯器生成這樣的代碼:

  • 獲取UnassignedCount
  • 獲取TotalCount
  • 添加UnassignedCountTotalCount
  • 返回結果

當調用屬性獲取器TotalCount(記住,getter是一個使用特殊語法的常規無參數函數)時,運行時將返回地址放置在堆棧上。第二步在開始時找到我們,在棧上有一個額外的返回地址;第三步再次執行,然後是第四步,第五步等。每次調用都會在堆棧上存放另一個返回地址。這一直持續到堆棧的極限,此時拋出異常。

4

,看看發生了什麼(IMO)最簡單的方法是將這些屬性轉化爲方法:

// If we didn't have properties, this is what the two first lines would be. Ick! 
private int assignedCount; 
private int unassignedCount; 

public int GetAssignedCount() 
{ 
    return assignedCount; 
} 

public void SetAssignedCount(int value) 
{ 
    assignedCount = value; 
} 

public int GetUnassignedCount() 
{ 
    return unassignedCount; 
} 

public void SetUnassignedCount(int value) 
{ 
    unssignedCount = value; 
} 

// And here's the read-only TotalCount property translation 
public int GetTotalCount() 
{ 
    return GetUnassignedCount() + GetTotalCount(); 
} 

現在內GetTotalCount()遞歸應該是很清楚。該方法無條件地調用它自己,所以最終打碎了堆棧。

自動實現的屬性和屬性訪問看起來像這樣的事實混合在一起,有時會讓人想起它們實際上只是變相的方法。希望上面的翻譯更加明顯。

2

您應該可以這樣寫: 您應該注意,TotalCount永遠不能設置爲無值。你有沒有這樣做的意思:

public class ModelInfo 
{ 
    public int AssignedCount { get; set; } 
    public int UnassignedCount { get; set; } 
    public int TotalCount { get { return UnassignedCount + AssignedCount; } } 
}