Как я могу заставить блоки итераторов проверять параметры перед упаковкой и возвратом в качестве продолжения?C#

Место общения программистов C#
Ответить
Anonymous
 Как я могу заставить блоки итераторов проверять параметры перед упаковкой и возвратом в качестве продолжения?

Сообщение Anonymous »

Ситуация: метод, который проверяет свои аргументы и возвращает итератор;

Код: Выделить всё

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();
}
}
Мое текущее решение — обернуть блок итератора в еще один метод под «Range» и вместо этого вернуть that.
Однако это очень похоже на хакерский обходной путь.
EDIT: Я не уточнил, почему это показалось «хакерским», когда я задавал вопрос. Тогда это было просто ощущение, но теперь я думаю, что могу объяснить, почему;
Обертывание и развертывание обычно используются для абстракции и формирования интерфейса - гораздо более распространенная и совершенно другая задача. В этой задаче весь смысл в том, что это не должно влиять на то, как на самом деле работает код.
Однако здесь это фактически меняет то, как работает код. А поскольку код выглядит так же, как и в более распространенном случае, не сразу понятно, почему его нельзя просто «развернуть» и переместить цикл доходности обратно в вызывающий метод.
Если бы существовала языковая конструкция или атрибут, который мог бы отделить проверку от цикла урожайности отличным от оболочки способом, это устранило бы двусмысленность.
@Theodor Zoulias опубликовал совершенно другой ответ, что я не думаю, что кто-то будет реорганизовать его, не разобравшись сначала. Сначала я принял другой ответ, но я действительно считаю, что ответ @Theodor Zoulias лучше.
/EDIT
Есть ли (лучший) способ заставить метод Range проверять свои аргументы перед возвратом итератора?
Я полностью ожидаю, что с этим уже сталкивались и на него отвечали раньше, но, к сожалению, я не смог найти его при поиске.

Подробнее здесь: https://stackoverflow.com/questions/798 ... up-and-ret
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»