移动到对象内部自定义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));

移动到对象内部自定义IEnumerable中的下一项

如果您有一个列表或其他索引集合作为私有字段,那么要实现此方法,您所需要的只是存储一个表示当前(或下一个)索引的整数。这样,该方法的实现就非常简单,只需对索引进行递增,按集合长度对其进行修改(以获得所需的包装行为),然后返回该索引处的项:

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

点击此链接查看描述