如何解决实现集合的简单方法?
| 我正在开发一个收集类,该类应实现IEnumerator和IEnumerable。 在我的第一种方法中,我直接实现了它们。现在,我发现了yield关键字,并且可以使用只读属性Values(用yield循环返回IEnumerable)代替IEnumerator / IEnumerable接口,从而简化了很多事情。 我的问题:是否可以通过使用yield来迭代类本身而无需实现IEnumerable / IEnumerator? 即,我想具有类似于框架集合的功能:List<int> myList = new List<int>();
foreach (int i in myList)
{
...
}
这有可能吗?
更新:看来我的问题措辞不好。我不介意实现IEnumerator或IEnumerable;我只是认为唯一的方法是使用旧的Current / MoveNext / Reset方法。
解决方法
您不必实现
IEnumerable<T>
或IEnumerable
就能使foreach
正常工作,但这是一个好主意。这很容易做到:
public class Foo : IEnumerable<Bar>
{
public IEnumerator<Bar> GetEnumerator()
{
// Use yield return here,or
// just return Values.GetEnumerator()
}
// Explicit interface implementation for non-generic
// interface; delegates to generic implementation.
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
不实现IEnumerable<T>
的替代方法只是调用Values
属性,但仍提供GetEnumerator()
方法:
public class Foo
{
public IEnumerator<Bar> GetEnumerator()
{
// Use yield return here,or
// just return Values.GetEnumerator()
}
]
尽管这行得通,但是这意味着您将无法将您的集合传递给期望值为1的任何东西,例如LINQ to Objects。
鲜为人知的事实是,foreach
可以与支持GetEnumerator()
方法的任何类型一起使用,该方法返回具有适当MoveNext()
和Current
成员的类型。这确实是为了在泛型之前允许使用强类型的集合,在这种情况下,对集合进行迭代将不会对值类型进行装箱等操作。IMO现在真的不需要它了。
,您可以做这样的事情,但是为什么呢? IEnumerator
已经很简单了。
Interface MyEnumerator<T>
{
public T GetNext();
}
public static class MyEnumeratorExtender
{
public static void MyForeach<T>(this MyEnumerator<T> enumerator,Action<T> action)
{
T item = enumerator.GetNext();
while (item != null)
{
action.Invoke(item);
item = enumerator.GetNext();
}
}
}
我宁愿使用in
关键字,也不想重写linq。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。