Frage

Mit Java Iterators ich die hasNext Methode verwendet habe, um zu bestimmen, ob eine Wiederholung mehr Elemente hat (ohne ein Element raubend.) - so hasNext ist wie eine „Peek“ Methode

Meine Frage: Gibt es so etwas wie ein "hasNext" oder "Peek" Methode mit C # 's allgemeinen IEnumerators

?
War es hilfreich?

Lösung

Nein, leider gibt es nicht.

Die IEnumerator<T> Schnittstelle nur macht folgende Elemente:

Methoden:

  

Dispose
   MoveNext
   Reset

Eigenschaften :

  

Current

Andere Tipps

Nein, aber in C # können Sie immer wieder für das aktuelle Element stellen, ohne auf den nächsten zu bewegen. Es ist nur eine andere Art und Weise, es zu betrachten.

Es wäre nicht zu schwer, eine C # Klasse zu schreiben, um einen .NET-Stil IEnumerator zu nehmen und eine Java-Stil Iterator zurückzukehren. Persönlich finde ich die .NET-Stil leichter in den meisten Fällen zu verwenden, aber es gehen wir:)

EDIT: Okay, das ist völlig ungetestet, aber ich denkt es wird funktionieren. Es ist zumindest kompilieren:)

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();
    }
}

Enumeratoren werden oft träge ausgewertet, so hasNext wenig Sinn macht.

Nope , nur MoveNext, Reset und Current.

Sie können auch versuchen, einen Blick auf diese Implementierung Peek mit zu IEnumerator und IEnumerator <> . Es ist eine Erweiterung Methode, die Peek-Funktionalität IEnumerator hinzufügt. Ich hoffe es hilft. :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top