davioooh
davioooh

Reputation: 24676

Best way to handle parameters in inherited classes

I have a base class ExportType and several inherited classes that implement the specific data exportation.

The inherited classes need several parameters to define the way the data are exported from the database. These parameters can be different from a class to another.

So I thought to use a Dictionary<string, string> to handle the export parameters and in my base class I put a method like this:

public abstract void Export (Dictionary<string, string> exportParams);

Is this the best way to do it, or there are better ways to handle different parameters?

Upvotes: 3

Views: 1147

Answers (2)

vgru
vgru

Reputation: 51224

Since you cannot know for sure what parameters will a specific export type need, you have several options:

  1. Use a dictionary (like you proposed): extensible, but no type safety
  2. Use an base class for the interface: still no type safety, since you need to cast inside every specific export method.
  3. Make parameters implementation-specific and hidden from the caller: preferred IMHO.

If you are hiding the concrete implementation of your export to your called through polymorphism, then you shouldn't expect them to know about your internal parameters.

I would simplify your export interface to:

interface IExport 
{
    void Export(); // or Export(string filename), alternatively
}

And then instantiating each concrete class the way you need:

// no params
IExport txt = new TextExport();

// single string (delimiter)
IExport csv = new DelimitedExport(",");

// lots of params
IExport excel = new ExcelExport(someStronglyTypedOptions);

This way your calling code doesn't need to bother with passing those parameters around.

[Edit]

To conclude: with no other apparent benefit, you can trivially solve the problem of the parameter type by rewriting this:

var csv = new ExcelExport();
csv.Export(parameters);

to this:

var csv = new ExcelExport(parameters);
csv.Export();

At one point, someone needs to know which parameters to instantiate and how to do it. This means that everyone else can accept an IExport instance from that point on, and be allowed nothing more than calling a plain parameterless method.

You concrete implementation will then have different constructors, and generally will follow this pattern:

class ExcelExport : IExport
{
    private readonly ExcelParams _params;
    public ExcelExport(ExcelParams parameters)
    {
        _params = parameters;
    }

    public void Export() 
    {
        // do stuff
    }
}

Upvotes: 4

George Duckett
George Duckett

Reputation: 32428

Depending on how it's called, you might be able to make the base class generic, taking in a type of a parameters class you create.

public abstract class BaseClass<TExportParams>
{
    public abstract void Export(TExportParams exportParams);
}

public class Derived : BaseClass<DerivedExportParamsClass>
{
    public void Export(DerivedExportParamsClass exportParams)
    {

    }
}

If you don't know the parameters type to pass to Export when you want to call it, then go with @Groo's answer.

Upvotes: 2

Related Questions