移动到对象内部自定义IEnumerable中的下一项
本文关键字:一项 对象 内部 自定义 IEnumerable 移动 | 更新日期: 2023-09-27 18:10:37
我有一个自定义对象继承自IEnumerable
。我需要一个方法在这个类中,它将导航到列表中的下一个项目,并相应地循环回到开始。
public class Enrolments : IEnumerable<IEnrolment>
{
public IEnrolment GetNextEnrolment()
{
}
}
我需要以下测试是有效的
IEnrolment enrolment1 = new Enrolment();
IEnrolment enrolment2 = new Enrolment();
Enrolments enrolments = new Enrolments {enrolment1, enrolment2};
IEnrolment current;
Assert.That(current, Is.EqualTo(enrolment1));
current = enrolments.GetNextEnrolment();
Assert.That(current, Is.EqualTo(enrolment2));
current = enrolments.GetNextEnrolment();
Assert.That(current, Is.EqualTo(enrolment1));
current = enrolments.GetNextEnrolment();
Assert.That(current, Is.EqualTo(enrolment2));
如果您有一个列表或其他索引集合作为私有字段,那么要实现此方法,您所需要的只是存储一个表示当前(或下一个)索引的整数。这样,该方法的实现就非常简单,只需对索引进行递增,按集合长度对其进行修改(以获得所需的包装行为),然后返回该索引处的项:
public class Enrolments : IEnumerable<IEnrolment>
{
private List<IEnrolment> list = new List<IEnrolment>();
private int currentIndex;
public IEnrolment GetNextEnrolment()
{
currentIndex = (currentIndex + 1) % list.Count;
return list[currentIndex];
}
//TODO implementations of Add and GetEnumerator
}
请注意,与其拥有自己的GetNextEnrolment
方法,不如拥有一个永远运行,重复迭代自身的IEnumerable<IEnrolment>
方法,而不是这一个自定义方法。您可以使用一个通用方法来永远重复任何序列,而不是对它进行特殊的大小写:
public static IEnumerable<T> Repeat<T>(IEnumerable<T> sequence)
{
while (true)
{
foreach (var item in sequence)
yield return item;
}
}
使用它,因为你的序列已经实现了IEnumerable<IEnrolment>
,你可以这样做:
Enrollments enrollments = new Enrollments(enrollment1, enrollment2);
IEnumerable<IEnrolment> repeatingSequence = Repeat(enrollments);
这里的优点是,您可以在重复序列上使用foreach
(尽管在某些情况下,如果您这样做,除非您打算永远使用break
),对其使用LINQ操作,或者依赖基于IEnumerable<T>
的其他通用帮助器方法
听起来您想使用IEnumerator接口。
IEnrollment enrollment1 = new Enrollment();
IEnrollment enrollment2 = new Enrollment();
Enrollments enrollments = new Enrollments(enrollment1, enrollment2);
IEnumerator<IEnrollment> enumerator = enrollment.GetEnumerator();
enumerator.MoveNext();
Assert.That(enumerator.Current, Is.EqualTo(enrollment1));
enumerator.MoveNext();
Assert.That(enumerator.Current, Is.EqualTo(enrollment2));
enumerator.Reset(); // Move back to the beginning of the list
enumerator.MoveNext();
Assert.That(enumerator.Current, Is.EqualTo(enrollment1));
enumerator.MoveNext();
Assert.That(enumerator.Current, Is.EqualTo(enrollment2));
您可以使用yield
点击此链接查看描述