C# 字典内部数组大小

Ser*_*art 5 c# arrays dictionary internal hashcode

我不确定这是否是在这里问的正确问题,但请不要杀了我:)

我和一个朋友就 C# 的字典发生了争执……她告诉我,如果我有的话,可以说字典有 1 个元素。并且键的哈希码是 100000,那么字典的内部数组的大小将是 100000!

这是真的吗?我试图在谷歌上找到答案,但由于某种原因我没有找到那个问题。

tom*_*ing 3

根据 MSDN 的说法,Dictionary 的默认构造函数“具有默认的初始容量” 。

它还指出:

如果您可以估计集合的大小,则使用指定初始容量的构造函数可以消除在向字典添加元素时执行大量调整大小操作的需要。

一个这样的构造函数只需要一个Int32,它初始化内部存储,如下所示:

字典可以包含的初始元素数。

字典的“默认初始容量”实际上是类的内部实现细节,因此不会在文档或公共 API 中公开。

反汇编mscorlibilspy检查默认构造函数表明它的实现如下:

public Dictionary() : this(0, null)
{
}
Run Code Online (Sandbox Code Playgroud)

该链式构造函数的实现如下:

public Dictionary(int capacity, IEqualityComparer<TKey> comparer)
{
    if (capacity < 0)
    {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity);
    }

    if (capacity > 0)
    {
        this.Initialize(capacity);
    }

    this.comparer = (comparer ?? EqualityComparer<TKey>.Default);
}
Run Code Online (Sandbox Code Playgroud)

ieInitialize()根本不会被默认构造函数直接或间接调用。

Initialize()是设置内部存储的方法。

所以实际上,如果您调用默认构造函数,内部存储大小甚至不会初始化,直到您第一次添加项目。所以它的大小基本上为零。

Initialize()最终在您第一次调用时以零值调用.Add(),这会进行设置。

private void Initialize(int capacity)
{
    int prime = HashHelpers.GetPrime(capacity);
    this.buckets = new int[prime];
    for (int i = 0; i < this.buckets.Length; i++)
    {
        this.buckets[i] = -1;
    }
    this.entries = new Dictionary<TKey, TValue>.Entry[prime];
    this.freeList = -1;
}
Run Code Online (Sandbox Code Playgroud)

GetPrime(0)返回3,因此this.buckets设置为包含三个整数的数组。

为 赋值的行this.entries看起来有点奇怪,但我不明白 100000 是在哪里出现的。

简短的回答
我认为你的同事是错的。