开发者

Are Multiple Iterators possible in c=C#?

开发者 https://www.devze.com 2022-12-11 23:33 出处:网络
Are multiple iterators (for a single class or object) possible in C# .NET? If they are, give me some simpl开发者_JAVA百科e examples.

Are multiple iterators (for a single class or object) possible in C# .NET? If they are, give me some simpl开发者_JAVA百科e examples.

Sorry if the question is not understandable and please make me clear.


You could certainly create different iterators to traverse in different ways. For example, you could have:

public class Tree<T>
{
    public IEnumerable<T> IterateDepthFirst()
    {
        // Iterate, using yield return
        ...
    }

    public IEnumerable<T> IterateBreadthFirst()
    {
        // Iterate, using yield return
        ...
    }
}

Is that the kind of thing you were asking?

You could also potentially write:

public class Foo : IEnumerable<int>, IEnumerable<string>

but that would cause a lot of confusion, and the foreach loop would pick whichever one had the non-explicitly-implemented GetEnumerator call.

You can also iterate multiple times over the same collection at the same time:

foreach (Person person1 in party)
{
    foreach (Person person2 in party)
    {
        if (person1 != person2)
        {
            person1.SayHello(person2);
        }
    }
}


It's not really clear if you mean that you can implement more than one iterator for a class, or if you can use more than one iterater for a class at a time. Either is possible.

You can have as many iterators as you like for a class:

public class OddEvenList<T> : List<T> {

  public IEnumerable<T> GetOddEnumerator() {
    return this.Where((x, i) => i % 2 == 0);
  }

  public IEnumerable<T> GetEvenEnumerator() {
    return this.Where((x, i) => i % 2 == 1);
  }

}

You can have as many instances of an iterator for a class active at the same time as you like:

foreach (int x in list) {
  foreach (int y in list) {
    foreach (int z in list) {
      ...
    }
  }
}


One option would be to implement the Strategy pattern:

  1. Create separate IEnumerator classes for each traversal strategy.
  2. Create a private attribute in the collection that stores the current strategy (with a default).
  3. Create a SetStrategy() method that changes that private attribute to the selected concrete strategy.
  4. Override GetEnumerator() to return an instance of the current strategy.

Of course, this means two threads trying to set the strategy at the same time could interfere, so if sharing the collection between threads is important, this isn't the best solution.

A straight Iterator pattern would also work, which is what I believe Jon Skeet is suggesting in his first example, but you lose the syntactic sugar of being able to use foreach.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号