c# - Should an IEnumerable iterator on a Queue dequeue an item -


i have created custom generic queue implements generic iqueue interface, uses generic queue system.collections.generic namespace private inner queue. example has been cleaned of irrelevant code.

public interface iqueue<tqueueitem> {     void enqueue(tqueueitem queueitem);     tqueueitem dequeue(); }  public class customqueue<tqueueitem> : iqueue<tqueueitem> {     private readonly queue<tqueueitem> queue = new queue<tqueueitem>();     ...     public void enqueue(tqueueitem queueitem)     {         ...         queue.enqueue( queueitem );         ...     }      public tqueueitem dequeue()     {         ...         return queue.dequeue();         ...     } } 

i want keep things consistent core implementations , have noticed core queue implements ienumerable same either explicitly implementing ienumerable on class or inheriting iqueue interface.

what want know when enumerating on queue should each move next dequeue next item? have used reflector see how microsoft has done , step through queues private array microsoft far infallible wanted general opinion.

public class customqueue<tqueueitem> : iqueue<tqueueitem>, ienumerable<tqueueitem> {     ...      public ienumerator<tqueueitem> getenumerator()     {         while (queue.count > 0)         {             yield return dequeue();         }     }      //or      public ienumerator<tqueueitem> getenumerator()     {         return queue.getenumerator();     }      ... } 

i in 2 minds, on 1 hand feel iterating through collection should not changed collections state on other hand , particular implementation make usage clean.

edit

to put things context. class implementing monitor.wait when dequeuing , there no items in queue. when item put onto queue there monitor.pulse. allows 1 thread push stuff onto queue , other "watch" queue.

from coding point of view trying decide looks cleaner:

foreach(queueitem item in queue) {     dosomethingwiththe(item); }  //or  while(systemisrunning) {     dosomethingwiththe(queue.dequeue()); } 

for particular implementation wouldn't matter if there multiple process dequeuing items. because queue can both pick of item no item should processed more once, hence use of queue.

edit

interestingly enough have found blog post has done this.

http://blogs.msdn.com/b/toub/archive/2006/04/12/blocking-queues.aspx

edit

one last stab @ before close off. how people feel class not implement ienumerable having ienumerator getenumerator() method dequeues items? .net language supports duck typing, foreach being 1 of uses. perhaps deserves it's own question?

edit

have raised question of implementing getenumerator method without implementing ienumerable in question.

iterators should idempotent, is, don't modify queue iterate on it.

there no guarantees there won't 2 concurrent iterations...


edit address new comments:

when programmer (such future self ;) ) comes along add features code, may not assume iterators single-use. might add log statement lists what's in queue before using (oops).

another thing thought of visual studio debugger enumerate classes display. cause extremely confusing bugs :)

if you're implementing sub-interface of ienumerable, , don't want support ienumerable, should throw notsupportedexception. although not give compile time warnings, run time error clear, while strange ienumerable implementation waste future hours.


Comments

Popular posts from this blog

android - Spacing between the stars of a rating bar? -

html - Instapaper-like algorithm -

c# - How to execute a particular part of code asynchronously in a class -