.NET: bool против enum как параметр метода
Каждый раз, когда я пишу метод, который принимает логический параметр, представляющий опцию, я думал: "Должен ли я заменить это на перечисление, которое значительно облегчит чтение вызовов метода?".
Рассмотрим следующее с объектом, который принимает параметр, указывающий, должна ли реализация использовать свою потокобезопасную версию или нет (я не спрашиваю здесь, является ли этот способ хорошим проектом или нет, только использование логического значения):
public void CreateSomeObject(bool makeThreadSafe);
CreateSomeObject(true);
Когда вызов находится рядом с объявлением, назначение параметра кажется очевидным. Когда он находится в какой-то сторонней библиотеке, которую вы едва знаете, сразу же увидеть, что делает код, труднее, чем:
public enum CreationOptions { None, MakeThreadSafe }
public void CreateSomeObject(CreationOptions options);
CreateSomeObject(CreationOptions.MakeThreadSafe);
который описывает намерение гораздо лучше.
Ситуация ухудшается, когда есть два логических параметра, представляющих параметры. Посмотрите, что случилось с ObjectContext.SaveChanges(bool)
между Framework 3.5 и 4.0. Он устарел, потому что был введен второй вариант, и все это было преобразовано в перечисление.
Хотя кажется очевидным использование перечисления при наличии трех или более элементов, каково ваше мнение и опыт использования перечисления вместо логического значения в этих конкретных случаях?
5 ответов
.NET 4.0 может помочь здесь. Вы можете использовать именованные параметры:
CreateSomeObject(makeThreadSafe : true);
Для более старых версий может быть полезно создать временные переменные.
bool makeThreadSafe = true;
CreateSomeObject(makeThreadSafe);
Я думаю, что это будет зависеть от семантики ваших методов, например, действительно ли ваше логическое значение представляет собой логическое значение? Или он используется только для обозначения присутствия, а не присутствия другой вещи?
Например:
// If true, uses 64 bit numbers, if false, 32.
doSomething(boolean)
Даже если вы знаете (что по крайней мере в обозримом будущем это не изменится (если вы не хотите поддерживать 16 или даже 8 бит), было бы намного легче читать, если бы вы использовали перечисление:
Options.Use32Bit,
Options.Use64Bit.
Для меня это зависит от нескольких вещей:
- читабельность
- Количество булевых параметров, переданных методу
- Вероятность того, что мне может понадобиться больше, чем просто правда / ложь
1) Что является более читабельным?
CreateSomeObject(CreationOptions.MakeThreadSafe);
CreateSomeObject(true);
2) Как насчет сейчас?
CreateSomeObject(CreationOptions.MakeThreadSafe, ExtraGoodies.Include, Logging.Disable);
CreateSomeObject(true, false, false);
3) Мне может понадобиться что-то более расширяемое, как истина / ложь / неопределенный. Если я напишу это так с самого начала, то не будет никаких серьезных изменений, если я просто добавлю дополнительный элемент в мое перечисление.
Вы можете использовать именованные параметры в C# 4.0:
CreateSomeObject(makeThreadSafe : true);
Очевидно, что второй подход более читабелен без IDE. Если вы в VS, вы можете использовать intellisense для поиска параметров, хотя по общему признанию это иногда может быть немного неуклюжим.
Если вы находитесь в C# 4.0, вы можете использовать именованные параметры, чтобы прояснить свое намерение.