2
Answers

Process is terminated due to StackOverflowException.

Aditya Patil

Aditya Patil

10y
5.2k
1
I am working on C# Console application of Inheritance,
While running the Console application I am getting message in console "Process is terminated due to StackOverflowException"
I am not getting how to overcome this problem, I studied my code, may be did small mistake, please help me regarding it.
Program.cs
namespace Inheritance
{
class Program
{

static void Main(string[] args)
{
Employee e = new Employee();
Console.WriteLine("Employee");
Console.ReadLine();
}
}

Employee.cs
namespace Inheritance
{
class Employee
{
static double totalsalary,laboursalary1,managersalary1,vpsalary1;
Labour l = new Labour("ABC", 9, 100); <---------------------------Exception thrown here as stackoverflowexception
Manager m = new Manager("PQR", 10000, 5000, 1000);
VicePresident vp = new VicePresident("XYZ", 20000, 10000, 5000);
SalesManager sm = new SalesManager("KLM", 8000, 2000, 500, 50);
public Employee()
{
laboursalary1 = l.getTotalSalary();
managersalary1 = m.getTotalSalary();
vpsalary1 = vp.getTotalSalary();
}
public static double calculateTotalSalary(Labour l, Manager m, VicePresident vp, SalesManager sm)
{
totalsalary = laboursalary1 + managersalary1 + vpsalary1;
Console.WriteLine(totalsalary);
return totalsalary;
}

Labour.cs
namespace Inheritance
{
class Labour:Employee
{
private string p1;
private double p2;
private double p3;

public Labour(string p1, double p2, double p3)
{
Console.WriteLine("Labour");
// TODO: Complete member initialization
this.p1 = p1;
this.p2 = p2;
this.p3 = p3;
}
public double getTotalSalary()
{
double laboursalary= p2*p3;
Console.WriteLine(laboursalary);
return laboursalary;
}
}
}
}
}
The exception is thrown at  above specified code. How I can solve this problem, this Exception?
Manager.cs
namespace Inheritance
{
  class Manager:Employee
  {
  private string p1;
  private double p2;
  private double p3;
  private double p4;

  public Manager(string p1, double p2, double p3, double p4)
  {
  Console.WriteLine("Manager");
  // TODO: Complete member initialization
  this.p1 = p1;
  this.p2 = p2;
  this.p3 = p3;
  this.p4 = p4;
  getTotalSalary();
  }

  public double getTotalSalary()
  {
  double managersalary = p2 + 30% p3 + p4;
  Console.WriteLine(managersalary);
  return managersalary;
  }
  }
}
SalesManager.cs
namespace Inheritance
{
  class SalesManager:Manager
  {
  private string p1;
  private double p2;
  private double p3;
  private double p4;
  private double p5;

  public SalesManager(string p1, double p2, double p3, double p4, double p5):base("PQR", 10000, 5000, 1000)
  {
  Console.WriteLine("salesmanager");
  // TODO: Complete member initialization
  this.p1 = p1;
  this.p2 = p2;
  this.p3 = p3;
  this.p4 = p4;
  this.p5 = p5;
  getTotalSalary();
  }
 
  public new double getTotalSalary()
    {
      double smsalary= p2 + 50% p3 + p4;
  Console.WriteLine(smsalary);
  return smsalary;
    }
  }
}
VicePresident.cs
namespace Inheritance
{
  class VicePresident:Employee
  {
  private string p1;
  private double p2;
  private double p3;
  private double p4;

  public VicePresident(string p1, double p2, double p3, double p4)
  {
  Console.WriteLine("VP");
  // TODO: Complete member initialization
  this.p1 = p1;
  this.p2 = p2;
  this.p3 = p3;
  this.p4 = p4;
  getTotalSalary();
  }
 
  public double getTotalSalary()
    {
  double vpsalary= p2 + 50 % p3 + p4;

  Console.WriteLine(vpsalary);
  return vpsalary;

  }
  }
}


Answers (2)
1
Vulpes

Vulpes

NA 98.3k 1.5m 10y
Well, I was right that the classes do form an inheritance hierarchy and you'll therefore need to fix the previous problem otherwise you'll get a stack overflow exception when you create Manager, VicePresident and SalesManager objects as well.

Another thing I notice is that you've got a lot of repetition here with each class having its own set of fields rather than inheriting fields from its base class. In fact you're  not really inheriting anything at all! 

If you make the fields protected rather than private, then they'll be accessible from the derived classes and you'll only then need to define new fields in the derived class.

Also, when a class hierarchy shares a method (getTotalSalary here) with each class providing its own implementation, it's usual to declare the method as 'virtual' in the base class and then 'override' in the derived classes. You don't then need to hide the base class method each time (using the 'new' keyword) and can automatically call the correct version of the method even if your derived class objects are assigned to a base class variable.


Accepted
1
Vulpes

Vulpes

NA 98.3k 1.5m 10y
When you create an Employee object, its Labour field 'l' is initialized to a new Labour object.

The Labour constructor therefore runs. However, before it does so, it first calls the base class's parameterless constructor. 

As the base class is Employee, this causes 'l' to be initialized again to a new (and independent) Labour object.

So the Labour constructor runs again, the Employee constructor again gets called and the whole process repeats until eventually the stack overflows and the application terminates with an exception.

Although you haven't posted the code for the Manager, VicePresident and SalesManager classes, I imagine they'll form some sort of inheritance hierarchy and, if they ever got the chance, initializing the fields: 'm', 'vp' and 'sm' would all cause the stack to overflow for similar reasons.

You should be able to see that what I've said above is in fact happening by commenting out some lines from the Employee class:

class Employee
{
      static double totalsalary,laboursalary1,managersalary1,vpsalary1;
      //Labour l = new Labour("ABC", 9, 100);// <---------------------------Exception thrown here as stackoverflowexception
      //Manager m = new Manager("PQR", 10000, 5000, 1000);
      //VicePresident vp = new VicePresident("XYZ", 20000, 10000, 5000);
      //SalesManager sm = new SalesManager("KLM", 8000, 2000, 500, 50);
      public Employee()
      {
         //laboursalary1 = l.getTotalSalary();
         //managersalary1 = m.getTotalSalary();
         //vpsalary1 = vp.getTotalSalary();
      }
      public static double calculateTotalSalary(Labour l, Manager m, VicePresident vp, SalesManager sm)
      {
          totalsalary = laboursalary1 + managersalary1 + vpsalary1;
          Console.WriteLine(totalsalary);
          return totalsalary;
      }
}

I'd expect that the application will then run and print "Employee" to the console.

So what you don't want here is to have fields of a derived class type being defined within its base class.

You'll therefore need to rethink the design of your Employee class to get the program to work properly.