.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. читабельность
  2. Количество булевых параметров, переданных методу
  3. Вероятность того, что мне может понадобиться больше, чем просто правда / ложь

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, вы можете использовать именованные параметры, чтобы прояснить свое намерение.

Другие вопросы по тегам