Поскольку вы не можете точно знать, какие параметры понадобятся конкретному типу экспорта, у вас есть несколько вариантов:
- Используйте словарь (как вы предложили): расширяемый, но без безопасности типов
- Использовать базовый класс для интерфейса : безопасность типов по-прежнему отсутствует, поскольку вам необходимо приводить внутри каждого конкретного метода экспорта.
- Сделать параметры специфичными для реализации и скрытыми от вызывающей стороны : предпочтительнее IMHO.
Если вы скрываете конкретную реализацию вашего экспорта в вызываемую полиморфизм, то не следует ожидать, что они узнают о ваших внутренних параметрах.
Я бы упростил ваш интерфейс экспорта до:
interface IExport
{
void Export(); // or Export(string filename), alternatively
}
И затем создание каждого конкретного класса так, как вам нужно:
// no params
IExport txt = new TextExport();
// single string (delimiter)
IExport csv = new DelimitedExport(",");
// lots of params
IExport excel = new ExcelExport(someStronglyTypedOptions);
Таким образом, ваш вызывающий код не должен беспокоиться о передаче этих параметров.
[Изменить]
В заключение: без других очевидных преимуществ вы можете тривиально решить проблему с типом параметра, переписав это:
var csv = new ExcelExport();
csv.Export(parameters);
на это:
var csv = new ExcelExport(parameters);
csv.Export();
В какой-то момент, кто-то должен знать, какие параметры создавать и как это сделать. Это означает, что все остальные могут принять экземпляр IExport
с этого момента, и ему будет разрешено только вызов простого метода без параметров.
Тогда ваша конкретная реализация будет иметь разные конструкторы и, как правило, будет следовать этой схеме:
class ExcelExport : IExport
{
private readonly ExcelParams _params;
public ExcelExport(ExcelParams parameters)
{
_params = parameters;
}
public void Export()
{
// do stuff
}
}