gpt4 book ai didi

c# - Queue 上的 IEnumerable 迭代器是否应该使项目出列

转载 作者:可可西里 更新时间:2023-11-01 03:13:01 28 4
gpt4 key购买 nike

我创建了一个实现通用 IQueue 接口(interface)的自定义通用队列,该接口(interface)使用 System.Collections.Generic 命名空间中的通用队列作为私有(private)内部队列。示例已清除不相关的代码。

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();
...
}
}

我想让事情与核心实现保持一致,并且注意到核心 Queue 实现了 IEnumerable,因此我将通过在类上显式实现 IEnumerable 或使用 IQueue 接口(interface)继承它来做同样的事情。

我想知道的是,在对队列进行枚举时,每个移动的下一步是否应该使下一个项目出列?我已经使用反射器来了解 Microsoft 是如何做到的,他们所做的只是遍历队列私有(private)数组,但 Microsoft 远非万无一失,所以我想得到一个普遍的意见。

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();
}

...
}

我有两种想法,一方面我觉得遍历集合不应该改变集合状态,但另一方面,特别是对于我的特定实现,它会使用法看起来很干净。

编辑

把事情放在上下文中。我正在实现的类在出队时执行 Monitor.Wait 并且队列中没有项目。当一个项目被放入队列时,就会有一个 Monitor.Pulse。这允许一个线程将内容推送到队列中,而另一个线程基本上“监视”队列。

从编码的角度来看,我试图决定哪个看起来更干净:

foreach(QueueItem item in queue)
{
DoSomethingWithThe(item);
}

//Or

while(systemIsRunning)
{
DoSomethingWithThe(queue.Dequeue());
}

对于我的特定实现,是否有多个进程出列项目无关紧要。因为它是一个队列,所以他们都可以选择一个项目,因为任何项目都不应被处理超过一次,因此使用队列。

编辑

有趣的是,我发现了一篇博文,其中有人正是这样做的。

Link

编辑

在我关闭它之前最后一次尝试。人们如何看待这个类没有实现 IEnumerable 但有一个 IEnumerator GetEnumerator() 方法来使项目出队? .net 语言支持鸭子类型,foreach 是其中一种用途。也许这值得它自己的问题?

编辑

提出了实现 GetEnumerator 方法而不在另一个中实现 IEnumerable 的问题 question .

最佳答案

迭代器应该始终是幂等的,也就是说,在迭代队列时不要修改它。

不能保证不会有两个并发迭代...


编辑以处理您的新评论:

当另一个程序员(比如你 future 的自己 ;) )过来为代码添加功能时,他们可能不会假设迭代器是一次性的。他们可能会添加一个日志语句,在使用它之前列出队列中的内容(哎呀)。

我刚刚想到的另一件事是,visual studio 调试器会经常枚举您的类以供显示。那会导致一些极其困惑的错误 :)

如果您正在实现 IEnumerable 的子接口(interface),并且不想支持 IEnumerable,则应该抛出 NotSupportedException。虽然这不会给您任何编译时警告,但运行时错误将非常明显,而奇怪的 IEnumerable 实现可能会浪费您以后的时间。

关于c# - Queue 上的 IEnumerable 迭代器是否应该使项目出列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4189581/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com