C#中有些奇怪 - UInt32 vs Int32

Ste*_*rck 3 c# unsigned signed

背景

我在C#工作,通常为嵌入式项目编写支持程序.我从一个早已离开的人那里继承了一个项目,这是我的一个客户用来通过RS-232下载和上传Intel Hex文件到他们的一些主板的程序.这个程序很好地为他们工作了好几年,但是我正在研究的新板子没有,并且需要一些修改.

问题

我打开了这个项目,发现了这个问题.新电路板在该范围内的地址处生成一些数据0x90000000-0x9007FFFF,而C#代码使用该int类型作为地址数据; 签名,错误地处理地址0x80000000.到现在为止还挺好.但后来我自大了.

我决定清理代码,用Int16/UInt16/Int32/UInt32替换所有"int",具体取决于用法.花了一段时间,但我认为它会使代码更清晰,更容易理解,并希望避免任何未来的错误.

代码停止工作.它花了我一天的大部分时间,它归结为这一行:

currseg = (HexSegment)hex_segments[HashEntry];
Run Code Online (Sandbox Code Playgroud)

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

public struct HexSegment
{
    UInt32 Address; // this is the fix I made, both were int
    UInt32 Buf_idx;
}
Run Code Online (Sandbox Code Playgroud)

hex_segments是一个HashTable.

最后,HashEntry是一个"int",也是一个UInt32.

在调试器中我看到了这个:

在此输入图像描述

如果看不到图像,则HashEntry的值为0x00000000.如果我要求调试器查看hex_segments[0],我会获得MLV.HexSegment合法数据.如果我要求调试器看到hex_segments[HashEntry],我会得到null!

更改HashEntryInt32解决问题.

就像我说的,我是一名嵌入式程序员.对我来说,这是一个很大的谜.有没有人可以解释为什么会这样?

mat*_*net 5

因为Hashtable是由对象索引而不是由int索引的.

public virtual object this[object key] { get; set; }
Run Code Online (Sandbox Code Playgroud)

因此,如果使用键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);
Run Code Online (Sandbox Code Playgroud)

  • 只是补充一下:自C#2以来的推荐是使用`Dictionary <UInt32,HexSegment>`.因为编译器知道查找总是使用`UInt32`完成,所以它将确保你不能使用除了`UInt32`之外的任何东西. (3认同)