C# 进阶知识一周学习笔记
抽象类 & 多态
一、语法糖(Syntactic Sugar)
语法糖是指对语言功能没有实际影响,但能方便程序员使用的语法。
1.var—— 隐式类型推断
编译时确定类型,一旦推断不可更改。
csharp
var age = 30; // 编译器推断为 int var name = "虹猫学园"; // 编译器推断为 string
2.dynamic—— 运行时类型推断
运行时确定类型,编译时不进行类型检查。
csharp
dynamic data = 10; // 运行时为 int data = "虹猫学园"; // 运行时变为 string,编译通过
varvsdynamic:var性能更好、类型安全;dynamic更灵活但存在运行时风险。
3.const与readonly
| 特点 | const | readonly |
|---|---|---|
| 初始化时机 | 声明时 | 声明时或构造函数中 |
| 常量类型 | 编译时常量 | 运行时常量 |
| 静态性 | 默认静态 | 需显式声明static |
| 引用类型 | 仅限string和null | 可以是任何类型 |
二、重写(override)与隐藏(Hide)
重写条件:函数成员、
public/protected可见、签名一致。重写:父类用
virtual,子类用override重新实现。
csharp
class Vehicle { public virtual void Run() { ... } } class Car : Vehicle { public override void Run() { ... } }隐藏:不用
virtual/override,子类会隐藏父类方法,不常用。
三、抽象类(abstract)
抽象方法:只有声明,没有方法体,必须在子类中重写。
抽象类特点:
用
abstract修饰,不能被实例化。可以包含抽象方法和非抽象方法。
子类必须重写所有抽象方法(除非子类也是抽象类)。
可以有字段、属性、构造函数(用于初始化成员)。
abstract不能与以下关键字共存:private:子类无法继承,无法重写。static:静态方法不能是抽象的。
四、接口(interface)
接口是功能的集合,只声明不实现。
定义格式:
csharp
public interface 接口名 { 抽象方法1; 抽象方法2; }接口特点:
方法默认是
public abstract。不能包含字段、构造函数、静态成员。
一个类可以实现多个接口。
类与接口的关系:
类与类:单继承
类与接口:多实现
接口与接口:多继承
接口 vs 抽象类:
抽象类描述"是什么"(如:动物),接口定义"能做什么"(如:飞行)。
五、多态(Polymorphism)
1. 静态多态 —— 方法重载
编译时决定调用哪个方法。
2. 动态多态 —— 继承 + 重写
形成条件:①继承关系 ②方法重写 ③父类引用指向子类对象。
csharp
Animal a = new Dog(); // 父类引用指向子类对象 a.Eat(); // 运行时决定调用 Dog 的 Eat()
3. 动态多态的成员访问规则
| 成员类型 | 编译期看 | 运行期看 |
|---|---|---|
| 成员变量 | 父类 | 父类 |
| 成员方法 | 父类 | 子类(动态绑定) |
| 静态方法 | 父类 | 父类 |
4. 引用类型转型
向上转型(隐式):
Animal a = new Dog();向下转型(显式):
Dog d = (Dog)a;
六、内部类
定义在类内部的类,适用于仅在该类中使用的辅助类。
成员内部类创建方式:
Outer.Inner inner = new Outer.Inner();
泛型
一、装箱与拆箱(补充)
装箱:值类型 → 引用类型(
object)拆箱:引用类型 → 值类型
装箱拆箱会损耗性能,泛型可以避免。
二、为什么使用泛型
避免为不同类型重复写相同逻辑。
解决
object方式的类型不安全与性能问题。
三、泛型基础
泛型是延迟声明:定义时不指定类型,调用时指定。
可应用于:方法、类、接口、委托。
csharp
// 泛型方法 public static void Show<T>(T t) { ... } // 泛型类 public class GenericClass<T> { public T _T; } // 泛型接口 public interface IGenericInterface<T> { T GetT(T t); } // 泛型委托 public delegate void SayHi<T>(T t);四、泛型性能对比
性能排序:泛型方法 > 普通方法 >
object方法(因为装箱拆箱)。
五、泛型约束(where)
| 约束 | 说明 |
|---|---|
where T : struct | T 必须是值类型 |
where T : class | T 必须是引用类型 |
where T : new() | T 必须有无参公共构造函数 |
where T : 基类名 | T 必须是指定基类或其派生类 |
where T : 接口名 | T 必须实现指定接口 |
⚠️
new()约束必须放在最后。
异常处理
一、常见异常
索引越界:
IndexOutOfRangeException空引用:
NullReferenceException除零异常:
DivideByZeroException
二、异常体系结构
text
System.Exception ├── System.SystemException(系统异常) │ ├── NullReferenceException │ ├── IndexOutOfRangeException │ └── DivideByZeroException └── System.ApplicationException(自定义异常基类)
三、try-catch-finally
csharp
try { // 可能出错的代码 } catch (DivideByZeroException ex) { // 处理特定异常 } catch (Exception ex) { // 处理其他所有异常 } finally { // 无论是否异常,都执行(释放资源) }四、throw与throw ex的区别
| 写法 | 说明 |
|---|---|
throw; | ✅推荐,保留原始异常堆栈 |
throw ex; | ❌ 重置堆栈,丢失原始异常源 |
throw new Exception("msg", ex); | 包装异常,保留内部异常 |
五、自定义异常
继承
Exception或ApplicationException。提供三个构造函数:无参、带消息、带消息+内部异常。
六、using语法糖
using (资源对象) { ... }等价于try { ... } finally { 资源.Dispose(); }只能用于实现了
IDisposable接口的对象(如文件流、数据库连接)。
ArrayList 集合 & 队列 & 栈
一、ArrayList(非泛型集合)
本质是
object数组,容量自动扩充。缺点:存储值类型需装箱,读取需拆箱,类型不安全。
常用方法:
添加:
Add,Insert删除:
Remove,RemoveAt,RemoveRange,Clear查找:
Contains,IndexOf,LastIndexOf属性:
Count,Capacity
二、Queue队列(FIFO)
先进先出,只能从队尾入队,队头出队。
核心方法:
Enqueue:入队(添加)Dequeue:出队(移除并返回队头元素)Peek:查看队头元素(不移除)
有泛型版本
Queue<T>
三、Stack栈(LIFO)
后进先出,只能从栈顶入栈和出栈。
核心方法:
Push:入栈(添加)Pop:出栈(移除并返回栈顶元素)Peek:查看栈顶元素(不移除)
有泛型版本
Stack<T>
字典 & 排序列表
一、List<T>泛型集合
ArrayList的泛型版本,类型安全,无需装箱拆箱,性能更好。
csharp
List<Student> stus = new List<Student>(); stus.Add(new Student { ID = 1001, Name = "貂蝉" });二、Hashtable(哈希表)
键/值对集合,键不能为
null,值可以为null。非泛型,键和值都是
object,有装箱拆箱问题。常用方法:
Add,Remove,ContainsKey,ContainsValue
三、Dictionary<K, V>(泛型字典)
Hashtable的泛型版本,类型安全,性能更好。特点:键唯一,查找速度快(接近 O(1))。
常用属性和方法:
Count,Keys,ValuesAdd,ContainsKey,TryGetValue,Remove
使用示例:
csharp
Dictionary<int, Student> students = new Dictionary<int, Student>(); students.Add(stu1.ID, stu1); Student s = students[1002]; // 通过键取值
四、SortedList
键/值对集合,按键自动排序。
可通过键或索引访问。
五、集合嵌套
csharp
Dictionary<string, Dictionary<int, Student>> school = new Dictionary<...>(); // 学校 → 班级 → 学生 Console.WriteLine(school["net7"][1002].Name);
IO 流 & 文件操作
一、Path类(静态)
处理路径字符串:
GetFileName:获取文件名GetExtension:获取扩展名GetDirectoryName:获取目录Combine:拼接路径
二、File类(静态)与FileInfo(实例)
| 类 | 特点 |
|---|---|
File | 静态方法,适合单次操作 |
FileInfo | 实例方法,适合多次操作同一文件 |
File常用方法:
读写:
ReadAllText,WriteAllText,ReadAllLines,WriteAllLines操作:
Copy,Delete,Move,Exists
三、Directory类(静态)与DirectoryInfo(实例)
操作文件夹:
CreateDirectory,Delete,Move,Exists
四、FileStream(字节流)
读写任何类型的文件(文本、图片、视频)。
csharp
using (FileStream fs = new FileStream("path", FileMode.Open, FileAccess.Read)) { byte[] buffer = new byte[1024 * 1024 * 5]; int r = fs.Read(buffer, 0, buffer.Length); string s = Encoding.UTF8.GetString(buffer, 0, r); }五、StreamReader/StreamWriter(字符流)
专用于文本文件的读写。
csharp
using (StreamReader sr = new StreamReader("path")) { string line = sr.ReadLine(); } using (StreamWriter sw = new StreamWriter("path", true)) { // true 表示追加 sw.WriteLine("追加内容"); }六、BufferedStream(缓冲流)
包装其他流,通过缓冲区提升读写性能。
七、FileMode与FileAccess
| FileMode | 说明 |
|---|---|
Create | 创建新文件,存在则覆盖 |
CreateNew | 创建新文件,存在则报错 |
Open | 打开现有文件 |
OpenOrCreate | 存在则打开,不存在则创建 |
Append | 追加到文件末尾 |
八、文件复制示例
csharp
public static void CopyFile(string src, string dest) { using (FileStream fsRead = new FileStream(src, FileMode.Open, FileAccess.Read)) using (FileStream fsWrite = new FileStream(dest, FileMode.OpenOrCreate, FileAccess.Write)) { byte[] buffer = new byte[1024 * 1024 * 5]; int r; while ((r = fsRead.Read(buffer, 0, buffer.Length)) > 0) { fsWrite.Write(buffer, 0, r); } } }九、CryptoStream(加密流)
用于数据加密/解密,可与
FileStream配合使用。
多线程
📌 该文件与 Day13 同时提供,内容相互补充。
一、进程与线程
进程:工厂车间,资源分配的基本单位。
线程:车间里的工人,CPU 调度和执行的基本单位。
二、Process类
管理本地和远程进程。
csharp
Process[] pros = Process.GetProcesses(); // 获取所有进程 Process.Start("calc"); // 打开计算器 pros[i].Kill(); // 终止进程三、Thread类
命名空间:
System.Threading创建方式:
csharp
// 无参 Thread t = new Thread(Method); // 有参(object 类型) Thread t = new Thread(ParameterizedMethod); t.Start(obj);
常用属性:
Name,IsAlive,IsBackground,Priority,ThreadState常用方法:
Start,Sleep,Join,Abort
四、线程优先级
枚举值:
Lowest,BelowNormal,Normal(默认),AboveNormal,Highest高优先级线程获得更多 CPU 时间。
五、线程同步 ——lock互斥锁
确保同一时间只有一个线程访问共享资源。
csharp
private static object locker = new object(); lock (locker) { // 临界区代码 }锁对象建议:
private static readonly object
六、Mutex互斥锁
可跨进程同步,功能比
lock强大。
csharp
Mutex m = new Mutex(true, "MutexName", out bool createdNew); if (createdNew) { // 获得了互斥锁 }💎 本周学习总结
本周学习内容覆盖了 C# 面向对象高级特性、数据集合、泛型、异常处理、文件 IO 和多线程编程。核心要点如下:
| 分类 | 核心知识点 |
|---|---|
| 面向对象 | 抽象类、接口、多态(虚方法/重写)、类型转换 |
| 语法增强 | var/dynamic、const/readonly、using语法糖 |
| 集合 | ArrayList、List<T>、Queue、Stack、Hashtable、Dictionary<K,V>、SortedList |
| 泛型 | 泛型方法/类/接口/委托、泛型约束(where) |
| 异常 | try-catch-finally、throwvsthrow ex、自定义异常 |
| IO 与文件 | File/FileInfo、Directory/DirectoryInfo、FileStream、StreamReader/Writer |
| 多线程 | Process、Thread、线程优先级、lock和Mutex同步 |