Hi All,
I am relatively new to C# and am trying to create an application but not sure of the best approach. I would rather get it right first time.
I am creating an app that will create one of a number of reports and was trying to use a main Report class and derive the individual reports from this. Here is my design.
Firstly I created an Abstract class as I wanted the derived class (the main report class) to use all of the defined methods. Also I didn't want the class instantiated.
public abstract class Report
{
public abstract void Open();
public abstract void InsertData();
public abstract void Close();
}
I then created the main report class from this.
public class TemplateReport: Report
public class TemplateReport: Report
{
public override void Open()
{
//Common code goes here.
}
public override void InsertData()
{
}
public override void Close()
{
//Common code goes here.
}
}
}
The open and close code will be the same for all reports so common code will be in these members.
Now I derive the individual reports.
class MyReport: TemplateReport
{
public override void Open()
{
base.Open();
}
public override void InsertData()
{
//Report specific code goes here.
}
public override void Close()
{
base.Close();
}
}
So now in the main body of the app I can put:
TemplateReport ReportContainer = new TemplateReport();
switch (Program.mainProgramArgs[0])
{
case "/M":
ReportContainer = new MyReport();
break;
case "/C":
ReportContainer = new MyReport2();
break;
}
ReportContainer.Open();
ReportContainer.InsertData();
ReportContainer.Close();
However I have a couple of questions.
1. If I comment out a function from the TemplateReport class, I get a compiler error saying that I must implement it, which is what I want. However when I do the same thing to the MyReport class, the compiler allows me to do this. I would like the enforment that applies to the TemplateReport class to filter down to the MyReport class. How do I do this?
2. I don't want the TemplateReport class to be instantiated but I do want the other classes to derive from it. The only way I can see is to make it an Abstract class, but this does not allow code in the member bodies. Any way to do this?
3. In the last piece of code where I have ReportContainer.Open(), can I add another method call e.g. ReportContainer.OpenFile("c:\Test.txt") where the member is defined in the TemplateReport class as an abstract so that I am forced to use it in the main application body?
4. Is this the best design to achieve the goal of having a Common container class to store the individual reports?
Basically I want to have a strict interface so that if I add another report, the compiler will warn if no calls are implemented applying all the way down to the main app body.
I hope this makes sense.
Any help would be appreciated.
Andy
VulpesPosted Nov 8, 2011, 9:28 AM
2. It's possible to include virtual methods (which can have a body) in an abstract class though you could also prevent instantiation by making the constructor protected rather than public. You can't make it private because the derived class constructors will need to call it implicitly or explicitly.
3. Yes, you can overload the OpenFile method.
4. Your basic design looks sound to me though I think you will have to accept that the compiler won't be able to warn you if you fail to override the 3 methods in each derived class - it will simply look up the inheritance chain for the last concrete implementation.
Sam HobbsPosted Nov 8, 2011, 1:21 PM
VulpesPosted Nov 8, 2011, 10:50 AM
C# CornerPosted Nov 8, 2011, 10:44 AM
public override void OpenReport()
{
base.Open(ORIGINAL_REPORT)
}
If the concrete rules were passed down, I would have had to include the Open method member as well and pass a string, although it would not be used.
VulpesPosted Nov 8, 2011, 10:25 AM
C# CornerPosted Nov 8, 2011, 9:52 AM
Thanks for the 2nd opinion on the design. I feel a bit more confident now.