C# - Property is causing StackOverflow

2020-05-01 10:00发布

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

*Edit:* I realized when I put this code in SO that the TotalCount property is adding the UnassignedCount + the TotalCount (I meant to add the other two counts together). Can someone please provide a throughough explanation on why the SO error occurs though? I mean, the low-level stuff.

Stackoverflowing!

9条回答
唯我独甜
2楼-- · 2020-05-01 10:41

you are in an infinite recursion, a property calling itself

查看更多
你好瞎i
3楼-- · 2020-05-01 10:43

There is a mechanism called the "stack," used to track nested calls. When you call a method or function, the current "stack frame" (the address that control will transfer to when the method you called returns, as well as any parameters and method locals in your method) are pushed onto the stack. When control returns to your method, this stack frame is popped off and the CPU registers are restored to their prior state so that your method can continue executing.

The stack is a fixed allocation of memory, and therefore you can only call so many levels deep before you run out of places to store the information that is necessary to restore the state of the CPU registers when your function is returned to. At this point, a stack overflow error happens because, well, you overflowed the stack. You made so many nested calls that you ran out of memory to record them in.

That's why the exception happens. You recurse infinitely: your property getter calls itself over and over and over until there is no more room on the stack.

查看更多
等我变得足够好
4楼-- · 2020-05-01 10:47

Can someone please provide a throughough explanation on why the SO error occurs though?

Sure: in order to calculate TotalCount, the compiler generates code like this:

  • Get UnassignedCount
  • Get TotalCount
  • Add UnassignedCount to TotalCount
  • Return the result

When calling the property getter of TotalCount (remember, a getter is a regular no-argument function that uses a special syntax), the runtime places the return address on the stack. The second step finds us back at the beginning, with one extra return address on the stack; the third step does it again, then the forth, the fifth, and so on. Each invocation deposits another return address on the stack. This continues all the way to the limit of the stack, at which point an exception is thrown.

查看更多
等我变得足够好
5楼-- · 2020-05-01 10:51

Because the call stack would get (theoretically) infinitely deep. And you don't have an infinite stack to keep all the data you would need.

查看更多
仙女界的扛把子
6楼-- · 2020-05-01 10:55

Because you are referring to TotalCount within the TotalCount getter. An infinite loop occurs until a stack overflow is reached.

查看更多
Anthone
7楼-- · 2020-05-01 11:00

You should be able to write this: You should note that TotalCount can never be set to so it would have no value. Did you perhaps mean to do this:

public class ModelInfo
{
    public int AssignedCount { get; set; }
    public int UnassignedCount { get; set; }
    public int TotalCount { get { return UnassignedCount + AssignedCount; } }
}
查看更多
登录 后发表回答