我是一名有用的助手,可以为您翻译文本。
我有一个简单的队列来管理添加到我的应用程序中的项目。
从微软当前的Queue.Peek方法文档中:
如果使用Peek()仍然会抛出无效操作异常,那么使用Peek()有什么意义?
我认为使用Peek()的整个目的是使代码不生成异常。
我有一个简单的队列来管理添加到我的应用程序中的项目。
从微软当前的Queue.Peek方法文档中:
我认为使用Peek()的整个目的是使代码不生成异常。
即使MSDN也提到了原因:
可以将 null 作为值添加到队列中,要区分 null 值和队列结尾,检查 Count 属性或捕获 InvalidOperationException。当队列为空时引发该异常。
所以,如果你尝试查看第一个元素,队列抛出异常的原因是它可能是null
。那么如何区分有效的null
值和没有项?
如果队列包含像int
这样的值类型,也是同样的问题。如果没有元素可以查看,它应该返回-1吗?不,-1可能是一个有效值,因此你无法知道队列中是否有另一个元素。
相反,请使用Count
属性来检查队列是否为空:
var queue = new Queue<int>();
queue.Enqueue(-1);
while (queue.Count > 0)
{
int current = queue.Peek(); // still in the queue
Console.WriteLine(queue.Dequeue()); // now empty
}
我认为你可能将queue.Peek
和像dataReader.Read
这样的方法混淆了。它们之间的区别在于Read
会将读取器前进到下一条记录,并返回一个指示是否存在记录的bool
。而Queue.Peek
也会返回该“记录”,但其目的不同,因此如果要知道是否有记录,请勿使用Peek
。
顺便说一下,这种行为在框架中是一致的。其他方法如Enumerable.First
在对空序列使用时也会抛出InvalidOperationException
异常。
Peek
的作用是查看队列的下一个元素,而不将其删除。它没有被删除这一点是Peek
和Pop
(在.NET中为Dequeue
)之间的主要区别。(这与.NET无关;对于任何语言的队列结构,如果有一个返回弹出值的Pop
(/Dequeue
),那么这就是这两者之间的区别。Queue
无法返回任何合理的内容。抛出异常是唯一的替代方案,所以这是适当的行为。要么捕获并处理异常,要么(如果您不担心竞态条件)在调用Peek
/Dequeue
之前检查队列是否为空。Dequeue()
,那么它会改变队列,这不是你想要的。Peek()
返回下一个元素,而不会 改变队列。 - SneftelCount
为零时不调用它即可。但根据编程风格,您可能更喜欢捕获异常而不是显式检查计数。 - Sneftel
Peek()
的其他所有东西一样,当没有其他内容时返回-1或null。那么Peek()
有什么意义呢?只需调用Dequeue
并在那里捕获异常即可。 - user153923Peek
要返回-1
呢?它应该返回队列中的第一个项目。Queue<T>
可以存储任何东西,不仅仅是像int
这样的值类型。而且,即使它包含整数,-1
也可能是一个有效的数字,所以你不知道这是第一个/最后一个还是其他。对于null
也是同样的情况。抛出异常是提示您逻辑有问题。您正在请求另一个项目,但没有任何项目可用。使用while(myQueue.Count > 0){ // 在这里可以查看 }
。 - Tim Schmelter