我想使用 C# 迭代自定义集合的值。
我创建了一个名为
MyLinkedList
的集合来表示这样的自定义链表
public class MyLinkedList<T> : IEnumerable<T?> where T : IEquatable<T?>
{
// other methods are removed for simplicity.
IEnumerator<T?> IEnumerable<T?>.GetEnumerator()
=> new MyLinkedListNodeEnumerator<T>(_root);
public IEnumerator GetEnumerator()
=> new MyLinkedListNodeEnumerator<T>(_root);
}
我实现了
IEnumerable<T?>
接口,因此我可以使用 foreach
循环来迭代自定义集合中的值。这是MyLinkedListNodeEnumerator
的实现
public class MyLinkedListNodeEnumerator<T>(MyLinkedListNode<T>? root)
: IEnumerator<T?> where T : IEquatable<T?>
{
private readonly MyLinkedListNode<T>? _root = root;
private MyLinkedListNode<T>? _current = root;
public object? Current
{
get
{
var current = _current;
_current = _current!.Next;
return current;
}
}
T? IEnumerator<T?>.Current
{
get
{
var current = _current;
_current = _current!.Next;
return current!.Data;
}
}
public void Dispose()
{
}
public bool MoveNext()
=> _current?.Next != null;
public void Reset()
{
_current = _root;
}
}
这是一个用例示例,
var list = new MyLinkedList<int>();
list.InsertFirst(10);
list.InsertNext(20);
list.InsertNext(30);
当我循环枚举器对象时,我期望每个项目都是
int
类型,因为这是创建列表的通用类型。所以 foreach
使用的是 IEnumerator GetEnumerator()
而不是 IEnumerable<T?>.GetEnumerator()
。
foreach(var item in list)
{
// here item is an object of a type MyLinkedListNode<int>
// not int as I am expecting.
}
如何确保
foreach
将使用 IEnumerable<T?>.GetEnumerator()
,以便我可以迭代 int
值?
不知道您的具体情况
MyLinkedListNode
:
public class MyLinkedListNodeEnumerator<T>()
: IEnumerator<T> where T : IEquatable<T>
{
private MyLinkedListNode<T> _root;
private MyLinkedListNode<T> _current = null;
public MyLinkedListNodeEnumerator(MyLinkedListNode<T> root)
=> _root = root;
T Current
=> _current.Data;
object IEnumerator.Current
=> _current.Data;
public bool MoveNext()
{
_current = (_current ?? _root).Next;
return _current is not null;
}
public void Reset()
=> _current = null;
public void Dispose()
{ }
}
请注意,
Current
是幂等的,不应修改枚举器。向前移动枚举器的唯一方法是使用 MoveNext
。在初始状态下,枚举器应该在第一个元素之前开始,这就是为什么 _current
从 null
开始。此外,未定义在先前未成功调用 Current
的情况下访问 MoveNext
。