Reputation: 2636
Using C#.NET4.5 and Visual Studio 2012 Ultimate.
Im currently trying out absract classes with my Label Printing program, Ive Used Interfaces before.
I used Interfaces to De-Couple my two classes, it works great.
Now Im trying out the following.
1st. My Abstract Class...
abstract class Label
{
public virtual IList<Microsoft.Reporting.WinForms.ReportParameter> NewReportSetup(string part, string batch, string locn, string wheel, string gear, string length,
string fits, string newbar, string newbarnum, string abs)
{
IList<Microsoft.Reporting.WinForms.ReportParameter> parameters = new List<Microsoft.Reporting.WinForms.ReportParameter>();
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramPart", part));
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramBatch", batch));
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramLocn", locn));
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramWheel", wheel));
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramGear", gear));
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramLength", length));
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramABS", abs));
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramBuyer", fits));
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramBarCode", newbar));
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramBartxt", newbarnum));
return parameters;
}
}
2nd. My ReportShaft Inherits Label...
class ReportShaft : Label
{
public virtual IList<Microsoft.Reporting.WinForms.ReportParameter> NewReportSetup()
{
return new List<Microsoft.Reporting.WinForms.ReportParameter>();
}
}
3rd. My Form Instantiates the ReportShaft Class and calls the NewReportSetup()...
private void NewReportSetupSHAFT()
{
if(txtABS.Text.ToString() == "" || txtABS.Text == null)
{
txtABS.Text = "N/A";
}
IList<Microsoft.Reporting.WinForms.ReportParameter> param = new List<Microsoft.Reporting.WinForms.ReportParameter>();
param = reportshaft.NewReportSetup(txtNewPart.Text.ToString(),
txtBatch.Text.ToString(), txtLocation.Text.ToString(), txtWheel.Text.ToString(), txtGear.Text.ToString(), txtLength.Text.ToString(),
txtFits.Text.ToString(), txtNewBar.Text.ToString(), txtNewBarNum.Text.ToString(), txtABS.Text.ToString());
reportViewer1.LocalReport.SetParameters(param);
}
This works fine(although I sense I'm using Abstract classes in the wrong way, not sure).
My Question is:
I want to Create a new Report Class. I want the Class to call the very Same method but alow me to Change the Top 2 Parameter names, and skip the last one out completly.
Now would this require an overide to the method? if so how would one do this? Will the Label method need changing from a Virtual Function?
Many Thanks Guys!
UPDATE:: Ok may seem to be some confusion when i mentioned parameters.
I meant to say i wish to Call 1 method from my abstract class, then in my report class that inherits this label class and method, i wish to change the "report paramaters" I mean the body of the method.
The reason for this is because if I simply make another method and call that for each different report i will be using methods almost identical.
Heres example:: change this..
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramPart", part));
Too this ..
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramchanged!!", part));
this is one example. So from what I gather i override my label class method in my report class. But then im stuck, if i try to change the body i must type out the rest of code that goes with it. to me im still gona end up with a bunch of methods that look identical.
Is there anyway to change "partial part of the methods body" without having to type out the rest.
Hope this clears confusion.
Upvotes: 0
Views: 8618
Reputation: 67065
I am not sure that what you are doing is the best approach. I would refactor the code so that the NewReportSetup
takes an object. Then, you could have the object have properties that you access, and if they are not set, then you dont use them. You can then create a builder class.
NewReportSetup(ReportProperties propertiesObject)
{
...
}
public class ReportProperties
{
public String Part{get;set;}
...
}
Then, you can create your child classes that use/format the given ReportProperties
object as specified by the implementation
Otherwise, a more direct answer is Micah's, which also works. The difference is one of Composition over Inheritance. Inheritance has its place, but should not be overused when composition is the better approach
For your update
Here is what it sounds like you can do for your update (however, the ReportProperties
object will still work...you can have it contain all of your metadata also)
Your abstract class:
public virtual void NewReportSetup(params)
{
...
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramBatch", batch));
...
FinalizeParameters(parameters, paramsThatAreImplSpecific);
}
protected abstract void FinalizeParameters(List, paramsThatAreImplSpecific);
Your concrete implementation:
protected override void FinalizeParameters(List, paramsThatAreImplSpecific)
{
parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramPart or paramChanged", part));
}
Now, you could make FinalizeParameters
have a root implementation that you override, but you want to be careful of breaking Liskov's Substitution Principle. It really does seem to me that you should use a ReportProperties
object with the appropriate metadata, whether through a dictionary or some other mechanism. But, I would say forcing the final param adds via an abstract method is your best option if you dont want to go any other way.
Upvotes: 2
Reputation: 6971
You want to overload the method in the base class not override.
Override changes functionallty where overloading changes the signature. you can do this like this
class ReportShaft : Label
{
public virtual IList<Microsoft.Reporting.WinForms.ReportParameter> NewReportSetup()
{
base.NewReportSetup("part", "batch", "locn", "wheel","gear", "length", "fits", "newbar", "newbarnum", null)
}
}
This is helpful if you use alot of the same parms or have a default param that you call alot. Also note that I am calling base which will call the base classes method instead of the method in the class I am working in
Upvotes: 1