C#8.0本质论第二章--数据类型

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。

从C#7.0开始不用先声明只准备作为out参数使用的变量,该变量在if内部和外部均可使用。

你可能感兴趣的:(C#学习笔记,c#,.net,笔记)