Is Multiple Iterators is possible in c#?

前端 未结 3 1434
北海茫月
北海茫月 2021-01-15 19:27

Can multiple iterators (for a single class or object) is possible in c#.net? If it is give me some simple examples. Sorry if the question is not understandable and please ma

相关标签:
3条回答
  • 2021-01-15 20:07

    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);
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-15 20:08

    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) {
          ...
        }
      }
    }
    
    0 讨论(0)
  • 2021-01-15 20:09

    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 讨论(0)
提交回复
热议问题