gpt4 book ai didi

C# IEnumerable、IEnumerator 重置函数未被调用

转载 作者:太空狗 更新时间:2023-10-29 19:53:09 26 4
gpt4 key购买 nike

我基本上是在尝试让我的类能够使用 foreach 进行迭代。我读了这个教程。 MSDN .看起来很直接。但是,当我想第二次迭代时,我遇到了问题。我调试了它;事实证明它没有调用 Reset() 函数。

A类

class A : IEnumerable, IEnumerator
{
int[] data = { 0, 1, 2, 3, 4 };

int position = -1;

public object Current
{
get
{
return data[position];
}
}

public bool MoveNext()
{
position++;
return (position < data.Length);
}

public void Reset()
{
position = -1;
}

public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
}

当我运行以下主要功能时;它从不调用 Reset() 函数。因此,在一个循环之后,我再也无法迭代我的类了。

主要内容

static void Main(string[] args)
{
A a = new A();

foreach (var item in a)
{
Console.WriteLine(item);
}

Console.WriteLine("--- First foreach finished. ---");

foreach (var item in a)
{
Console.WriteLine(item);
}
}

输出:

0
1
2
3
4
--- First foreach finished. ---
Press any key to continue . . .

有什么想法吗?

最佳答案

每次foreach被调用,它要求一个新的 IEnumerator .返回你的类实例是个坏主意 - 你应该创建一个单独的类来实现 IEnumerator ,并返回它。

这通常是通过使用嵌套(私有(private))类并返回它的一个实例来完成的。您可以将 A 类实例传递给私有(private)类(使其可以访问 data ),然后将 position该类中的字段。它将允许同时创建多个枚举器,并将与后续的 foreach 调用一起正常工作。

例如,要修改您的代码,您需要执行以下操作:

using System;
using System.Collections;

class A : IEnumerable
{
int[] data = { 0, 1, 2, 3, 4 };

public IEnumerator GetEnumerator()
{
return new AEnumerator(this);
}

private class AEnumerator : IEnumerator
{
public AEnumerator(A inst)
{
this.instance = inst;
}

private A instance;
private int position = -1;

public object Current
{
get
{
return instance.data[position];
}
}

public bool MoveNext()
{
position++;
return (position < instance.data.Length);
}

public void Reset()
{
position = -1;
}

}
}

请注意,您也可以直接返回数组的枚举器(尽管我假设您正在尝试学习如何制作干净的枚举器):

class A : IEnumerable
{
int[] data = { 0, 1, 2, 3, 4 };

public IEnumerator GetEnumerator()
{
return data.GetEnumerator();
}
}

最后,你可以使用iterators以更简单的方式实现这一点:

class A : IEnumerable
{
int[] data = { 0, 1, 2, 3, 4 };

public IEnumerator GetEnumerator()
{
for (int i=0;i<data.Length;++i)
yield return data[i];
}
}

话虽如此,我强烈建议实现 IEnumerable<int>除了IEnumerable。泛型使这在使用方面变得更好。

关于C# IEnumerable、IEnumerator 重置函数未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11475328/

26 4 0