Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我曾读到,迭代哈希集是一种不好的做法。我应该先打电话给.ToList()吗?_C#_List_Enumeration_Hashset - Fatal编程技术网

C# 我曾读到,迭代哈希集是一种不好的做法。我应该先打电话给.ToList()吗?

C# 我曾读到,迭代哈希集是一种不好的做法。我应该先打电话给.ToList()吗?,c#,list,enumeration,hashset,C#,List,Enumeration,Hashset,我有一个名为RegisteredItems的项目集合。我不关心RegisteredItems中项目的顺序,只关心它们是否存在 我对RegisteredItems执行两种类型的操作: 按属性查找并返回项 迭代集合并产生副作用 根据:罗伯特·R.说 “迭代哈希集有点危险,因为这样做 对集合中的项目施加顺序。该顺序实际上不是 属性。您不应该依赖它。如果 集合中的项目对您很重要,该集合不是 设置。” 在某些情况下,我的收藏将包含50-100个项目。我意识到这不是一个大量的项目,但我仍然希望收获使用哈

我有一个名为RegisteredItems的项目集合。我不关心RegisteredItems中项目的顺序,只关心它们是否存在

我对RegisteredItems执行两种类型的操作:

  • 按属性查找并返回项
  • 迭代集合并产生副作用
根据:罗伯特·R.说

“迭代哈希集有点危险,因为这样做 对集合中的项目施加顺序。该顺序实际上不是 属性。您不应该依赖它。如果 集合中的项目对您很重要,该集合不是 设置。”

在某些情况下,我的收藏将包含50-100个项目。我意识到这不是一个大量的项目,但我仍然希望收获使用哈希集而不是列表的回报

我发现自己正在查看以下代码,不知道该怎么做:

LayoutManager.Instance.RegisteredItems.ToList().ForEach( item => item.DoStuff() );

vs

foreach( var item in LayoutManager.Instance.RegisteredItems)
{
    item.DoStuff();
}
RegisteredItems用于返回一个
IList
,但现在它返回一个哈希集。我觉得,如果为了提高效率而使用HashSet,将其转换为列表是不合适的。然而,上面引用的罗伯特的话也让我对重复一遍感到不安


在这种情况下,什么是正确的选择?谢谢

如果您不关心顺序,请使用哈希集。这句话是关于当你担心顺序时使用HashSet是危险的。如果您多次运行此代码,并且项目以不同的顺序进行操作,您会介意吗?如果没有,那么你很好。如果是,则不要使用哈希集。首先任意转换为列表并不能真正解决问题

我不确定,但我怀疑.ToList()会迭代HashSet来实现这一点,所以,现在要遍历集合两次


不要过早地优化。如果您只有100项,只需使用HashSet并继续。如果你开始关心顺序,那么把它改成一个列表,然后在任何地方都把它作为一个列表使用。

如果你真的不关心顺序,并且你知道你的hashset中不能有重复项(这是你想要的),那就用hashset吧。

在引用的问题中,我想他是说如果你迭代一个集合,你可以很容易地欺骗自己,让自己认为这些物品是按一定顺序排列的。例如,以不同的方式对待第一个迭代项是很容易的,但是您不能保证它仍然是第一个迭代项


只要你记住这一点,并考虑无序的集合,迭代它就可以了。

我想他只是说如果你在迭代一个集合,你可能会关心迭代的顺序,如果你真的不应该使用一个集合。是否允许在对哈希集进行迭代时从哈希集中删除项?或者这是一次非法行动?只要试着理解散列集的整个排序是如何工作的……那会导致一个异常。从效率上来说,这并不危险,但从你认为它的“行为”来看是什么样的。因此,
HashSet
不是一个
IList
,而是一个
ICollection
。当然,您可以对其进行迭代,但这不能保证订单!但在您的情况下,如果
RegisteredItems
应该是
IList
,则可能需要这样做……我怀疑.ToList()也会这样做。:)我只是认为它可能(必然地)枚举哈希集,这样当我调用item.DoStuff()时,任何副作用都不会影响哈希集的“顺序”,而不会抛出非法的OperationException?嗯,在迭代过程中不能修改任何排序的集合。那太糟糕了。从你最初的问题中不清楚你的担忧是什么。你必须先详细解释副作用,然后才能提出建议。我建议开始一个新的问题,措辞为“我正在迭代一个HashSet,执行一个有FOO副作用的操作,我得到了这个异常。我如何正确地做到这一点?”完全理解这是不好的,但是,作为一个简单的例子。要在列表中对项目进行迭代时删除项目,我使用for循环并将索引设置为列表中的最后一个项目,然后向后遍历列表--在执行时删除项目。这工作非常好,是标准的。但是,我无法按索引访问哈希集。这让我想知道我是否必须将它转换到一个列表中才能拥有这个功能。不过,我现在实际上没有这个必要,我只是在想相反,您应该在通过哈希集时构建一个要删除的项目列表,然后在从哈希集中删除的位置执行第二次“删除列表”迭代。这是标准。我不赞成做反向迭代,因为它只是一种非标准的迭代,使代码维护更困难,降低了其他人的可读性;其他人很可能不同意我的观点。昨天我花了20-30个小时讨论了这两种方法的优点:p他们可能都可以。。我认为对于哈希集来说,您的方式肯定更好——但对于通过索引访问的列表来说,可能会更好。在处理列表时,第二轮查找并非微不足道(与哈希集近乎恒定的查找时间相反)