一、入门
1、简介
1.1、C#语言介绍
C#是一种新式编程语言,不仅面向对象,还类型安全。C# 是面向对象的、面向组件的编程语言。多项 C# 功能有助于创建可靠且持久的应用程序。 垃圾回收自动回收不可访问的未用对象所占用的内存。 可以为 null 的类型可防范不引用已分配对象的变量。 异常处理提供了一种结构化且可扩展的方法来进行错误检测和恢复。 Lambda 表达式支持函数编程技术。 语言集成查询 (LINQ) 语法创建一个公共模式,用于处理来自任何源的数据。 异步操作语言支持提供用于构建分布式系统的语法。 C# 有统一类型系统。 所有 C# 类型(包括 int 和 double 等基元类型)均继承自一个根 object 类型。 所有类型共用一组通用运算。 任何类型的值都可以一致地进行存储、传输和处理。 此外,C# 还支持用户定义的引用类型和值类型。 C# 允许动态分配轻型结构的对象和内嵌存储。 C# 支持泛型方法和类型,因此增强了类型安全性和性能。 C# 可提供迭代器,使集合类的实现者可以定义客户端代码的自定义行为。
面向对象三大特性
封装
封装就是通过给类及类中的成员变量、属性和方法设置不同的访问修饰符(public、protected、internal、protected internal、private)来控制它们的作用范围,以达到封装的目的。
访问修饰符 |
说明 |
public |
公有访问。不受任何限制。 |
protected |
保护访问。只限于本类内部和子类内部可访问,实例不能访问。 |
internal |
内部访问。只限于本项目内访问,其他不能访问。(相当于项目内的public) |
protected internal |
内部保护访问。只限于本项目和子类访问,其他不能访问。(protected和internal的权限之和)。 |
private |
私有访问。只限于本类成员内访问,子类、实例都不能访问。 |
继承
①被继承的类成为父类、基类、超类,而主动继承的类成为子类或派生类。子类继承父类的状态和行为,同时也有自己的特性。
②System.Object是所有类型的基类
③C#中继承的写法,class A:B{ }
④继承具有传递性,由A:B B:C=>A:C
⑤构造方法不能继承
⑥C#只允许单继承,一个类只能继承于一个父类
⑦密封类不能被继承,例如:sealed class Animal{ }
⑧子类不仅继承了父类的公有成员,同时继承了父类的私有成员,只是父类的私有成员在子类中不可被访问。
⑨当父类和子类中有名称相同的方法时,父类中的方法会被隐藏。
⑩A:B,A和B都有方法SayHi(),当B中的SayHi()是一个虚方法(virtual)时,才能在子类A中被重写/覆写,通过override关键字重写。
⑪里氏替换原则:子类对象可以赋值给父类变量,反之不成立。
多态
多态有两种形式:重载、重写/覆写。
①重载
同一个类中有多个方法的名称相同、参数个数不同或类型不同,则属于重载。
同一个类中有多个方法名称相同、参数个数相同、参数类型相同、返回值类型不同,这样不属于重载,编译时会报错。
②重写/覆写
实现重写有三种情况:
普通类中的virtual方法可在子类中被重写;
抽象类中的abstract方法和abstract属性必须直接或间接在子类中被重写;
接口中的所有成员都必须被子类实现。
三大 特性之间的关系
①继承时父类中的内容需要封装,例如:父类中的某些内容不希望被子类使用,那就需要使用private访问修饰符。
②重写形式的多态必须依靠继承,不继承是无法实现重写的,这无须多说。
③继承具有封装功能,继承分普通类、抽象类、接口三种情况。
1.2、.NET 体系结构
C# 程序在 .NET 上运行,而 .NET 是名为公共语言运行时 (CLR) 的虚执行系统和一组类库。 CLR 是 Microsoft 对公共语言基础结构 (CLI) 国际标准的实现。
用 C# 编写的源代码被编译成符合 CLI 规范的中间语言 (IL)。 IL 代码和资源(如位图和字符串)存储在扩展名通常为 .dll 的程序集中。
执行 C# 程序时,程序集将加载到 CLR。 CLR 会直接执行实时 (JIT) 编译,将 IL 代码转换成本机指令。 CLR 可提供其他与自动垃圾回收、异常处理和资源管理相关的服务。 CLR 执行的代码有时称为“托管代码”。而“非托管代码”被编译成面向特定平台的本机语言。
CLR
公共语言运行库(Common Language Runtime,CLR)是整个.NET框架的核心,它为.NET应用程序提供了一个托管的代码执行环境。它实际上是驻留在内存里的一段代理代码,负责应用程序在整个执行期间的代码管理工作。
CLI
CLI不是某种代码库或者程序,它是一项国际性的标准,全名是公共语言基础结构(Common Language Infrastructure)。它是一系列规范的总称。
IL
中间语言(中间代码)是一种面向语法,易于翻译成目标程序的源程序的等效内部表示代码。其可理解性及易于生成目标代码的程度介于源语言和目标语言之间。
1.3、类型和变量
类型定义 C# 中的任何数据的结构和行为。 类型的声明可以包含其成员、基类型、它实现的接口和该类型允许的操作。 变量是用于引用特定类型的实例的标签。
C# 有两种类型:值类型和引用类型。 值类型的变量直接包含它们的数据。 引用类型的变量存储对数据(称为“对象”)的引用。 对于引用类型,两个变量可以引用同一个对象;对一个变量执行的运算可能会影响另一个变量引用的对象。
C# 的值类型进一步分为:简单类型、枚举类型、结构类型、可以为 null 的值类型和元组值类型。 C# 引用类型又细分为类类型、接口类型、数组类型和委托类型。
值类型
简单类型
有符号整型:、short、int、long
无符号整型:、ushort、uint、ulong
Unicode 字符:,表示 UTF-16 代码单元
IEEE 二进制浮点:、double
高精度十进制浮点数:
布尔值:bool,表示布尔值(true 或 false)
枚举类型
enum E {…} 格式的用户定义类型。 enum 类型是一种包含已命名常量的独特类型。 每个 enum 类型都有一个基础类型(必须是八种整型类型之一)。 enum 类型的值集与基础类型的值集相同。
结构类型
格式为 struct S {…} 的用户定义类型
可以为 null 的值类型
值为 null 的其他所有值类型的扩展
元组值类型
格式为 (T1, T2, …) 的用户定义类型
引用类型
类类型
其他所有类型的最终基类:object
Unicode 字符串:,表示 UTF-16 代码单元序列
格式为 class C {…} 的用户定义类型
接口类型
格式为 interface I {…} 的用户定义类型
数组类型
一维、多维和交错。 例如:int[]、int[,] 和 int[][]
委托类型
格式为 delegate int D(…) 的用户定义类型
用户可定义以下六种 C# 类型:类类型、结构类型、接口类型、枚举类型、委托类型和元组值类型。 还可以声明 record 类型(record struct 或 record class)。
class 类型定义包含数据成员(字段)和函数成员(方法、属性及其他)的数据结构。 类类型支持单一继承和多形性,即派生类可以扩展和专门针对基类的机制。
struct 类型定义包含数据成员和函数成员的结构,这一点与类类型相似。 不过,与类不同的是,结构是值类型,通常不需要进行堆分配。 结构类型不支持用户指定的继承,并且所有结构类型均隐式继承自类型 object。
interface 类型将协定定义为一组已命名的公共成员。 实现 interface 的 class 或 struct 必须提供接口成员的实现代码。 interface 可以继承自多个基接口,class 和 struct 可以实现多个接口。
delegate 类型表示引用包含特定参数列表和返回类型的方法。 通过委托,可以将方法视为可分配给变量并可作为参数传递的实体。 委托类同于函数式语言提供的函数类型。 它们还类似于其他一些语言中存在的“函数指针”概念。 与函数指针不同,委托是面向对象且类型安全的。
class、struct、interface 和 delegate 类型全部都支持泛型,因此可以使用其他类型对它们进行参数化。
C# 支持任意类型的一维和多维数组。 可以为 null 的类型不需要单独定义。 C# 采用统一的类型系统,因此任意类型的值都可视为 object。
1.4、程序结构
C# 中的关键组织结构概念包括程序、命名空间、类型、成员和程序集。 程序声明类型,而类型则包含成员,并被整理到命名空间中。 类型示例包括类、结构和接口。 成员示例包括字段、方法、属性和事件。 编译完的 C# 程序实际上会打包到程序集中。 程序集的文件扩展名通常为 .exe 或 .dll,具体视其分别实现的是应用程序还是库.exe而定。
namespace Acme.Collections;
public class Stack<T>
{
Entry _top;
public void Push(T data)
{
_top = new Entry(_top, data);
}
public T Pop()
{
if (_top == null)
{
throw new InvalidOperationException();
}
T result = _top.Data;
_top = _top.Next;
return result;
}
class Entry
{
public Entry Next { get; set; }
public T Data { get; set; }
public Entry(Entry next, T data)
{
Next = next;
Data = data;
}
}
}
https://www.bookstack.cn/