CLR via C# 编程语言的基元类型

某些数据类型很常用,以至于许多编译器允许代码以简化语法来操纵它们。

它太繁琐了。包括C#在内的许多编译器都允许换用下面的语法:

这种语法不仅增强了代码的可读性,生成的 IL 代码还与使用System.Int32 生成的 IL 代码完全一致。

编译器直接支持的数据类型称为基元类型(primitive type)。基元类型直接映射到Framework类库(FCL)中存在的类型。

C#基元类型与对应的FCL类型
C#基元类型FCL类型符合CLS说明
sbyteSystem.SByte有符号8位值
byteSystem.Byte无符号8位值
shortSystem.Int16有符号16位值
ushortSystem.UInt16无符号16位值
intSystem.Int32有符号32位值
uintSystem.UInt32无符号32位值
longSystem.Int64有符号64位值
ulongSystem.UInt64无符号64位值
charSystem.Char16位Unicode字符
floatSystem.SingleIEEE32位浮点值
doubleSystem.DoubleIEEE64位浮点值
boolSystem.Booleantrue/false值
decimalSystem.Decimal128位高精度浮点值
stringSystem.String字符数组
objectSystem.Object所有类型的基类型
dynamicSystem.Object对于CLR,dynamic与object完全一致

C#语言规范建议使用关键字,但是本书作者不建议,理由如下4点:

1.许多开发人员纠结是用string还是String。由于C#的string(一个关键字)直接映射到SystemString(一个FCL类型),所以两者没有区别。

2.C#的long映射到System.Int64,但在其他编程语言中,long可能映射到int16或int32。

3.FCL的许多方法都将类型名作为方法名的一部分。System.Convert类型的方法包括ToBoolean,ToInt32,ToSingle等。

都正确,第一个别扭,第二个自然。

4.平时只用C#的许多程序员逐渐忘了还可以用其他语言写面向CLR的代码,“C#主义”逐渐入侵类库代码。

//--

System.Int32和System.Int64是不同的类型,相互不存在派生关系。

C#编译器会正确编译上述类型,运行起来也没问题。因为C#编译器非常熟悉基元类型,会在编译代码时应用自己的特殊规则。

只有在转换“安全”的时候,C#才允许隐式转换。所谓“安全”,是指不会发生数据丢失的情况。

但如果可能不安全,C#就要求显式转换。对于数值类型,“不安全”意味着转换后可能丢失精度或数量级。

不同编译器可能生成不同代码来处理这些转换。例如,将值为6.8的Single转换为Int32,有的编译器可能生成代码对其进行截断(向下取整),最终是6。而有些编译器可能将结果向上取整为7。C#总是对结果进行截断。

除了转型,基本类型还能写成字面值(literal)。字面值可能被看成是类型本身的实例。

另外,如果表达式由字面值构成,编译器在编译时就能完成表达式求值,从而增强应用程序性能:

最后,编译器知道如何和以什么顺序解析代码中的操作符(+,-,*,/,%,&,^,|,==,!=,>,<,>=,<=,<<,>>,~,!,++,--等)。

//--checked和unchecked基元类型操作

对基元类型执行的许多算数运算都可能造成溢出:

溢出大多数时候是我们不希望的。如果没有检测到这种溢出,会导致应用程序行为失常。

(极少时候(比如计算哈希值或者检验和)这种溢出不仅可接受还是我们希望的)。

除了全局性地打开或关闭溢出检查,程序员还可以在代码特定区域控制溢出检查。

除了checked和unchecked操作符,C#还支持checked和unchecked语句,它们造成一个块中的所有表达式都进行或不进行溢出检查:

建议:

1.尽量使用有符号数值类型(比如Int32和Int64)而不是无符号数值类型(比如UInt32和UInt64)。这允许编译器检测更多的上溢/下溢错误。除此之外,类库多个部分(比如Array和String的Length属性)被硬编码为返回有符号的值。这样代码中四处移动这些值时,需要进行的强制类型转换就少了。较少的强制类型使代码更整洁,更容易维护。除此之外,无符号数值类型不符合CLS。

2.写代码时,如果代码可能发生你不希望的溢出,就把这些代码放到checked块中。同时捕捉OverflowException,得体地从错误中恢复。

3.写代码时,将允许发生溢出的代码显式放到unchecked块中。

4.对于没有使用checked和unchecked的任何代码,都假定你希望发生溢出时抛出一个异常,此时的溢出应被记为bug。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值