Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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# 是列表<&燃气轮机;按顺序位于类堆数组中的元素?_C#_.net - Fatal编程技术网

C# 是列表<&燃气轮机;按顺序位于类堆数组中的元素?

C# 是列表<&燃气轮机;按顺序位于类堆数组中的元素?,c#,.net,C#,.net,我正在学习C#,基本上知道数组和列表的区别,最后一个是泛型的,可以动态增长,但我想知道: List元素是按顺序位于堆状数组中,还是每个元素“随机”位于不同的位置 如果这是真的,那么这会影响访问和从内存中检索数据的速度吗 如果这是真的,这就是为什么数组比Lists快一点的原因吗 让我们先看看第二个和第三个问题: 如果这是真的,那会影响访问和从内存中检索数据的速度吗 如果这是真的,这就是为什么数组比列表快一点的原因吗 在.NET中只有一个类型的“原生”集合(用.net表示CLR,所以运行时):数组

我正在学习C#,基本上知道数组和列表的区别,最后一个是泛型的,可以动态增长,但我想知道:

  • List
    元素是按顺序位于堆状数组中,还是每个元素“随机”位于不同的位置
  • 如果这是真的,那么这会影响访问和从内存中检索数据的速度吗
  • 如果这是真的,这就是为什么数组比
    List
    s快一点的原因吗

让我们先看看第二个和第三个问题:

如果这是真的,那会影响访问和从内存中检索数据的速度吗

如果这是真的,这就是为什么数组比列表快一点的原因吗

在.NET中只有一个类型的“原生”集合(用.net表示CLR,所以运行时):数组(技术上,如果考虑“代码>字符串/代码>集合类型,那么有两个本机类型的集合:-))(技术上的第2部分:不是所有数组都是“本地”的数组。数组…只有基于0的一维数组是“本机”数组。

T[,]
类型的数组不是,第一个元素的索引不为0的数组不是)。每个其他集合(除了
链接列表
)都构建在其上。如果您使用
IlSpy
查看
列表
,您将看到在列表的底部有一个
T[]
,并为
计数添加了
int
T[].Length
容量
)。显然,数组比
列表快一点,因为使用它可以减少一个间接寻址(直接访问数组,而不是访问访问列表的数组)

让我们看看第一个问题:

是按顺序列出位于堆状数组中的元素,还是每个元素随机位于不同的位置

显然,
列表内部基于一个数组,它像数组一样存储其元素,因此是在一个连续的内存块中(但是请注意,对于
列表
,其中
SomeObject
是引用类型,列表是引用的列表,而不是对象的列表,因此引用被放在一个连续的内存块中(对于计算机的高级内存管理,我们将忽略“连续内存块”一词)“不准确”,最好说“一个连续的地址块”))

(是的,甚至
Dictionary
HashSet
都是在数组上构建的。相反,可以不使用数组而构建树状集合,因为它更类似于
LinkedList

其他一些细节:CIL语言(编译的.NET程序中使用的中间语言)中有四组指令与“本机”数组一起使用:

  • Newarr

  • Ldelem
    和系列
    Ldelem

  • Stelem
    和系列
    Stelem.*

  • 只读
    (不要问我它的用途,我不知道,文档也不清楚)

如果查看
OpCodes.Newarr
,您将在XML文档中看到以下注释:

// Summary:
//     Pushes an object reference to a new zero-based, one-dimensional array whose
//     elements are of a specific type onto the evaluation stack.

是的,列表中的元素是连续存储的,就像数组一样。列表实际上在内部使用数组,但这是一个实现细节,您不应该真正关心

当然,为了从该语句中获得正确的印象,您还必须了解.NET中的内存管理,即这些类型的对象是如何存储的。值类型将存储在连续内存中。对于引用类型,引用将存储在连续内存中,而不是实例本身

使用列表的优点是,类内部的逻辑可以为您分配和管理项。您可以在任何位置添加元素,从任何位置删除元素,并在不做任何额外工作的情况下扩展集合的整个大小。当然,这也是列表比数组稍慢的原因。如果有的话为了满足您的请求,必须进行定位,当分配一个新的、更大的数组并将元素复制到该数组中时,性能会受到影响。但不会比使用原始数组手动编写代码慢多少

如果您的长度要求是固定的(即,您永远不需要增加/扩展阵列的总容量),您可以继续使用原始阵列。它甚至可能比列表快一点,因为它避免了额外的开销和间接寻址(尽管这需要通过JIT编译器进行优化)


如果您需要能够动态调整集合大小,或者需要List类提供的任何其他功能,只需使用List。性能差异几乎是不可察觉的。

可能与int、bool等值类型的列表重复?我的意思是,整数数组也是引用数组吗?我很抱歉不太确定。@MatíasFidemraizer No,
int[]
是对内存块的引用,其中所有的
int
s都在内存块中(加上一些其他辅助的东西…但最后它有点不透明)。如果使用
不安全的
code,
已修复(int*addr=&(arr[0])
将为您提供第一个int的地址,
addr+1
(其中addr+1是指针上类似于C的数学运算)将是下一个元素的地址,就像在C中一样。(显然,对于所有值类型,
bool
int
DateTime
,以及一般的
struct
s:)谢谢,我明白了。“引用将存储在连续内存中”这意味着当数组由100个元素组成时,我在数组中有100个引用