C#中为什么没有Java的包装类integer?

2020-09-21 14:40发布

4条回答
收货啦官方账号
2020-09-21 15:12 .采纳回答



首先,C#中有值类型这个概念,也就是struct,因此自定义类型可以定义成struct使其始终停留在栈内存中(Java为什么没有我不知道),值类型是一个非常重要的功能,在一些原生的语言如C,C++,都有许多面向值类型的设计,比如引用,左右值等等。C#中的基本类型也不例外,int, double, float这些都可以看做一个struct,因此所有针对整数的处理都可以被包裹在int本身,也就不需要专门开一个Integer类型了。

既然自定义的值类型都已经被语言支持了,那么泛型毫无疑问也可以被支持了,所以理论上泛型支持所有格式,也可以用where限制格式,比如where T : IDisposable, 这一句勒令传入的类型必须继承了IDisposable这个接口,而C#的接口被用作泛型限制时,是同样不会因为闭包装装箱而产生内存垃圾的,也就是始终停留在栈内存中。

再来论证一下为什么需要值类型,很显然这个题目是“C#为什么不需要托管类型的int”,而不是“为什么C#比Java好”,所以我对于论证哪个语言更强毫无兴趣。我只是想单纯解释一下为什么值类型的设计对于C#这样一个语言来说至关重要,比如这里随便放一段代码,这段代码计算了一个OpenGL坐标系中世界坐标转模型坐标的矩阵:

可以看到,如果没有值类型,那么这小小的一段代码就会产生巨量的内存垃圾。首先第一句,就产生了4个float4实例和一个float4x4实例,float本身占4 byte,这就会产生(4 * 4 + 4 * 4) * 4 = 128 byte,第二句要用transpose返回一个新的实例,又产生了64 byte,第三句看似生成了一个实例,实际上是两个,mul函数返回了一个float4类型的实例,而.xyz作为一个属性则又返回了一个float3类型实例,所以这其实是(3 + 4) * 4 = 28 byte,localPos = -localPos这个理论上不产生实例,最后一句又产生了一个float4,也就是16 byte,那么这一段函数就产生了236 byte的内存垃圾,如果编译器没有特殊优化,那么可想而这这一段代码的性能可能会比有值类型时慢几十倍甚至上百倍。


一周热门 更多>