前言
💬 hello大家好啊,我是writer桑,这是自己整理的 C# 类型与变量的学习笔记。方便自己学习的同时分享出来。
1,类型和变量
类型定义C#中的任何数据的结构和行为。类型的声明可以包含其成员、基类型、它实现的接口和该类型允许的操作。变量是用于引用特定类型的实例的标签。
- C#有两种类型:值类型和引用类型。值类型的变量直接包含它们的数据。引用类型的变量存储对数据(称为"对象")的引用。
- 对于引用类型,两个变量可以引用同一个对象;对一个变量执行的运算可能会影响另一个变量引用的对象。
- 借助值类型,每个变量都有自己的数据副本;因此,对一个变量执行的运算不会影响另一个变量。(而ref和out参数变量除外)
标识符是变量名称。标识符是不包含任何空格的unicode字符序列。如果标识符的前缀为@,则该标识符可以是C#保留字。在与其他语言交互时,使用保留字作为标识符很有用。
前缀为@的标识符的示例如下:
// bool、class均为 C# 的保留字
int @bool = 11;
int @class = 22;
2,类型系统
C#的值类型进一步分为:简单类型、枚举类型、结构类型、可以为null的值类型和元组值类型。C#引用类型又细分为类类型、接口类型、数组类型和委托类型。
以下大纲概述了C#的类型系统:
- 值类型
- 简单类型
- 有符号整型:sbyte、short、int、long
- 无符号整型:byte、ushort、uint、ulong
- Unicode字符:char,表示 UTF-16 代码单元
- IEEE二进制浮点:float、double
- 高精度十进制浮点数:decimal
- 布尔值:bool,表示布尔值(true 或 false)
- 枚举类型
- enum E {…} 格式的用户定义类型。 enum 类型是一种包含已命名常量的独特类型。 每个 enum 类型都有一个基础类型(必须是八种整型类型之一)。enum 类型的值集与基础类型的值集相同。
- 结构类型
- 格式为 struct S {…} 的用户定义类型
- 可以为null的值类型
- 值为 null 的其他所有值类型的扩展
- 元组值类型
- 格式为 (T1, T2, …) 的用户定义类型
- 简单类型
- 引用类型
- 类类型
- 其他所有类型的最终基类:object
- Unicode 字符串:string,表示 UTF-16 代码单元序列
- 格式为 class C {…} 的用户定义类型
- 接口类型
- 格式为 interface I {…} 的用户定义类型
- 数组类型
- 一维、多维和交错。例如: int[]、int[,] 和 int[][]
- 委托类型
- 格式为delegate int D(…) 的用户定义类型
- 类类型
C#程序使用类型声明创建新类型。类型声明指定新类型的名称和成员。用户可定义以下六种C#类型:类类型、结构类型、接口类型、枚举类型、委托类型和元组值类型。还可以声明record类型(record struct 或 record class)。记录类型具有编译器合成成员。记录主要用于存储值,关联行为最少。
- (类)class 类型定义包含数据成员(字段)和函数成员(方法、属性及其他)的数据结构。 类类型支持单一继承和多形性,即派生类可以扩展和专门针对基类的机制。
- (结构体)struct 类型定义包含数据成员和函数成员的结构,这一点与类类型相似。 不过,与类不同的是,结构是值类型,通常不需要进行堆分配。 结构类型不支持用户指定的继承,并且所有结构类型均隐式继承自类型 object。
- (接口)interface 类型将协定定义为一组已命名的公共成员。 实现 interface 的 class 或struct 必须提供接口成员的实现代码。 interface 可以继承自多个基接口,class和 struct 可以实现多个接口。
- (委托)delegate 类型表示引用包含特定参数列表和返回类型的方法。 通过委托,可以将方法视为可分配给变量并可作为参数传递的实体。 委托类同于函数式语言提供的函数类型。 它们还类似于其他一些语言中存在的“函数指针”概念。 与函数指针不同,委托是面向对象且类型安全的。
class、struct、interface 和 delegate 类型全部都支持泛型,因此可以使用其他类型对它们进行参数化。
3,数组类型
C# 支持任意类型的一维和多维数组。 与上述类型不同,数组类型无需先声明即可使用。相反,数组类型是通过在类型名称后面添加方括号构造而成。 例如,int[] 是 int 类型的一维数组,int[,] 是 int 类型的二维数组,int[][] 是由 int 类型的一维数组或“交错”数组构成的一维数组。
一维数组,二维数组以及交错数组在程序中的声明如下所示:
int[] array1 = new int[] { 1 }; // 一维数组
int[,] array2 = new int[,] { { 1, 2 }, { 3, 4 } }; // 二维数组
// 交错数组的声明
int[][] jaggedArray2 = new int[][]
{
new int[] { 1, 3, 5, 7, 9 },
new int[] { 0, 2, 4, 6 },
new int[] { 11, 22 }
};
4,null类型
可以为 null 的类型不需要单独定义。 对于所有不可以为 null 的类型 T,都有对应的可以为 null 的类型 T?,后者可以包含附加值 null。 例如,int? 是可保存任何 32 位整数或null 值的类型,string? 是可以保存任何 string 或 null 值的类型。
不可以为 null 的类型 T 和可以为 null 的类型 T?的示例如下:
string notNull = "Hello"; // string不能为null
string? nullable = default; // string?可以为null
5,基类object
C# 采用统一的类型系统,因此任意类型的值都可视为 object。 每种 C# 类型都直接或间接地派生自 object 类类型,而 object 是所有类型的最终基类。 只需将值视为类object,即可将引用类型的值视为对象。 通过执行装箱和取消装箱操作,可以将值类型的值视为对象。
在以下示例中,int 值被转换成 object,然后又恢复成 int。
int i = 123;
object o = i; // 装箱
int j = (int)o; // 拆箱
- 将值类型的值分配给 object 对象引用时,会分配一个“箱”来保存此值。 该箱是引用类型的实例,此值会被复制到该箱。 相反,当 object 引用被显式转换成值类型时,将检查引用的 object 是否是具有正确值类型的箱。 如果检查成功,则会将箱中的值复制到值类型。
C# 的统一类型系统实际上意味着“按需”将值类型视为 object 引用。鉴于这种统一性,使用类型 object 的常规用途库可以与派生自 object 的所有类型结合使用,包括引用类型和值类型。
C# 有多种变量,其中包括字段、数组元素、局部变量和参数。 变量表示存储位置。 每个变量都具有一种类型,用于确定可以在变量中存储哪些值,如下文所述。
- 不可为null的值类型
- 具有精确类型的值
- 可以为null的值类型
- null值或具有精确类型的值
- object
- null 引用、对任意引用类型的对象的引用,或对任意值类型的装箱值的引用
- 类类型
- null 引用、对类类型实例的引用,或对派生自类类型的类实例的引用
- 接口类型
- null 引用、对实现接口类型的类类型实例的引用,或对实现接口类型的值类型的装箱值的引用
- 数组类型
- null 引用、对数组类型实例的引用,或对兼容的数组类型实例的引用
- 委托类型
- null引用或对兼容的委托类型实例的引用
结语
💭 以上就是C#的类型和变量的介绍,希望能够对大家有所帮助。感谢大家的支持。