RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1278286
Accepted
Potion
Potion
Asked:2022-05-05 16:40:08 +0000 UTC2022-05-05 16:40:08 +0000 UTC 2022-05-05 16:40:08 +0000 UTC

集合、数组和泛型之间的单值差异,以及它们的内部结构 C#

  • 772

对收藏感到困惑,我需要简要介绍所有收藏的要点。

数组可以称为集合吗?常识说是的,因为这是元素的集合,但在尖锐的地方有数组,有集合,还有泛型。并不是所有的事情都对他们很清楚。

  1. 我们知道集合是泛型之前的通用元素分组机制的旧版本。这些是 ArrayList、Stack、Queue、Hashtable

您添加的所有内容都保存为object,这会导致装箱和拆箱,如果变量是值类型,例如 int,那么我们复制它 - 结果我们得到两个变量。

问题 - 这仅适用于集合,还是简单数组的工作方式相同?

分配单元格值时,int 数组是否进行装箱和拆箱?我们是在分配数组单元格值时复制 int 值,还是以其他方式工作?

  1. Richter 写道,泛型的优点之一是不需要打包——拆包,因为。泛型是强类型的,不会与对象相互转换,而是以这种方式存储的。

但是它们存储在堆上吗?如果原始类型是值类型,我们还有值复制吗?

  1. 引用类型对所有集合的工作方式是否相同——它们不会被复制,只是将对实例的引用存储在它们的单元格中?数组、集合和泛型的主要区别在处理值类型时是否准确体现?

  2. 是否所有集合和数组都引用类型,它们的所有单元格及其所有内容是否都存储在堆上?

  3. 收藏的底层是什么?ArrayList 或 List 是如何在内部实现的?我读到 Dictionary 在引擎盖下有一个 Hashtable,它只是使用键的哈希值来查找,但是 Hashtable 本身是如何工作的呢?里面有数组吗?

这些问题重叠并且有点令人困惑,因为我将我所知道的关于集合的所有内容都放入其中。貌似我用过,但一切都散了,现在读了里希特,总体上是一头雾水。

如果有关于比较所有集合及其内部实现的简短摘要,我将不胜感激。

c#
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Alexander Petrov
    2022-05-05T20:34:16Z2022-05-05T20:34:16Z

    泛型是一种概括。
    集合可以是通用的或非通用的。

    数组最初具有特殊的地位,事实上,它总是被泛化的。


    您似乎害怕复制值。但这并不可怕,因为习惯上使值类型变小并且复制它们与复制引用类型指针相当。

    既然你读过里希特,你就已经为痛苦和屈辱做好了心理准备……在现代 dotnet 实现中,可以在堆栈上创建引用类型!但这是运行时优化,我们不应该特别担心。


    泛型和非泛型集合之间的区别不仅限于值类型的处理。object使用泛型,在使用引用类型时不需要强制转换(cast) 。也就是说,使用它们更容易、更安全。


    我将给出一个图表,说明重要类型如何存储在类型的数组和泛型集合中List<T>:

    [value1|value2|value3]
    

    这就是它们将如何存储在非通用集合中的方式:

    [ref1|ref2|ref3]
    
    ref1: box(value1)
    
    ref2: box(value2)
    
    ref3: box(value3)
    

    在集合本身 - 链接。并且打包(装箱)的值分散在堆上。


    1. 是否所有集合和数组都引用类型,它们的所有单元格及其所有内容是否都存储在堆上?

    不必要。例如,这里的ImmutableArray Struct - 如您所见,这是一个值类型。里面有什么不重要。

    没有人也没有什么能阻止您创建一个在字段中存储一组值的集合结构。实现索引器、枚举器——集合的所有属性。在这种情况下,不使用堆。

    stackalloc是在堆栈上创建数组的标准方法。


    1. 收藏的底层是什么?

    如果您从哲学意义上广泛地看待这个问题,那么答案是:任何事情!
    可能在堆栈或堆中分配了一块内存,或者可能使用任何协议直接访问文件、数据库或服务。


    您可以在Wikipedia上阅读有关 Hash 表的实现(有一次我被它的内部结构惊呆了,一开始我被它的复杂性所震撼,最后我被它的美丽所吸引)。

    也可以查看那里的其他数据结构。如果您会说英语,请切换到它。

    • 2
  2. pasx
    2022-05-28T21:49:40Z2022-05-28T21:49:40Z

    这是部分答案。

    从技术上讲,数组不是 C# 中的集合,因为它们不是 System.Collections 的一部分。正如您所写,常识使我们通常将数组和集合视为包含值集的数据结构。类似于我们在数学中所说的“集合”。最主要的是数组在打包/解包方面没有问题。

    我们知道,集合构成了许多用于在 C# 中存储数据的结构的基础。这些集合是专门的或扩展的,以提供一些额外的功能——例如,堆栈、队列、字典、哈希表。

    原始的非泛型版本使用对象。对于值类型,它们意味着使用装箱/拆包机制。检查这篇文章:“不应使用非泛型集合” https://github.com/dotnet/platform-compat/blob/master/docs/DE0006.md

    泛型不仅仅是集合的一个特性。它们是 C# 的一个重要特性。对于集合,它们可以在不将其包装为对象的情况下存储值。

    更多信息 - 可能太多了 - 在这里:https ://mihai-albert.com/2020/02/10/boxing-performance-in-c-versus-generics/

    • 0

相关问题

  • 使用嵌套类导出 xml 文件

  • 分层数据模板 [WPF]

  • 如何在 WPF 中为 ListView 手动创建列?

  • 在 2D 空间中,Collider 2D 挂在玩家身上,它对敌人的重量相同,我需要它这样当它们碰撞时,它们不会飞向不同的方向。统一

  • 如何在 c# 中使用 python 神经网络来创建语音合成?

  • 如何知道类中的方法是否属于接口?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5