English 中文(简体)
Are Multiple Iterators possible in c=C#?
原标题:

Are multiple iterators (for a single class or object) possible in C# .NET? If they are, give me some simple 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.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签