C#8.0本质论第二章–数据类型
2.1基本数据类型
C#的基本数据类型都有关键字与之关联,decimal是特殊的浮点数类型,能存储大数字而无表示错误。
2.1.1整数类型
C#中有8种整数类型
类型 | 大小 | BCL名称 | 后缀 |
---|---|---|---|
sbyte | 8位 | System.SByte | |
byte | 8位 | System.Byte | |
short | 16位 | System.Int16 | |
ushort | 16位 | System.UInt16 | |
int | 32位 | System.Int32 | |
uint | 32位 | System.UInt32 | U或u |
long | 64位 | System.Int64 | L或l |
ulong | 64位 | System.UInt64 | UL或ul |
C#所有基元类型都有短名称和完整名称,完整名称对应**BCL(基类库)**中的类型名称,该名称在所有语言中都相同,对程序集中的类型进行了唯一性标识。从编译器角度看,最终生成的CIL代码看不出源代码具体使用的是哪一种。不要时而用短名称时而用完整名称,比如用string而不是System.String。
2.1.2浮点类型
浮点数精度可变,除非分母恰好是2的整数幂,否则用二进制浮点类型无法准确表示该数比如0.1容易表示成0.09999999…或者0.10000…1,
类型 | 大小 | BCL名称 | 有效位数 | 后缀 |
---|---|---|---|---|
float | 32位 | System.Single | 7 | F或f |
double | 64位 | System.Double | 15-16 | D或d |
2.1.3decimal类型
类型 | 大小 | BCL名称 | 有效位数 | 后缀 |
---|---|---|---|---|
decimal | 128位 | System.Decimal | 28-29 | M或m |
和浮点数不同,decimal类型保证范围内的所有十进制数都是精确的,但是它的范围较小,计算速度稍慢,但差别不大可以忽略不计。之所以用m表示decimal是因为这种数据类型经常用于货币(monetary)计算。
2.1.4字面值
字面值(literal value)表示源代码中的固定值。直接将值放到源代码中称为硬编码(hardcoding)。默认情况下输入带小数点的字面值,编译器会自动把它解释成double类型,整数值通常默认为32位int,如果值太大编译器会把它解释成long。此外,C#编译器允许向非int的数值类赋值,如:
short s = 42;
byte b = 77;
这一点仅对字面值成立,而下面是非法的:
b = s;
有时数字很大,为了解决可读性问题,C#7.0新增了对数字分隔符的支持,可在书写字面值时用下划线(_)分割,如9_814_072_356
0x002A表示16进制42,从C#7.0开始可将数字表示成二进制值,如0b101010表示42,从C#7.2开始可以把数字分隔符放到x或b后面
输出时可以将数字格式化成十六进制:
//输出0x2A,即十六进制的42
System.Console.Writeline($"0x{42:X}");
为了更准确地表示double值的字符串形式,可以使用格式字符串和**round-trip格式说明符R(或r)**进行转换。
2.2更多基本类型
2.2.1布尔类型
类型 | 大小 | BCL名称 |
---|---|---|
bool | 8位 | System.Boolean |
虽然一个二进制位足以容纳布尔一个类型的值,但是在C#里bool实际是一个字节大小。
2.2.2字符类型
类型 | 大小 | BCL名称 |
---|---|---|
char | 16位 | System.Char |
char表示16位字符,虽然大小和ushort相同,但是char是C#特有类型,要单独对待(C++里是8位)。
反斜杠和特殊字符代码统称为转义序列(escape sequence)。
2.2.3字符串
类型 | BCL名称 |
---|---|
string | System.String |
零或多个字符的有限序列称为字符串。
C#允许在字符串前使用@符号,指明转义序列不被处理,结果是一个逐字字符串字面值(verbatim string literal)。(对应C++11里的raw string)。
和C++不同的是,C#不自动连接字符串字面值。(是的,C++里"ab" “cd"会自动连接成"abcd”)。
假如同一字符串面值在程序集中多次出现,那么编译器在程序集中只定义字符串一次,且所有变量都指向它。
逐字和插值可组合使用,先指定$再指定@。
字符串插值是调用string.Format()方法的语法糖,比如:
//表面上
System.Console.Writeline($"your name is {firstname},{lastname}.");
//实际上
object[] args = new object[] {firstname,lastname};
System.Writeline($"your name is {0},{1}.",args);
实现了某种程度上的本地化支持,不会因为字符串造成编译后代码注入。
一些字符串方法:Format,Concat,Compare,StartsWith,EndsWith,ToLower,ToUpper,Trim,TrimEnd,Replace.
之前调用静态方法需附加如命名空间和类型名前缀,可利用C#6.0新增的using static指令避免这些前缀。只支持静态方法和属性。
如果要在插值或格式化的字符串中添加实际的左右大括号,可连写两个大括号来表示,如$“{{ {123} }}“表示字符串”{ 123 }”.
输出换行所需的字符由操作系统决定,Windows的换行符是\r和\n两个字符组合,而UNIX是单个\n,
要依赖System.WriteLine()和System.Enviroment.NewLine()而不是\n来确保跨平台兼容。
C#语法允许像访问成员变(在C#中称为字段)量那样访问属性(Property),属性定义了称为**赋值方法(setter)和取值方法(getter)**的特殊方法
string类型的关键特征是它不可变(immutable),处于性能考虑,没有提供修改现有字符串内容的机制,不可能在同一个内存位置将字符串中的字母全部转换成大写,只能在其他位置新建字符串,让它成为旧字符串大写字母版本,而旧字符串不会被修改。
如有大量字符串需要修改,可考虑使用System.Text.StringBuilder类型而不是string。
2.2.4null和void
将null赋给引用类型的变量和根本不赋值是不一样的概念。将null赋给string变量和为变量赋值""也不是一样的概念。
声明变量时在名称后加一个问号,表示该变量可以被设置为null,这便是可空修饰符(C#2.0后)。
在C#8.0之前,可控修饰符不能用于引用类型变量的声明,从C#8.0开始,有了可空引用类型的概念,若要启动,则需要在声明变量之前任意位置放置"#nullable enable"语句。被启用时将没有可控修饰符的变量设置为null将会产生警告信息。
void有两个含义:标记方法不返回任何值,以及代表指向未知类型的存储位置的一个指针,但这种在C#中比较罕见。
2.3数据类型转换
有可能造成数据丢失或抛出异常的任何转换都要执行显示转型。相反的都可以进行隐式转型。
2.3.1显示转型
默认情况下,容不下的数据在赋值时会悄悄地溢出,但将代码放到checked块中,就会使运行时引发System.OverflowException异常:
checked
{
int n = inr.MaxValue+1;
}
还支持unchecked块强制不进行溢出检查。
C#不支持从数值类型到布尔类型的有效转换,是为了避免可能发生的歧义,还有助于避免用户在本应使用相等操作符的时候用赋值操作符。
2.3.2隐式转型
2.3.3不使用转型操作符的类型转换
每个数值数据类型都包含一个Parse()方法,允许将字符串转换成对应的数值类型,还可以用特殊类型System.Convert()。
所有类型都支持ToString()方法。
从C#2.0起,所有基元数值类型都包含静态TryParse()方法,与Parse()的区别是,转换失败不是抛出异常,而是返回false。文章来源:https://www.toymoban.com/news/detail-634074.html
从C#7.0开始不用先声明只准备作为out参数使用的变量,该变量在if内部和外部均可使用。文章来源地址https://www.toymoban.com/news/detail-634074.html
到了这里,关于C#8.0本质论第二章--数据类型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!