c#读书笔记——类型和变量
文章目录
类型概述
C#中有两种类型:值类型***和***引用类型。
- 值类型的变量直接包含其数据,而引用类型的变量存储对其数据的引用。
- 后者称为对象。使用引用类型,两个变量可以引用同一对象,因此对一个变量的操作可能会影响另一个变量引用的对象。
- 对于值类型,变量每个都有其自己的数据副本,并且对一个变量的操作不可能影响另一个变量(
ref
和out
参数变量除外)。
值类型和**引用类型]**是C#类型的两个主要类别。
- 值类型
- 简单类型
- 符号整型:
sbyte
,short
,int
,long
- 无符号整型:
byte
,ushort
,uint
,ulong
- Unicode字符:
char
- IEEE二进制浮点数:
float
,double
- 高精度十进制浮点数:
decimal
- 布尔值:
bool
- 符号整型:
- 枚举类型
- 用户定义的表格类型
enum E {...}
- 用户定义的表格类型
- 结构类型
- 用户定义的表格类型
struct S {...}
- 用户定义的表格类型
- 可空值类型
- 具有
null
值的所有其他值类型的扩展
- 具有
- 简单类型
- 引用类型
- 类类型
- 所有其他类型的最终基础类:
object
- Unicode字符串:
string
- 用户定义的表格类型
class C {...}
- 所有其他类型的最终基础类:
- 接口类型
- 用户定义的表格类型
interface I {...}
- 用户定义的表格类型
- 数组类型
- 单和多维,例如,
int[]
和int[,]
- 单和多维,例如,
- 代表类型
- 用户定义的表格类型
delegate int D(...)
- 用户定义的表格类型
- 类类型
C#的bool
类型用于表示布尔值- true
或的值false
。
C#中的字符和字符串处理使用Unicode编码。该char
类型表示一个UTF-16代码单元,并且所述string
类型表示的UTF-16代码单元的序列。
C#程序使用类型声明来创建新类型。类型声明指定名称和新类型的成员。C#的类型类别中有五种是用户可定义的:类类型,结构类型,接口类型,枚举类型和委托类型。
甲class
类型定义了包含数据成员(字段)和函数成员(方法,属性等)的数据结构。类类型支持单一继承和多态性,派生类可以扩展和专门化基类的机制。
甲struct
类型类似于在它代表与数据成员和函数成员的结构的类类型。但是,与类不同,结构是值类型,通常不需要堆分配。结构类型不支持用户指定的继承,并且所有结构类型都隐式继承自type object
。
一种interface
类型定义了一个协定,作为一个命名集公共职能的成员。一个class
或struct
一个实现了interface
必须提供的接口函数成员的实现。一个interface
可以从多个基接口继承,而一个class
或struct
可以实现多个接口。
一个delegate
类型代表与特定参数列表和返回类型的方法的引用。委托使将方法视为可以分配给变量并作为参数传递的实体成为可能。委托类似于功能语言提供的功能类型。它们也类似于某些其他语言中的函数指针的概念。与函数指针不同,委托是面向对象的和类型安全的。
在class
,struct
,interface
,和delegate
类型都支持泛型,因此他们可以与其他类型的进行参数设置。
一种enum
类型是不同的类型与命名常量。每个enum
类型都有一个基础类型,该基础类型必须是八个整数类型之一。该组的值的enum
类型是相同的该组中的基础类型的值的。
C#支持任何类型的一维和多维数组。与上面列出的类型不同,在使用数组类型之前不必先声明它们。相反,数组类型是通过在类型名称后加上方括号来构造的。例如,int[]
是的一维数组int
,int[,]
是的二维数组int
,并且int[][]
是的一维数组的一维数组int
。
在使用空值类型之前也不必先声明它们。对于每种非空值类型T
,都有一个对应的可空值类型T?
,它可以容纳一个附加值null
。例如,int?
是一种可以容纳任何32位整数或value的类型null
。
C#的类型系统是统一的,因此任何类型的值都可以视为object
。C#中的每个类型都直接或间接源自object
类类型,并且object
是所有类型的最终基类。通过将引用类型的值视为type,可以将引用类型的值视为对象object
。通过执行装箱和拆箱操作,将值类型的值视为对象。在以下示例中,int
值将转换为object
,然后再次转换为int
。
using System;
class BoxingExample
{
static void Main()
{
int i = 123;
object o = i; // Boxing
int j = (int)o; // Unboxing
}
}
将值类型的值转换为type时object
,将object
分配一个实例(也称为“框”)以保存该值,然后将该值复制到该框中。相反,当将object
引用转换为值类型时,将检查所引用的object
是正确值类型的框,如果检查成功,则将框中的值复制出来。
C#的统一类型系统有效地意味着值类型可以成为“按需”对象。由于具有统一性,因此object
可以将使用类型的通用库与引用类型和值类型一起使用。
C#中有多种变量,包括字段,数组元素,局部变量和参数。变量代表存储位置,每个变量都有一个类型,该类型确定可以在变量中存储哪些值,如下所示。
- 非空值类型
- 该确切类型的值
- 可空值类型
- 一个
null
值或那个确切类型的值
- 一个
- 对象类型
null
参考,任何引用类型的对象的引用,或为任何值类型的装箱值的参考
- 类类型
null
引用,对该类类型的实例的引用,或一个类的实例的引用从该类类型派生
- 接口类型
null
参考,一类类型的实例的引用实现该接口类型,或为一个值类型的装箱值的引用对实现该接口类型
- 数组类型
null
引用,对该数组类型的实例的引用,或兼容数组类型的实例的引用
- 代表类型
null
参考或到兼容的委托类型的实例的引用
值类型
值类型概述
基本整数类型
C#支持以下预定义的整数类型:
C#类型/关键字 | 范围 | 尺寸 | .NET类型 |
---|---|---|---|
sbyte |
-128至127 | 有符号的8位整数 | 系统字节 |
byte |
0至255 | 无符号8位整数 | 系统字节 |
short |
-32,768至32,767 | 有符号的16位整数 | System.Int16 |
ushort |
0至65,535 | 无符号16位整数 | System.UInt16 |
int |
-2,147,483,648至2,147,483,647 | 有符号的32位整数 | System.Int32 |
uint |
0至4,294,967,295 | 无符号32位整数 | System.UInt32 |
long |
-9,223,372,036,854,775,808至9,223,372,036,854,775,807 | 有符号的64位整数 | System.Int64 |
ulong |
0至18,446,744,073,709,551,615 | 无符号64位整数 | System.UInt64 |
在上表中,最左列中的每个C#type关键字都是对应的.NET类型的别名。它们是可互换的。例如,以下声明声明了相同类型的变量:
int a = 123;
System.Int32 b = 123;
每个整数类型的默认值为零0
。每个整数类型都具有MinValue
和MaxValue
常数,它们提供该类型的最小值和最大值。
整型文字类型
整数文字可以是
- 小数:无任何前缀
- 十六进制:带有
0x
或0X
前缀 - binary:带有
0b
或0B
前缀(在C#7.0和更高版本中可用)
using System;
class BoxingExample
{
static void Main()
{
var decimalLiteral = 42;
var hexLiteral = 0x2A;
var binaryLiteral = 0b_0010_1010;
Console.WriteLine($"{decimalLiteral},{hexLiteral},{binaryLiteral}");
}
}
前面的示例还显示了将_
用作数字分隔符,从C#7.0开始支持。您可以将数字分隔符与所有类型的数字文字一起使用。
整数文字的类型由其后缀确定,如下所示:
- 如果文字没有后缀,其类型是所述第一以下类型,其中它的值可以表示的:
int
,uint
,long
,ulong
。 - 如果文字以
U
或作为后缀u
,则其类型是以下可以表示其值的类型中的第一个:uint
,ulong
。 - 如果文字以
L
或作为后缀l
,则其类型是以下可以表示其值的类型中的第一个:long
,ulong
。- 注意
- 您可以使用小写字母
l
作为后缀。但是,这会产生编译器警告,因为字母l
可能与digit混淆1
。L
为清楚起见使用。
- 您可以使用小写字母
- 注意
- 如果文字是由后缀
UL
,Ul
,uL
,ul
,LU
,Lu
,lU
,或lu
,其类型是ulong
。
如果由整数文字表示的值超UInt64.MaxValue,则会发生编译器错误CS1021。
如果一个整数文字的确定的类型是int
和由文字表示的值在目标类型的范围内,该值可以被隐式转换为sbyte
,byte
,short
,ushort
,uint
,或ulong
:
byte a = 17;
byte b = 300; // CS0031: Constant value '300' cannot be converted to a 'byte'
如前面的示例所示,如果文字的值不在目标类型的范围内,则会发生编译器错误CS0031。
您还可以使用强制转换将整数文字形式表示的值转换为确定的文字类型之外的其他类型:
var signedByte = (sbyte)42;
var longVariable = (long)42;
转换次数
您可以将任何整数数字类型转换为任何其他整数数字类型。如果目标类型可以存储源类型的所有值,则转换是隐式的。否则,您需要使用强制转换运算符()
来调用显式转换。有关更多信息,请参见内置数字转换。
浮点数值类型
浮点类型总述
在浮点数字类型表示实数。所有浮点数字类型都是值类型。它们也是简单类型,可以使用文字进行初始化。所有浮点数字类型都支持算术,比较和相等运算符。
浮点类型的特征
C#支持以下预定义的浮点类型:
C#类型/关键字 | 大概范围 | 精确 | 尺寸 | .NET类型 |
---|---|---|---|---|
float |
±1.5 x 10 −45至±3.4 x 10 38 | 约6-9位数 | 4字节 | 单系统 |
double |
±5.0×10 -324到±1.7×10 308 | 约15-17位数字 | 8字节 | 系统双 |
decimal |
±1.0 x 10 -28至±7.9228 x 10 28 | 28-29位数字 | 16字节 | 系统十进制 |
在上表中,最左列中的每个C#type关键字都是对应的.NET类型的别名。它们是可互换的。例如,以下声明声明了相同类型的变量:
double a = 12.3;
System.Double b = 12.3;
每种浮点类型的默认值为零0
。每个浮点类型都有MinValue
和MaxValue
常数,它们提供该类型的最小和最大有限值。
由于decimal
类型比float
和都具有更高的精度和更小的范围double
,因此它适合进行财务和货币计算。
您可以在表达式中混合使用整数类型和float
和double
类型。在这种情况下,整数类型会隐式转换为浮点类型之一,如有必要,该float
类型会隐式转换为double
。该表达式的计算如下:
- 如果
double
表达式中有类型,则表达式的计算结果为double
,或bool
关系和相等比较中的。 - 如果
double
表达式中没有类型,则表达式的计算结果为float
,或者为bool
关系和相等比较的结果。
您还可以decimal
在表达式中混合使用整数类型和类型。在这种情况下,整数类型将隐式转换为该decimal
类型,并且表达式在关系和相等比较中的计算结果为decimal
或bool
。
您不能在表达式中将decimal
类型与float
和double
类型混合使用。在这种情况下,如果要执行算术,比较或相等运算,则必须明确地将操作数从decimal
类型转换为类型,如以下示例所示:
double a = 1.0;
decimal b = 2.1m;
Console.WriteLine(a + (double)b);
Console.WriteLine((decimal)a + b);
输出值为:
3.1
3.1
注释:
decimal必须后面加m或M.
实际文字的类型由其后缀确定,如下所示:
- 不带后缀或带有
d
或D
后缀的文字类型为double
- 带
f
或F
后缀的文字类型为float
- 带
m
或M
后缀的文字类型为decimal
double d = 3D;
d = 4d;
d = 3.934_001;
float f = 3_000.5F;
f = 5.4f;
decimal myMoney = 3_000.5m;
myMoney = 400.75M;
前面的示例还显示了将_
用作数字分隔符,从C#7.0开始支持。您可以将数字分隔符与所有类型的数字文字一起使用。
您还可以使用科学计数法,即指定真实文字的指数部分,如以下示例所示:
double d = 0.42e2;
Console.WriteLine(d); // output 42;
float f = 134.45E-2f;
Console.WriteLine(f); // output: 1.3445
decimal m = 1.5E6m;
Console.WriteLine(m); // output: 1500000
输出结果为:
42
1.3445
1500000
转换次数
浮点数值类型之间只有一种隐式转换:从float
到double
。但是,您可以使用显式cast将任何浮点类型转换为任何其他浮点类型。有关更多信息,请参见内置数字转换。
类型间的转化
C#提供了一组整数和浮点数字类型。任意两个数字类型(隐式或显式)之间都存在转换。您必须使用强制转换运算符()
来调用显式转换。
隐式数值转换(类型的自动转化)
表显示了内置数字类型之间的预定义隐式转换:
从 | 至 |
---|---|
sbyte | short , int , long , float , double , or decimal |
byte | short , ushort , int , uint , long , ulong , float , double , or decimal |
short | int , long , float , double , or decimal |
ushort | int , uint , long , ulong , float , double , or decimal |
int | long , float , double , or decimal |
uint | long , ulong , float , double , or decimal |
long | float , double , or decimal |
ulong | float , double , or decimal |
float | double |
从隐式转换int
,uint
,long
,或ulong
到float
从long
或ulong
到double
可能造成的精度损失,但从来没有一个数量级的损失。其他隐式数值转换不会丢失任何信息。
另请注意