Вы, конечно, можете создавать разные итераторы для обхода разными способами. Например, вы могли бы иметь:
public class Tree<T>
{
public IEnumerable<T> IterateDepthFirst()
{
// Iterate, using yield return
...
}
public IEnumerable<T> IterateBreadthFirst()
{
// Iterate, using yield return
...
}
}
Это то, о чем вы спрашивали?
Вы можете также потенциально написать:
public class Foo : IEnumerable<int>, IEnumerable<string>
но это вызовет много путаницы, и цикл foreach
выберет тот, у кого был явно не реализованный вызов GetEnumerator
.
Вы можете также повторять несколько раз для одной и той же коллекции одновременно:
foreach (Person person1 in party)
{
foreach (Person person2 in party)
{
if (person1 != person2)
{
person1.SayHello(person2);
}
}
}