C#中有些奇怪的地方-UInt32与Int32

时间:2019-02-19 15:42:34

标签: c# unsigned signed

背景

我从事C#工作,通常为嵌入式项目编写支持程序。我从一个久违的人那里继承了一个项目,该程序被我的一位客户用来通过RS-232下载Intel Hex文件并将其上传到他们的某些主板的程序。多年来,该程序对他们来说都运作良好,但对于我正在研究的新董事会却没有,并且需要进行一些修改。

问题

我打开了项目,发现了问题。新的电路板在0x90000000-0x9007FFFF范围内的地址处生成一些数据,而C#代码在地址数据中使用int类型。签名,错误地处理了0x80000000上的地址。到目前为止,一切都很好。但是后来我变得自大了。

我决定清理代码,根据用途将所有“ int”替换为Int16 / UInt16 / Int32 / UInt32。花了一段时间,但我认为它将使代码更清晰,更易理解,并希望避免将来出现任何错误。

该代码停止工作。花了我大部分时间,然后归结为这一行:

currseg = (HexSegment)hex_segments[HashEntry];

HexSegment类型是一个结构(是,结构,不是类),

public struct HexSegment
{
    UInt32 Address; // this is the fix I made, both were int
    UInt32 Buf_idx;
}

hex_segments是一个哈希表。

最后,HashEntry是一个“ int”,也变成了UInt32

在调试器中,我看到以下内容:

enter image description here

如果看不到图像,则HashEntry的值为0x00000000。 如果我要求调试器查看hex_segments[0],则会得到MLV.HexSegment包含合法数据的信息。 如果我要求调试器查看hex_segments[HashEntry],我将得到空值!

HashEntry更改为Int32可以解决此问题。

就像我说的那样,我是一名嵌入式程序员。对我来说,这是一个很大的谜。有谁能解释为什么会这样?

1 个答案:

答案 0 :(得分:5)

因为Hashtable是按对象而不是int索引的。

public virtual object this[object key] { get; set; }

因此,如果添加了一个键0为Int32的对象,则不同于添加了0的UInt32对象。

看看这个:

UInt32 index = 0;
Int32 index2 = 0;
Hashtable t = new Hashtable();

t.Add(index, new { name = "matt" });
t.Add(index2, new { name = "Matt" });

var obj = t[index];
var obj2 = t[index2];

Console.WriteLine(obj);
Console.WriteLine(obj2);