문제

Java와 함께 Iterators, 나는 그것을 사용했다 hasNext 반복에 요소를 소비하지 않고 더 많은 요소가 있는지 여부를 결정하는 방법. hasNext "Peek" 방법.

내 질문 : A와 같은 것이 있습니까?hasNext" 또는 "Peek"C#의 일반적인 방법 IEnumerator에스?

도움이 되었습니까?

해결책

아니요, 불행히도 없습니다.

그만큼 IEnumerator<T> 인터페이스는 다음 멤버 만 노출합니다.

행동 양식:

Dispose
MoveNext
Reset

속성:

Current

다른 팁

아니요, 그러나 C#에서는 다음 요소로 이동하지 않고 현재 요소를 반복적으로 요청할 수 있습니다. 그것은 그것을 보는 다른 방법 일뿐입니다.

그렇지 않을 것입니다 ~도 .NET 스타일을 사용하기 위해 C# 클래스를 작성하기가 어렵습니다. IEnumerator 그리고 자바 스타일을 반환하십시오 Iterator. 개인적으로 나는 대부분의 경우 .NET 스타일을 사용하기 쉽지만 우리는 간다 :)

편집 : 좋아, 이것은 완전히 테스트되지 않았지만 나는 생각한다 작동합니다. 적어도 컴파일합니다 :)

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에 추가하는 확장 방법입니다. 도움이되기를 바랍니다. :)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top