c# - 枚举一个 IDictionary.Keys 集合,它是一个 ICollection<T>

标签 c# .net enumeration

我希望我不会因为提出如此基本的问题而受到抨击。我可以通过 Google 搜索答案,但我想听听教科书中没有的内容。

我正在编写一个单元测试来验证我的 IDictionary键是连续的。

Keys属性是 ICollection<T> ,我想枚举集合并将键值打印到控制台。

尝试使用简单的 for 打印键值时循环:

for (int i = 0; i < unPivotedData.Count; i++)
{
    Console.WriteLine(unPivotedData.Keys[i]);
}

我收到以下编译错误:

Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.ICollection<int>'

但是,当我使用 foreach循环:

foreach(int key in unPivotedData.Keys)
{
    Console.WriteLine(key);
}

一切正常。

我了解索引器的作用及其实现方式,但 foreach 是如何实现的工作?我不明白 foreach可以工作了 for导致编译器错误。

我是否缺少枚举的基础知识?

干杯!

编辑: 此外,两者之间是否存在性能差异?我知道我不能使用 for使用 IDictionary 但如果我使用 IList,我可以。 forforeach 移动得更快还是性能提升可以忽略不计

最佳答案

foreach 只需要 IEnumerable;而 for(a,b,c) (在您的情况下)需要一个索引器属性。

当您在实现了 IEnumerable 的对象上调用 foreach 时,它会在后台调用 GetEnumerator(),它会返回一个 IEnumerator。目的。该对象实现了一些成员,例如 MoveNext()Currentforeach 的每次迭代实际上都在调用 MoveNext(),如果枚举器可以向前移动,则返回 true,如果不能,则返回 false (到达终点)。

这里的关键是实现IEnumerable 的对象不知道它有多少项,它所在的项的索引等。它所知道的只是它可以前进到下一个项目,将其作为当前项目返回,直到用完所有项目。

for(a,b,c) 循环,另一方面,本质上将永远循环 - 也就是说,它不受您可能碰巧迭代的集合的约束(尽管在实践中通常是)。在最基本的层面上,它每次执行一次C,并检查B是否为真。如果 B 为真,它将再次循环。如果它是假的,它将停止。每次循环时,在循环中您可能正在调用 object[number],如果您的对象没有这样的属性,这当然会失败。

这里的关键是带有索引器的对象支持随机访问 - 这意味着您可以在任何时候调用[arbitrary index] 并获取那个对象。将此与 IEnumerable 进行对比,后者同样只能访问当前 项。

关于c# - 枚举一个 IDictionary.Keys 集合,它是一个 ICollection<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1455901/

相关文章:

arrays - 为什么在 Optional Array 上的映射不同于 non-optionalArray

c# - .NET 3.5 没有 enum.tryparse,那么如何安全地将字符串解析为枚举?

c# - 在 C# 中捕获 Plink 输出

c# - 在 MVC4 分部 View 中使用 PagedList 时的不良行为

c# - 如何解析XML?

c# - 代码中添加<>是什么意思?

sql - 每天使用另一个表中的值更新 sql 表

python - 在 Python 中使用枚举迭代到 len(list) - 1

c# - 高级自定义多语言 URL 处理/角色和成员资格 LoginUrl

C# 列表和内存