Я реализую DelegateCommand
, и когда я собирался реализовать конструктор (ы), я предложил следующие два варианта дизайна:
1: Наличие нескольких перегруженных конструкторов
public DelegateCommand(Action<T> execute) : this(execute, null) { }
public DelegateCommand(Action<T> execute, Func<T, bool> canExecute)
{
this.execute = execute;
this.canExecute = canExecute;
}
2: Наличие только одного конструктора с необязательным параметром
public DelegateCommand(Action<T> execute, Func<T, bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute;
}
Я не знаю, какой из них использовать, потому что я не знаю, какие возможные преимущества / недостатки связаны с любым из двух предложенных способов. И то, и другое можно назвать так:
var command = new DelegateCommand(this.myExecute);
var command2 = new DelegateCommand(this.myExecute, this.myCanExecute);
Может кто-нибудь указать мне правильное направление и дать отзыв?
c#
class-design
parameters
constructors
Томас Флинков
источник
источник
Bitmap.FromFile
) также вариантОтветы:
Я предпочитаю несколько конструкторов значениям по умолчанию, и лично мне не нравятся ваши два примера конструктора, они должны быть реализованы по-разному.
Причина использования нескольких конструкторов заключается в том, что основной может просто проверить, все ли параметры не равны NULL и являются ли они действительными, тогда как другие конструкторы могут предоставить значения по умолчанию для основного.
В ваших примерах, однако, нет никакой разницы между ними, потому что даже вторичный конструктор передает значение
null
по умолчанию, и первичный конструктор также должен знать значение по умолчанию. Я думаю, что это не должно.Это означает, что он будет чище и лучше отделен, если будет реализован следующим образом:
обратите внимание на
_ => true
переданный первичному конструктору, который теперь также проверяет все параметрыnull
и не заботится о любых значениях по умолчанию.Однако наиболее важным моментом является расширяемость. Несколько конструкторов безопаснее, когда есть вероятность, что вы будете расширять свой код в будущем. Если вы добавите больше обязательных параметров, а необязательные должны появиться в конце, вы сломаете все свои текущие реализации. Вы можете создать старый конструктор
[Obsolete]
и проинформировать пользователей о том, что он будет удален, что даст им время для перехода на новую реализацию без мгновенного нарушения кода.С другой стороны, слишком большое количество необязательных параметров может привести к путанице, потому что если некоторые из них требуются в одном сценарии и необязательны в другом, вам нужно будет изучить документацию, а не просто выбирать правильный конструктор, просто просматривая его параметры.
источник
CultureInfo
объекта. Я бы предпочел API, который позволял предоставлятьCultureInfo
параметр через дополнительный параметр, но настаивал на том, что если он был предоставлен, то этого не должно бытьnull
. Таким образом, случайныеnull
значения не интерпретируются как означающие «нет».Obsolete
старый, если вы хотите избежать поломок, независимо от того, есть ли у вас дополнительные параметры или нет. С необязательными параметрами вам нужно только,Obsolete
если вы удалите один.Принимая во внимание единственное, что вы делаете в конструкторе - это простое присваивание, решение с одним конструктором может быть лучшим выбором в вашем случае. Другой конструктор не предоставляет никакой дополнительной функциональности, и из конструктора конструктора с двумя параметрами ясно, что второй аргумент указывать не нужно.
Несколько конструкторов имеют смысл, когда вы создаете объект из разных типов. В этом случае конструкторы являются заменой внешней фабрики, поскольку они обрабатывают входные параметры и форматируют их в правильное представление внутреннего свойства класса, который создается. Однако в вашем случае этого не происходит, поэтому одного конструктора должно быть более чем достаточно.
источник
Я думаю, что есть два разных случая, для которых каждый подход может проявить себя.
Во-первых, когда у нас есть простые конструкторы (что, по моему опыту, обычно так), я бы рассматривал необязательные аргументы, чтобы сиять.
Buuuut, есть случаи, когда необязательные аргументы в конструкторах просто делают вещи более запутанными. Очевидный пример - когда эти необязательные аргументы являются исключительными (т. Е. Не могут использоваться вместе). Перегрузка конструкторов, которые допускают только действительные комбинации аргументов, обеспечит принудительное выполнение этого ограничения во времени компиляции. Тем не менее, вам также следует избегать даже столкновения с этим случаем (например, с несколькими классами, унаследованными от базы, где каждый класс выполняет исключительное поведение).
источник