Я родом из мира Python и пытаюсь создать «генераторный» метод в C#. Я разбираю файл в кусках определенного размера буфера и хочу только читать и хранить следующий фрагмент за один раз и давать его в цикле . Вот то, что я до сих пор (упрощенное доказательство концепции):C# «Генератор» Метод
class Page
{
public uint StartOffset { get; set; }
private uint currentOffset = 0;
public Page(MyClass c, uint pageNumber)
{
uint StartOffset = pageNumber * c.myPageSize;
if (StartOffset < c.myLength)
currentOffset = StartOffset;
else
throw new ArgumentOutOfRangeException("Page offset exceeds end of file");
while (currentOffset < c.myLength && currentOffset < (StartOffset + c.myPageSize))
// read data from page and populate members (not shown for MWE purposes)
. . .
}
}
class MyClass
{
public uint myLength { get; set; }
public uint myPageSize { get; set; }
public IEnumerator<Page> GetEnumerator()
{
for (uint i = 1; i < this.myLength; i++)
{
// start count at 1 to skip first page
Page p = new Page(this, i);
try
{
yield return p;
}
catch (ArgumentOutOfRangeException)
{
// end of available pages, how to signal calling foreach loop?
}
}
}
}
Я знаю, что это не является совершенным, так как это рабочий пример минимального (не позволяют многим из этих свойств необходимо установить публично, но для сохраняя это просто, я не хочу вводить частные члены и свойства).
Однако, мой главный вопрос: как я могу позволить вызывающему абоненту обходить MyClass с помощью инструкции foreach, знать, что больше нет элементов, оставшихся до цикла? Есть ли исключение, которое я указываю, что элементов нет?
Вы просто прекратите сдавать предметы, как в Python.При этом вы должны сделать метод, который возвращает 'IEnumerable'; перечисления легче потреблять. –
poke
'IEnumerator .MoveNext' - это то, что говорит вызывающему абоненту прекратить итерацию. Это выполняется для вас, когда вы используете 'yield return'. Если вы хотите явно остановиться, вы можете использовать 'yield break'. –
@poke несоответствие - это моя ошибка в примере. Страница - это сделанная вещь для этого поста, BTreePage - это действительно то, что я возвращаю в своем реальном коде. Исправлена. – Dan