私はPythonの世界から来て、C#で "generator"メソッドを作成しようとしています。私は、特定のバッファサイズのチャンクでファイルを解析しており、一度に1つずつ次のチャンクを読み込んで保存し、それをループの中でforeach
ループに収めたいだけです。ここで私はこれまでのところ(概念実証を簡素化)しているものです:C# "Generator"メソッド
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?
}
}
}
}
それは(私はこれらのプロパティの多くは公に設定することができますが、ためていない最低限の実施例であるので、私は、これは完璧ではない知っていますこれを単純にしておくと、プライベートメンバーやプロパティを入力する必要はありません)。
しかし、私の主な質問どのように私は、ループするための項目が残っていることをforeachステートメントで知っているMyClassを介してループすることができますか?要素が残っていないことを示すためにスローする例外はありますか?
Pythonの場合と同じように、アイテムの降伏を単に止めるだけです。つまり、IEnumerableを返すメソッドを作成する必要があります。列挙可能なものは簡単に消費できます。 –
poke
'IEnumerator .MoveNext'は、呼び出し元に反復処理を停止するよう指示するものです。これは 'yield return'を使うときに実装されます。明示的に停止したい場合は、 'yield break'を使うことができます。 –
@この例では矛盾は私のせいです。ページはこの投稿のために作られたもので、BTreePageは本当に私が実際のコードで返すものです。一定。 – Dan