Я занимаюсь разработкой библиотеки, предназначенной для публичного выпуска. Он содержит различные методы для работы с наборами объектов - генерация, проверка, разбиение и проецирование наборов в новые формы. Если это уместно, это библиотека классов C # с включенными расширениями в стиле LINQ IEnumerable
, которая будет выпущена в виде пакета NuGet.
Некоторые из методов в этой библиотеке могут иметь неудовлетворительные входные параметры. Например, в комбинаторных методах есть метод для генерации всех наборов из n элементов, которые могут быть созданы из исходного набора из m элементов. Например, с учетом набора:
1, 2, 3, 4, 5
и запрос комбинаций 2 даст:
1, 2
1, 3
1, 4 и
т. Д.
5, 3
5, 4
Теперь, очевидно, можно попросить что-то, что не может быть сделано, например, дать ему набор из 3 предметов, а затем попросить комбинации из 4 предметов при установке опции, которая говорит, что он может использовать каждый предмет только один раз.
В этом сценарии каждый параметр действителен в отдельности :
- Исходная коллекция не равна нулю и содержит элементы
- Запрашиваемый размер комбинаций является положительным ненулевым целым числом
- Запрашиваемый режим (используйте каждый элемент только один раз) является правильным выбором
Однако состояние параметров в совокупности вызывает проблемы.
В этом сценарии вы ожидаете, что метод сгенерирует исключение (например InvalidOperationException
) или возвратит пустую коллекцию? Либо мне кажется действительным:
- Вы не можете создать комбинации из n элементов из набора из m элементов, где n> m, если вам разрешено использовать каждый элемент только один раз, поэтому эту операцию можно считать невозможной
InvalidOperationException
. - Набор комбинаций размером n, которые могут быть получены из m элементов, когда n> m является пустым набором; никакие комбинации не могут быть произведены.
Аргумент для пустого набора
Моя первая проблема заключается в том, что исключение предотвращает идиоматическое объединение методов в стиле LINQ, когда вы имеете дело с наборами данных, которые могут иметь неизвестный размер. Другими словами, вы можете сделать что-то вроде этого:
var result = someInputSet
.CombinationsOf(4, CombinationsGenerationMode.Distinct)
.Select(combo => /* do some operation to a combination */)
.ToList();
Если ваш входной набор имеет переменный размер, поведение этого кода непредсказуемо. Если .CombinationsOf()
выдается исключение, если в someInputSet
нем менее 4 элементов, этот код иногда завершится с ошибкой во время выполнения без предварительной проверки. В приведенном выше примере эта проверка тривиальна, но если вы вызываете ее на полпути по длинной цепочке LINQ, это может быть утомительно. Если он вернет пустой набор, то result
он будет пустым, что может вас порадовать.
Аргумент для исключения
Мое второе беспокойство заключается в том, что возвращение пустого набора может скрыть проблемы - если вы вызываете этот метод на полпути вниз по цепочке LINQ и он спокойно возвращает пустой набор, то вы можете столкнуться с проблемами через несколько шагов или оказаться с пустым набор результатов, и может не быть очевидным, как это произошло, учитывая, что у вас определенно было что-то во входном наборе.
Чего бы вы ожидали, и каков ваш аргумент для этого?