Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.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/22.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_.net Micro Framework - Fatal编程技术网

C# 什么会导致添加到哈希表的键为空?

C# 什么会导致添加到哈希表的键为空?,c#,.net,.net-micro-framework,C#,.net,.net Micro Framework,使用.NET Micro Framework 4.1 我正在将以下字符串键(和字符串值,此处不相关)添加到哈希表中: "eth::address" "eth::netmask" "eth::gateway" "eth::dns" "eth::port" "com::baudrate" "com::parity" "com::databits" "com::stopbits" "com::handshake" "com::read-timeout" "com::write-timeout" "dr

使用.NET Micro Framework 4.1

我正在将以下字符串键(和字符串值,此处不相关)添加到哈希表中:

"eth::address"
"eth::netmask"
"eth::gateway"
"eth::dns"
"eth::port"
"com::baudrate"
"com::parity"
"com::databits"
"com::stopbits"
"com::handshake"
"com::read-timeout"
"com::write-timeout"
"drv::led-firmware-file"
"scr::width"
"scr::height"
"scr::colors"
将这些添加到哈希表时,不会抛出错误

但是,在查看哈希表的属性和内容时 我可以看到:

public Hashtable(int capacity) : this(capacity, (float) 1f)
{
}

public Hashtable(int capacity, float loadFactor)
{
    // arguments checking - elided

    this.loadFactor = 0.72f * loadFactor;
    double num = ((float) capacity) / this.loadFactor;
    if (num > 2147483647.0)
    {
        throw new ArgumentException(
            Environment.GetResourceString("Arg_HTCapacityOverflow"));
    }
    int num2 = (num > 3.0) ? HashHelpers.GetPrime((int) num) : 3;
    this.buckets = new bucket[num2];
    this.loadsize = (int) (this.loadFactor * num2);
    this.isWriterInProgress = false;
}
16个bucket,但其中6个具有null键和null值。 总是一样的

这可能是什么原因造成的

更新:

没有太多代码可发布:

var settings = new HashTable(16);
settings.Add("eth::address", "192.168.1.1");
//Keep adding the settings mentioned above
没有抛出异常,最终有16个异常 哈希表中的项,从3个有效项开始,然后是一些空项,然后是一些有效项,等等

因为这只是一个简单的测试用例,所以不涉及任何其他内容

如果我试图获取其中一个“丢失”的值, 将引发异常:

var x = settings["eth::port"];
将导致:

A first chance exception of type 'System.Exception' occurred in mscorlib.dll
An unhandled exception of type 'System.Exception' occurred in mscorlib.dll


enter code here

我没有访问micro framework的权限,但对于.NET4.0,我使用您提供的示例进行了测试,它分配了23个bucket,其中7个具有空值。每个值都放置在bucket中,其哈希代码为%23。例如,eth::gateway的散列码为1866092901,其模数23为22,因此将其放入第22个存储桶中。为什么要担心哈希表的内部桶分配策略?在Linqpad中尝试下面的代码,您可以确定:

void Main()
{
    string[] vals = {"eth::address", "eth::netmask", .. all other strings... };
    var ht = new Hashtable(16);
    foreach (var v in vals) 
          ht[v] = v;
    var m = typeof(Hashtable).GetField("buckets", BindingFlags.NonPublic | BindingFlags.Instance);
    m.GetValue(ht).Dump();
    ht.Dump();
}

要扩展Volkan的答案-检查
Hashtable
的内部实现,您可能会发现以下内容:

public Hashtable(int capacity) : this(capacity, (float) 1f)
{
}

public Hashtable(int capacity, float loadFactor)
{
    // arguments checking - elided

    this.loadFactor = 0.72f * loadFactor;
    double num = ((float) capacity) / this.loadFactor;
    if (num > 2147483647.0)
    {
        throw new ArgumentException(
            Environment.GetResourceString("Arg_HTCapacityOverflow"));
    }
    int num2 = (num > 3.0) ? HashHelpers.GetPrime((int) num) : 3;
    this.buckets = new bucket[num2];
    this.loadsize = (int) (this.loadFactor * num2);
    this.isWriterInProgress = false;
}
那么,当您使用
新哈希表(16)
初始化它时会发生什么呢。。。?首先,
num
的值被计算为
16/0.72=22。(2)
。然后,
HashHelpers.GetPrime(22)
启动,如下所示:

internal static int GetPrime(int min)
{
    // arguments checking - elided

    for (int i = 0; i < primes.Length; i++)
    {
        int num2 = primes[i];
        if (num2 >= min)
        {
            return num2;
        }
    }

    // more code; irrelevant in this case - elided
}

使用
22
作为
min
参数,我们可以很容易地看到
GetPrime
返回
23
。这是在
Hashtable
构造函数中用于创建bucket数组的值。您可以对micro framework执行相同的分析,以了解它为什么会创建16个bucket(考虑到bucket number作为prime值是一种良好的做法,这很奇怪,TBH)

你可能需要发布更多的代码。没有太多的文章要发布了。我想说的是,<代码>哈希表< /代码>正在丢失条目。试着定义你的哈希表,而不是一个容量,只是为了测试你应该考虑哈希表是否在你的字符串上做引用相等,在这种情况下,即使字符串值相等,查找也可能失败。要解决此问题,请指定创建哈希表时要使用的相等比较。哈希表的实现也可能有缺陷,因为它在调试器中显示了16个bucket,并且哈希表通常不使用非素数大小。在不寻常的平台上非通用集合的非标准使用有时可能会有问题。