可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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!
回答1:
You're calling TotalCount
from within TotalCount
, don't do that.
You can have another field for the value of the property instead.
Though, I suspect your code should read as:
public int TotalCount { get { return UnassignedCount + AssignedCount ; } }
EDIT:
as for why the stackoverflow occurs, it is because when you're using Properties, the .NET compiler will actually generate 2 functions, set_PropertyName
and get_PropertyName
. So in essense, it causes a stackoverflow from the get_PropertyName
method call that becomes infinitely deep.
回答2:
The easiest way to see what's happening (IMO) is to translate these properties into methods:
// 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();
}
Now the recursion within GetTotalCount()
should be really clear. The method unconditionally calls itself, so blows up the stack eventually.
The mixture of auto-implemented properties and the fact that property accesses look like field accesses sometimes gets in the way of remembering that they're really just methods in disguise. Hopefully the translation above makes it all more obvious.
回答3:
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.
回答4:
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; } }
}
回答5:
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.
回答6:
Because you are referring to TotalCount
within the TotalCount
getter. An infinite loop occurs until a stack overflow is reached.
回答7:
You are looping round and round when trying to get the value for TotalCount
So roughly, the logic for getting TotalCount is:
- Get value for UnassignedCount
- Get value for Totalcount
repeat, rinse and wash.
Edit: as for why, have a look at Wiki
回答8:
you are in an infinite recursion, a property calling itself
回答9:
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.