Search code examples
c#recursionmathstack-overflowgetter

Stack Overflow Exception C#


I have encountered this error

Process is terminated due to StackOverflowException.

The source of error come from this code

 internal class Record
{
    [Name("Name")]
    public string Name { get; set; }
    [Name("Principal")]
    public int Principal { get { return Math.Abs(Principal); } set {; } }

}

I searched the error and it state the error occur because of recursive. I think my Principal method is not recursive method.


Solution

  • Perhaps you want to consider one of these:

    internal class Record
    {
        [Name("Name")]
        public string Name { get; set; }
        
        [Name("Principal")]
        public int Principal { get; set; }
    
        [Name("AbsPrincipal")]
        public int AbsPrincipal { get { return Math.Abs(Principal); } set; }
    
    }
    
    internal class Record
    {
        [Name("Name")]
        public string Name { get; set; }
        
        [Name("Principal")]
        private int _principal = 0;
        public int Principal { 
          get => _principal; 
          set => _principal = Math.Abs(value); 
        }
    
    }
    

    Any property or method that returns the result of getting its own value with nothing to stop it will overflow the stack. Recursive things that at work correctly usually have something with a condition that eventually changes state and stops the recursion (doesn't return the result of getting its own value)

    Take a look at the first one: we don't make the property math.abs itself, we make it abs something else - this cannot recurse unless the something else were to return the first thing (then the recursion would flip flop between them)

    The second one is probably more like what you want to do- again we abs something else (a backing variable) rather than the property itself preventing recursive overflow. In this one I abs on the set because it seems you never wanted to retrieve the non Abs value for principal so we might as well abs it when we store it then we can just retrieve it a million times without abs each time.. of course if you ever need private access to the non Abs'd variable you should do the abs on the get.. or if you know your use case will be that to store it a million times and only get it once, again do the abs on the get rather than the set. The typical program behavior I would expect in most cases is to set fewer times than get so we can avoid unnecessary work by choosing carefully when to do the abs