我正在创建一个原型应用程序,为此我设计了一个行为类似于无限循环列表的类。也就是说,如果我的内部列表包含100个值,当我要求第101个值时,我得到第一个,第102个得到第二个,依此类推,重复。
所以我想写下面的代码:
public class InfiniteLoopingList : IEnumerable<double>
{
double[] _values = File.ReadLines(@"c:\file.txt")
.Select(s => double.Parse(s, CultureInfo.InvariantCulture))
.ToArray();
int _size;
public InfiniteLoopingList()
{
_size = _values.Length;
}
public double this[int i]
{
get { return _values[i % _size]; }
set { _values[i % _size] = value; }
}
public IEnumerator<double> GetEnumerator()
{
return this.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
// ???? now what ?? :(
}
}
为此我需要实现IEnumerable,因为我理解。
这是我目前的代码:
SessionLocaleResolver
答案 0 :(得分:3)
由于您实现了索引器属性,因此可以通过以下最简单的方式执行此操作:
public IEnumerator<double> GetEnumerator()
{
int i = 0;
while (true)
yield return this[i++];
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
修改强>
请注意,这不是无限循环。这种方法只能在i = int.MaxValue
之前使用。感谢@oleksii。
答案 1 :(得分:2)
你不需要这个班......
扩展方法可以解决这个问题:
public static class InfEx
{
public static IEnumerable<T> LoopForever<T>(this IEnumerable<T> src)
{
var data = new List<T>();
foreach(var item in src)
{
data.Add(item);
yield return item;
}
for(;;)
{
foreach(var item in data)
{
yield return item;
}
}
}
}
现在你可以采用一个序列并使其成为一个循环的无限序列:
IEnumerable<Foo> mySeq = ...;
IEnumerable<Foo> infMySeq = mySeq.LoopForver();
IEnumerable<Foo> aSelectionOfInfMySeq = infMySeq.Skip(101).Take(5);
答案 2 :(得分:0)
您可以实现IEnumerator接口:
class InifniteEnumerator<T> : IEnumerator<T> {
private int index = -1;
private IList<T> innerList;
private int repeatPos;
public InifniteEnumerator(IList<T> innerList, int repeatPos) {
this.innerList = innerList;
this.repeatPos = repeatPos;
}
public T Current {
get {
if (index == -1) {
throw new InvalidOperationException();
}
return this.innerList[index];
}
}
object IEnumerator.Current {
get {
return this.Current;
}
}
public void Dispose() {
}
public bool MoveNext() {
this.index++;
if (this.index == repeatPos) {
this.index = 0;
}
return true;
}
public void Reset() {
this.index = -1;
}
}
然后在GetEnumerator方法中返回它的一个实例:
IEnumerator IEnumerable.GetEnumerator() {
return this.GetEnumerator();
}
public IEnumerator<T> IEnumerable<T>.GetEnumerator() {
return new InifniteEnumerator(this, 100);
}