C# 中的一些奇怪的东西 - UInt32 与 Int32
Something strange in C# - UInt32 vs Int32
背景
我在 C# 工作,通常为嵌入式项目编写支持程序。我从一个早已离去的人那里继承了一个项目,这是我的一位客户用来通过 RS-232 下载和上传 Intel Hex 文件到他们的一些主板的程序。该程序多年来对他们来说工作得很好,但我正在研究的新板却没有,需要进行一些修改。
问题
我打开项目,发现了问题。新板正在 0x90000000-0x9007FFFF
范围内的地址生成一些数据,而 C# 代码使用 int
类型作为地址数据;已签名,错误处理了 0x80000000
上的地址。到目前为止,一切都很好。但后来我变得自大了。
我决定清理代码,根据用途将所有 "int" 替换为 Int16/UInt16/Int32/UInt32。花了一段时间,但我认为这会使代码更清晰易懂,并希望避免任何未来的错误。
代码停止工作。我花了大半天时间,归结为这一行:
currseg = (HexSegment)hex_segments[HashEntry];
HexSegment 类型是结构(是的,结构,不是 class),
public struct HexSegment
{
UInt32 Address; // this is the fix I made, both were int
UInt32 Buf_idx;
}
hex_segments 是一个哈希表。
最后,HashEntry 是一个"int",也变成了一个UInt32
。
在调试器中我看到了这个:
如果看不到图片,HashEntry的值为0x00000000
。
如果我要求调试器查看 hex_segments[0]
,我会得到一个包含合法数据的 MLV.HexSegment
。
如果我要求调试器查看 hex_segments[HashEntry]
,我会得到 null!!
将 HashEntry
更改为 Int32
解决了该问题。
正如我所说,我是一名嵌入式程序员。对我来说,这是一个很大的谜团。有谁能解释一下为什么会这样吗?
因为 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);
背景
我在 C# 工作,通常为嵌入式项目编写支持程序。我从一个早已离去的人那里继承了一个项目,这是我的一位客户用来通过 RS-232 下载和上传 Intel Hex 文件到他们的一些主板的程序。该程序多年来对他们来说工作得很好,但我正在研究的新板却没有,需要进行一些修改。
问题
我打开项目,发现了问题。新板正在 0x90000000-0x9007FFFF
范围内的地址生成一些数据,而 C# 代码使用 int
类型作为地址数据;已签名,错误处理了 0x80000000
上的地址。到目前为止,一切都很好。但后来我变得自大了。
我决定清理代码,根据用途将所有 "int" 替换为 Int16/UInt16/Int32/UInt32。花了一段时间,但我认为这会使代码更清晰易懂,并希望避免任何未来的错误。
代码停止工作。我花了大半天时间,归结为这一行:
currseg = (HexSegment)hex_segments[HashEntry];
HexSegment 类型是结构(是的,结构,不是 class),
public struct HexSegment
{
UInt32 Address; // this is the fix I made, both were int
UInt32 Buf_idx;
}
hex_segments 是一个哈希表。
最后,HashEntry 是一个"int",也变成了一个UInt32
。
在调试器中我看到了这个:
如果看不到图片,HashEntry的值为0x00000000
。
如果我要求调试器查看 hex_segments[0]
,我会得到一个包含合法数据的 MLV.HexSegment
。
如果我要求调试器查看 hex_segments[HashEntry]
,我会得到 null!!
将 HashEntry
更改为 Int32
解决了该问题。
正如我所说,我是一名嵌入式程序员。对我来说,这是一个很大的谜团。有谁能解释一下为什么会这样吗?
因为 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);