Код: Выделить всё
public static IEnumerable Range(double startingValue, double step, int count)
{
// I would really like this validation to be performed before returning the iterator
if (count < 0) throw new ArgumentOutOfRangeException("count must be >= 0");
double currentValue = startingValue;
for (int i = 0; i < count; i++)
{
yield return currentValue;
currentValue += step;
}
}
Это означает, что код может завершиться неудачей гораздо позже, чем вызов создания итератора.
Возможно, если диапазон передается в качестве аргумента другой функции. Очень намного позже.
Код: Выделить всё
[TestMethod]
[TestCategory(nameof(TestCategoryEnum.UnitTest))]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestCreateRangeNegativeCount_01()
{
var range = Range(1.0, 1.0, -100);
// Should never reach here
Assert.Fail(); // Uh-uh. Absolutely reaches here...
foreach (var obs in range)
{
Assert.Fail();
}
}
Однако это очень похоже на хакерский обходной путь.
EDIT: Я не уточнил, почему это показалось «хакерским», когда я задавал вопрос. Тогда это было просто ощущение, но теперь я думаю, что могу объяснить, почему;
Обертывание и развертывание обычно используются для абстракции и формирования интерфейса - гораздо более распространенная и совершенно другая задача. В этой задаче весь смысл в том, что это не должно влиять на то, как на самом деле работает код.
Однако здесь это фактически меняет то, как работает код. А поскольку код выглядит так же, как и в более распространенном случае, не сразу понятно, почему его нельзя просто «развернуть» и переместить цикл доходности обратно в вызывающий метод.
Если бы существовала языковая конструкция или атрибут, который мог бы отделить проверку от цикла урожайности отличным от оболочки способом, это устранило бы двусмысленность.
@Theodor Zoulias опубликовал совершенно другой ответ, что я не думаю, что кто-то будет реорганизовать его, не разобравшись сначала. Сначала я принял другой ответ, но я действительно считаю, что ответ @Theodor Zoulias лучше.
/EDIT
Есть ли (лучший) способ заставить метод Range проверять свои аргументы перед возвратом итератора?
Я полностью ожидаю, что с этим уже сталкивались и на него отвечали раньше, но, к сожалению, я не смог найти его при поиске.
Подробнее здесь: https://stackoverflow.com/questions/798 ... up-and-ret
Мобильная версия