阅读所有可能的C#数组初始化语法我想知道为什么C#总是推断int/Int32
的数组,其中较小的数据类型(如byte
或short
)就足够了。
new[] { 30, 130, 230 } // sbyte[] suffices but becomes int[]
new[] { -1, 125, -119 } // sbyte[] suffices but becomes int[]
new[] { -31647, -1337, 23456} // short suffices but becomes int[]
在引用的问题中,Eric Lippert指出使用了"最佳类型"——见下文,但int
如何成为最佳可能类型?如果我们要过度杀伤,为什么不使用long
呢?
数组元素的类型是通过计算最佳类型来推断的,如果存在,则为所有具有类型的给定元素中的一个。所有元素必须隐式转换为该类型。
我怀疑处理8或16位数据类型可能比32位结构更快,例如,当使用SIMD时,四个byte
实例可以容纳在一个int/Int32
的寄存器空间中。我知道JIT编译器没有(广泛)使用SSE指令,但"int
无处不在"的使用确保了当JIT编译器将包含此类优化时,它不会有多大帮助。
有人能详细说明这些事实,并说明为什么它总是求助于int
吗?
//编辑//我真的不在乎规范规定没有前缀的文字应该被视为int
。重新表述问题:
为什么要使用大于所需的数据类型?为什么规范对文字有这个规则优点是什么,因为巨大的缺点是远离未来(SIMD)优化。
为什么使用大于所需的数据类型?
用整数进行计算并能保证结果适合一个字节或短字节的业务线应用程序的数量少得可怜。整数计算结果适合int的业务线应用程序的数量是巨大。
为什么规范对文字有这个规则?
因为这是一个非常合理的规则。它是一致的、明确的和可以理解的。它在许多语言目标之间做出了很好的妥协,例如合理的性能、与现有非托管代码的互操作性、熟悉其他语言的用户,以及将数字视为数字而不是位模式。绝大多数C#程序使用数字作为数字。
优点是什么,因为最大的缺点是远离未来(SIMD)优化。
我向您保证,没有一个C#程序员会将"利用SIMD优化的困难"列为C#数组类型推理语义的"巨大缺点"。事实上,你可能是唯一一个。我当然不会想到这一点。如果你是那种非常关心它的人,那么将类型在数组初始值设定项中显式。
C#的设计并不是为了榨取未来可能发明的机器的最后一盎司性能,尤其是在涉及类型推理时也不是为了这样做。它的设计目的是提高业务线开发人员的生产力,而业务线开发员并不认为columnWidths = new [] { 10, 20, 30 };
是字节的数组。
C#5.0规范2.4.4.2
•如果文字没有后缀,则它具有可以表示其值的第一种类型:int、uint、long、ulong。
•如果文字的后缀是U或U,则它有这些类型中的第一种,可以表示其值:uint、ulong。
•如果文字的后缀是L或L,则它有这些类型中的第一种,可以表示其值:long、ulong。
•如果文字后缀为UL、UL、UL、UL、LU、LU、LU或LU,则为ulong类型。
您的所有示例都在该列表中排名第一。。。int
。
所有的积分文字都遵循这个规则。这就是为什么var i = 10;
也被推断为int
的原因。
当您放入不带任何后缀的整数值(如30, 130, 230
)时,您声明int32值;所以
new[] { 30, 130, 230 }; // <- array of int's
如果你想要byts的数组,你必须把它显式地放在上:
new byte[] { 30, 130, 230 }; // <- treat each value as byte
用作示例的文字都有System.Int32
,而这些值可以在不丢失的情况下存储在缩小的积分类型(例如System.Int16
)中,语法显示为System.Int32
。
由于每个数组的所有指定成员都是System.Int32
,因此该数组的类型为System.Int32[]
。
当然,可以定义一种语言,其中积分文字(没有后缀等其他指示)的类型为"足以容纳值的最小积分类型",该语言不是C#。
在最新的V5.0–C#语言规范中(来自我的VS2013安装),在2.4.4.2节中:
整型文字用于写入类型为
int
、uint
、long
和ulong
的值。
Ie。没有强制转换就无法编写byte
、sbyte
、short
或unsigned short
文字。
我相信在本机位大小下运行操作总是会更快,因此int
适用于32位机器,因此是惯例。
这也意味着,对于运行64位应用程序,对于数组,int64将比int更好地使用。