ある"HasNext"法IEnumerator?
-
13-09-2019 - |
質問
Java Iterator
s使用しているの hasNext
方法かどうかを判定するために繰り返し処理がさらに要素を持っていなかの要素)--このように、 hasNext
のような"Peek
"方法です。
私の質問:があるように"hasNext
"または"Peek
"法C#'s汎用 IEnumerator
s?
解決
いいえ、残念なことに、あまり大きい分けるどれがいいですか?
の IEnumerator<T>
インタのみ公開は以下のメンバー:
方法:
Dispose
MoveNext
Reset
特性:
Current
他のヒント
はありませんが、C#で使用すると、繰り返し次のいずれかに移動することなく、現在の要素を求めることができます。それは見てのちょうど別の方法です。
これはのあまりに.NETスタイルのIEnumerator
を取るためにC#クラスを作成し、JavaスタイルのIterator
を返すようにのハードではないでしょう。個人的に私は、ほとんどの場合に使用する簡単な.NETのスタイルを見つけることが、私たちはそこに行く:)
EDIT:さて、これは完全にテストされていないが、私は<全角> のそれが動作すると思います。それは、少なくともコンパイルん:)
using System;
using System.Collections;
using System.Collections.Generic;
// // Mimics Java's Iterable<T> interface
public interface IIterable<T>
{
IIterator<T> Iterator();
}
// Mimics Java's Iterator interface - but
// implements IDisposable for the sake of
// parity with IEnumerator.
public interface IIterator<T> : IDisposable
{
bool HasNext { get; }
T Next();
void Remove();
}
public sealed class EnumerableAdapter<T> : IIterable<T>
{
private readonly IEnumerable<T> enumerable;
public EnumerableAdapter(IEnumerable<T> enumerable)
{
this.enumerable = enumerable;
}
public IIterator<T> Iterator()
{
return new EnumeratorAdapter<T>(enumerable.GetEnumerator());
}
}
public sealed class EnumeratorAdapter<T> : IIterator<T>
{
private readonly IEnumerator<T> enumerator;
private bool fetchedNext = false;
private bool nextAvailable = false;
private T next;
public EnumeratorAdapter(IEnumerator<T> enumerator)
{
this.enumerator = enumerator;
}
public bool HasNext
{
get
{
CheckNext();
return nextAvailable;
}
}
public T Next()
{
CheckNext();
if (!nextAvailable)
{
throw new InvalidOperationException();
}
fetchedNext = false; // We've consumed this now
return next;
}
void CheckNext()
{
if (!fetchedNext)
{
nextAvailable = enumerator.MoveNext();
if (nextAvailable)
{
next = enumerator.Current;
}
fetchedNext = true;
}
}
public void Remove()
{
throw new NotSupportedException();
}
public void Dispose()
{
enumerator.Dispose();
}
}
public sealed class IterableAdapter<T> : IEnumerable<T>
{
private readonly IIterable<T> iterable;
public IterableAdapter(IIterable<T> iterable)
{
this.iterable = iterable;
}
public IEnumerator<T> GetEnumerator()
{
return new IteratorAdapter<T>(iterable.Iterator());
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public sealed class IteratorAdapter<T> : IEnumerator<T>
{
private readonly IIterator<T> iterator;
private bool gotCurrent = false;
private T current;
public IteratorAdapter(IIterator<T> iterator)
{
this.iterator = iterator;
}
public T Current
{
get
{
if (!gotCurrent)
{
throw new InvalidOperationException();
}
return current;
}
}
object IEnumerator.Current
{
get { return Current; }
}
public bool MoveNext()
{
gotCurrent = iterator.HasNext;
if (gotCurrent)
{
current = iterator.Next();
}
return gotCurrent;
}
public void Reset()
{
throw new NotSupportedException();
}
public void Dispose()
{
iterator.Dispose();
}
}
hasNextはほとんど意味がないので、
列挙子は、多くの場合、遅延評価されます。
いやに、ちょうどMoveNext
、Reset
とCurrent
ます。
また、この実装かいま見を見てみた試してみてくださいIEnumeratorとのIEnumerator <> をします。それはのIEnumeratorにかいま見機能を追加する拡張メソッドです。それが役に立てば幸い。 :)
所属していません StackOverflow