Я думаю, что вы слишком усложняете вещи и в итоге создадите слишком много классов.
Я бы посмотрел на проблему как на менее сложную, а не на то, как вы представляете хороший интерфейс для вызывающего абонента .net. То, что существует множество возможных аргументов, не означает, что вам нужно создавать для них множество классов, по крайней мере, если возможные вариации внутри каждого аргумента не очень сложные, т.е. если значение либо есть, либо его нет, и имеет дополнительные единицы. Затем вы попадаете в эту неразбериху, когда вам необходимо знать, в каком порядке должны располагаться части команды и т. Д.
Вероятно, я бы создал класс для возможных аргументов команды, позволил бы вызывающей стороне установить те, которые им нравятся, и поручил бы этому классу генерировать строку в одной большой (уродливой?) Конкатенации строк.
Например, я бы начал с чего-то подобного, а по ходу дела я бы добавил методы, в которых имеет смысл реорганизовать небольшую часть конкатенации строк в зависимости от схожести различных частей команды.
class CommandArgs
{
private double? _Position_x = null;
private double? _Position_y = null;
private String _Position_units = null;
private double? _Width = null;
private String _Width_units = null;
private double? _Height = null;
private String _Height_units = null;
// maybe there's a better tuple-like type for this.
public double[] Position
{
set
{
if (value.length != 2) throw new ArgumentException("argh!");
_Position_x = value[0];
_Position_y = value[1];
}
}
public string Position_Units
{
set
{
_Position_Units = value;
}
}
public double Width
set
{
_Width = value;
}
}
public double Height
set
{
_Height = value;
}
}
public string Width_Units
set
{
_Width = value;
}
}
public string Height_Units
set
{
_Height = value;
}
}
// ....
public override string ToString()
{
return
( _Position_x != null ? string.Format(" Position ({0},{1})",_Position_x, _Position_y ) : "" )
+ ( _Height != null ? string.Format(" Height {0}")
+ ( _Height_Units != null ? string.Format(" Units {0}", _Height_Units) : "" )
+ ( _Width != null ? string.Format(" Width {0}")
+ ( _Width_Units != null ? string.Format(" Units {0}", _Width_Units) : "" )
// ...
;
}
}
Если вы предпочитаете, вы можете создавать методы вместо свойств, чтобы вы могли установить значение и единицы измерения одновременно.
Я бы, вероятно, сразу же произвел рефакторинг, используя следующие методы:
private string FormatUnits(string units)
{
return units == null ? "" : string.Format(" Units {0}", units);
}
private string FormatSingleValueArgument(string argName, object argValue, string units)
{
if (argValue == null) return "";
return string.Format(" {0} {1}", argName, argValue) + FormatUnits(units);
}
делает ToString () похожим на это:
return
( _Position_x != null ? string.Format(" Position ({0},{1})",_Position_x, _Position_y ) : "" )
+ FormatSingleValueArgument("Height", _Height, _Height_Units)
+ FormatSingleValueArgument("Width", _Width, _Width_Units)
// ...
;
тогда, возможно, сделайте аналогичный метод для аргументов, подобных позициям, если их несколько.