gpt4 book ai didi

c# - IEnumerator 是否有 "HasNext"方法?

转载 作者:可可西里 更新时间:2023-11-01 08:50:18 24 4
gpt4 key购买 nike

对于 Java Iterator,我使用了 hasNext 方法来确定迭代是否有更多元素(不消耗元素)——因此,hasNext 类似于“Peek”方法。

我的问题:C# 的通用 IEnumerator 是否有类似“hasNext”或“Peek”的方法?

最佳答案

不,但在 C# 中,您可以重复请求当前元素而不移动到下一个元素。这只是一种不同的看待方式。

编写 C# 类以采用 .NET 风格的 IEnumerator 并返回 Java 风格的 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();
}
}

关于c# - IEnumerator 是否有 "HasNext"方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1273001/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com