在C#中,为什么“int”是System.Int32的别名?

时间:2011-12-24 18:00:42

标签: c# types language-design alias

由于C#支持Int8Int16Int32Int64,为什么该语言的设计者选择将int定义为{的别名{1}}而不是允许它根据本机架构认为是Int32的内容而变化?

我没有特别需要word表现出不同于它的方式,我只是要求纯粹的百科全书兴趣。

我认为可以想象存在64位RISC架构,它最有效地仅支持64位量,并且32位量的操作需要额外的操作。在程序坚持使用32位整数的世界中,这样的架构将处于不利地位,这是另一种说C#成为未来语言的方式,这实际上阻止了硬件设计者提出这样的问题。未来的建筑。

StackOverflow不鼓励推测答案,所以请仅在您的信息来自可靠来源时回答。我注意到SO的一些成员是微软的内部人员,所以我希望他们能够在这个问题上启发我们。

注1:事实上,我确实阅读了SO: Is it safe to assume an int will always be 32 bits in C#?的所有答案和所有评论,但没有找到关于我在这个问题中提出的 why 的任何提示。

注2:此问题在SO上的可行性(无结果)在此讨论:Meta: Can I ask a “why did they do it this way” type of question?

2 个答案:

答案 0 :(得分:33)

我认为他们的主要原因是针对CLR的程序的可移植性。如果他们允许基本类型int与平台相关,那么为CLR制作便携式程序将变得更加困难。在平台中立的C / C ++代码中扩展typedef - ed整数类型以涵盖内置int的使用,这是对CLR的设计者决定制作内置类型的原因的间接暗示平台无关。像这样的差异是基于虚拟机的执行系统“一次编写,随处运行”目标的重要阻碍。

编辑通常情况下,int的大小会通过位操作隐式地进入您的代码,而不是通过算术(毕竟,i++的大小可能会出错{1}},对吗?)但错误通常更微妙。请考虑以下示例:

const int MaxItem = 20;
var item = new MyItem[MaxItem];
for (int mask = 1 ; mask != (1<<MaxItem) ; mask++) {
    var combination = new HashSet<MyItem>();
    for (int i = 0 ; i != MaxItem ; i++) {
        if ((mask & (1<<i)) != 0) {
            combination.Add(item[i]);
        }
    }
    ProcessCombination(combination);
}

此代码计算并处理20个项目的所有组合。正如您所知,代码在具有16位int的系统上失败,但在32位或64位的整数下工作正常。

不安全的代码会提供另一个令人头痛的问题:当int被固定在某个大小(比方说32)的代码时,它会分配4倍的字节数,因为它需要编组的整数个数就会起作用,即使在技术上使用4代替sizeof(int)也是不正确的。此外,这种技术上不正确的代码仍然可以移植!

最终,像这样的小事在很大程度上将平台视为“好”或“坏”。 .NET程序的用户并不关心程序崩溃,因为程序员犯了一个非便携式错误,或者CLR是错误的。这类似于早期Windows由于驱动程序质量差而被广泛认为不稳定的方式。对于大多数用户来说,崩溃只是另一个.NET程序崩溃,而不是程序员的问题。因此,对于“.NET生态系统”的感知有利于使标准尽可能宽容。

答案 1 :(得分:6)

许多程序员倾向于为他们使用的平台编写代码。这包括关于类型大小的假设。如果将int的大小更改为16位或64位,则会有许多C程序失败,因为它们是在假设int为32位的情况下编写的。 C#的选择通过简单地定义它来避免这个问题。如果你根据平台将int定义为变量,则可以回到同一个问题。虽然你可能会认为这是程序员做出错误假设的错误,但它会使语言更加健壮(IMO)。对于桌面平台,32位int可能是最常见的事件。此外,它使本地C代码移植到C#更容易。

编辑:我认为您编写的代码比您想象的更频繁地对类型的sizer做出(隐式)假设。基本上任何涉及序列化的东西(如.NET远程处理,WCF,将数据序列化到磁盘等)都会让你遇到麻烦,如果你允许int的变量大小,除非程序员通过使用像{{1这样的特定大小的类型来处理它}}。然后你最终得到“我们将始终使用int32以防万一”并且你什么都没得到。