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

时间:2013-04-23 15:34:10

标签: c# linq inheritance

我有一个继承自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));

3 个答案:

答案 0 :(得分:0)

听起来您想要使用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));

答案 1 :(得分:0)

您可以使用此

的收益率

检查this链接以获取说明

答案 2 :(得分:0)

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

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>

的其他通用助手方法