From f604d5319156c60d09fef25b258824ffe28774b6 Mon Sep 17 00:00:00 2001
From: Rosmontis_Cloud <2451830085@qq.com>
Date: Wed, 1 Jul 2026 16:31:35 +0800
Subject: [PATCH] =?UTF-8?q?Initial=20commit:=20C#=20=E5=AD=A6=E4=B9=A0?=
=?UTF-8?q?=E7=AC=94=E8=AE=B0=E5=92=8C=E7=A4=BA=E4=BE=8B=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Lesson 01-10: C# 基础语法
- WebView2: 集成示例
- notes/: 详细笔记
---
.gitignore | 25 +++
WebView2Demo | 1 +
lessons/Lesson02/Lesson02.csproj | 10 +
lessons/Lesson02/Program.cs | 67 ++++++
lessons/Lesson03/Lesson03.csproj | 10 +
lessons/Lesson03/Program.cs | 96 +++++++++
lessons/Lesson04/Lesson04.csproj | 10 +
lessons/Lesson04/Program.cs | 119 +++++++++++
lessons/Lesson05/Helpers/MathHelper.cs | 27 +++
lessons/Lesson05/Lesson05.csproj | 10 +
lessons/Lesson05/Models/Person.cs | 46 +++++
lessons/Lesson05/Program.cs | 42 ++++
lessons/Lesson05/Services/AudioService.cs | 39 ++++
lessons/Lesson06/Animals/Animal.cs | 25 +++
lessons/Lesson06/Animals/Cat.cs | 16 ++
lessons/Lesson06/Animals/Dog.cs | 27 +++
lessons/Lesson06/Devices/Camera.cs | 34 ++++
lessons/Lesson06/Devices/IDevice.cs | 10 +
lessons/Lesson06/Devices/Microphone.cs | 34 ++++
lessons/Lesson06/Lesson06.csproj | 10 +
lessons/Lesson06/Program.cs | 55 +++++
lessons/Lesson07/Lesson07.csproj | 10 +
lessons/Lesson07/Program.cs | 107 ++++++++++
lessons/Lesson08/Lesson08.csproj | 10 +
lessons/Lesson08/Program.cs | 187 +++++++++++++++++
lessons/Lesson09/Lesson09.csproj | 10 +
lessons/Lesson09/Program.cs | 103 ++++++++++
lessons/Lesson10/Lesson10.csproj | 10 +
lessons/Lesson10/Program.cs | 136 +++++++++++++
lessons/Lesson_One/Lesson01_HelloWorld.cs | 24 +++
lessons/Lesson_One/Lesson_One.csproj | 10 +
lessons/Lesson_One/Program.cs | 67 ++++++
notes/01_CSharp_Basics.md | 46 +++++
notes/02_Variables_and_Types.md | 62 ++++++
notes/03_Conditions_and_Loops.md | 102 ++++++++++
notes/04_Methods_and_Classes.md | 91 +++++++++
notes/05_MultiFile_and_Access_Modifiers.md | 114 +++++++++++
notes/06_Inheritance_and_Interface.md | 191 ++++++++++++++++++
notes/07_Collections.md | 135 +++++++++++++
notes/08_Exception_Handling.md | 164 +++++++++++++++
notes/09_File_IO.md | 150 ++++++++++++++
notes/10_Delegates_and_Events.md | 182 +++++++++++++++++
notes/11_WebView2_Basics.md | 121 +++++++++++
notes/PDF/01_CSharp_Basics.pdf | Bin 0 -> 183250 bytes
notes/PDF/02_Variables_and_Types.pdf | Bin 0 -> 196606 bytes
notes/PDF/03_Conditions_and_Loops.pdf | Bin 0 -> 169847 bytes
notes/PDF/04_Methods_and_Classes.pdf | Bin 0 -> 220791 bytes
.../PDF/05_MultiFile_and_Access_Modifiers.pdf | Bin 0 -> 369412 bytes
notes/PDF/06_Inheritance_and_Interface.pdf | Bin 0 -> 322454 bytes
notes/PDF/07_Collections.pdf | Bin 0 -> 304593 bytes
notes/PDF/08_Exception_Handling.pdf | Bin 0 -> 381916 bytes
51 files changed, 2745 insertions(+)
create mode 100644 .gitignore
create mode 160000 WebView2Demo
create mode 100644 lessons/Lesson02/Lesson02.csproj
create mode 100644 lessons/Lesson02/Program.cs
create mode 100644 lessons/Lesson03/Lesson03.csproj
create mode 100644 lessons/Lesson03/Program.cs
create mode 100644 lessons/Lesson04/Lesson04.csproj
create mode 100644 lessons/Lesson04/Program.cs
create mode 100644 lessons/Lesson05/Helpers/MathHelper.cs
create mode 100644 lessons/Lesson05/Lesson05.csproj
create mode 100644 lessons/Lesson05/Models/Person.cs
create mode 100644 lessons/Lesson05/Program.cs
create mode 100644 lessons/Lesson05/Services/AudioService.cs
create mode 100644 lessons/Lesson06/Animals/Animal.cs
create mode 100644 lessons/Lesson06/Animals/Cat.cs
create mode 100644 lessons/Lesson06/Animals/Dog.cs
create mode 100644 lessons/Lesson06/Devices/Camera.cs
create mode 100644 lessons/Lesson06/Devices/IDevice.cs
create mode 100644 lessons/Lesson06/Devices/Microphone.cs
create mode 100644 lessons/Lesson06/Lesson06.csproj
create mode 100644 lessons/Lesson06/Program.cs
create mode 100644 lessons/Lesson07/Lesson07.csproj
create mode 100644 lessons/Lesson07/Program.cs
create mode 100644 lessons/Lesson08/Lesson08.csproj
create mode 100644 lessons/Lesson08/Program.cs
create mode 100644 lessons/Lesson09/Lesson09.csproj
create mode 100644 lessons/Lesson09/Program.cs
create mode 100644 lessons/Lesson10/Lesson10.csproj
create mode 100644 lessons/Lesson10/Program.cs
create mode 100644 lessons/Lesson_One/Lesson01_HelloWorld.cs
create mode 100644 lessons/Lesson_One/Lesson_One.csproj
create mode 100644 lessons/Lesson_One/Program.cs
create mode 100644 notes/01_CSharp_Basics.md
create mode 100644 notes/02_Variables_and_Types.md
create mode 100644 notes/03_Conditions_and_Loops.md
create mode 100644 notes/04_Methods_and_Classes.md
create mode 100644 notes/05_MultiFile_and_Access_Modifiers.md
create mode 100644 notes/06_Inheritance_and_Interface.md
create mode 100644 notes/07_Collections.md
create mode 100644 notes/08_Exception_Handling.md
create mode 100644 notes/09_File_IO.md
create mode 100644 notes/10_Delegates_and_Events.md
create mode 100644 notes/11_WebView2_Basics.md
create mode 100644 notes/PDF/01_CSharp_Basics.pdf
create mode 100644 notes/PDF/02_Variables_and_Types.pdf
create mode 100644 notes/PDF/03_Conditions_and_Loops.pdf
create mode 100644 notes/PDF/04_Methods_and_Classes.pdf
create mode 100644 notes/PDF/05_MultiFile_and_Access_Modifiers.pdf
create mode 100644 notes/PDF/06_Inheritance_and_Interface.pdf
create mode 100644 notes/PDF/07_Collections.pdf
create mode 100644 notes/PDF/08_Exception_Handling.pdf
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3cf4ff9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+# .NET
+bin/
+obj/
+*.user
+*.suo
+*.cache
+*.log
+
+# IDE
+.vs/
+.vscode/
+*.swp
+
+# Build results
+[Dd]ebug/
+[Rr]elease/
+x64/
+x86/
+
+# NuGet
+packages/
+*.nupkg
+
+# WebView2
+*.WebView2/
diff --git a/WebView2Demo b/WebView2Demo
new file mode 160000
index 0000000..1d85cb1
--- /dev/null
+++ b/WebView2Demo
@@ -0,0 +1 @@
+Subproject commit 1d85cb160f81d5a41125d348f97c01b2db0a09b4
diff --git a/lessons/Lesson02/Lesson02.csproj b/lessons/Lesson02/Lesson02.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/lessons/Lesson02/Lesson02.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/lessons/Lesson02/Program.cs b/lessons/Lesson02/Program.cs
new file mode 100644
index 0000000..5a0173b
--- /dev/null
+++ b/lessons/Lesson02/Program.cs
@@ -0,0 +1,67 @@
+using System;
+
+namespace Lesson02
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ // ========== 变量 ==========
+ int age = 25;
+ double height = 175.5;
+ string name = "无言势字幕";
+ char grade = 'A';
+ bool isActive = true;
+
+ Console.WriteLine("=== 变量 ===");
+ Console.WriteLine($"姓名: {name}");
+ Console.WriteLine($"年龄: {age}");
+ Console.WriteLine($"身高: {height}cm");
+ Console.WriteLine($"等级: {grade}");
+ Console.WriteLine($"状态: {isActive}");
+
+ // ========== var 自动推断 ==========
+ Console.WriteLine("\n=== var 自动推断 ===");
+ var message = "这是 string 类型";
+ var number = 42; // 推断为 int
+ Console.WriteLine($"message 是: {message.GetType()}");
+ Console.WriteLine($"number 是: {number.GetType()}");
+
+ // ========== 常量 ==========
+ Console.WriteLine("\n=== 常量 ===");
+ const int MAX_RETRY = 3;
+ const string VERSION = "v1.0";
+ Console.WriteLine($"最大重试次数: {MAX_RETRY}");
+ Console.WriteLine($"版本: {VERSION}");
+
+ // ========== 类型转换 ==========
+ Console.WriteLine("\n=== 类型转换 ===");
+ int i = 10;
+ double d = i; // 隐式转换
+ Console.WriteLine($"int -> double: {d}");
+
+ double d2 = 3.14;
+ int i2 = (int)d2; // 显式转换
+ Console.WriteLine($"double -> int: {i2}");
+
+ string s = i.ToString();
+ Console.WriteLine($"int -> string: {s}");
+
+ int i3 = int.Parse("123");
+ Console.WriteLine($"string \"123\" -> int: {i3}");
+
+ // ========== 输入练习 ==========
+ Console.WriteLine("\n=== 输入练习 ===");
+ Console.Write("请输入你的名字: ");
+ string inputName = Console.ReadLine();
+ Console.Write($"你好, {inputName}! ");
+
+ Console.Write("请输入年龄: ");
+ string ageInput = Console.ReadLine();
+ int userAge = int.Parse(ageInput);
+ Console.WriteLine($"你 {userAge} 岁了");
+
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/lessons/Lesson03/Lesson03.csproj b/lessons/Lesson03/Lesson03.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/lessons/Lesson03/Lesson03.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/lessons/Lesson03/Program.cs b/lessons/Lesson03/Program.cs
new file mode 100644
index 0000000..1531250
--- /dev/null
+++ b/lessons/Lesson03/Program.cs
@@ -0,0 +1,96 @@
+using System;
+
+namespace Lesson03
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ // ========== if / else ==========
+ Console.WriteLine("=== if / else ===");
+ int score = 85;
+
+ if (score >= 90)
+ {
+ Console.WriteLine("优秀");
+ }
+ else if (score >= 60)
+ {
+ Console.WriteLine("及格");
+ }
+ else
+ {
+ Console.WriteLine("不及格");
+ }
+
+ // 三元运算符
+ string result = score >= 60 ? "及格" : "不及格";
+ Console.WriteLine($"三元运算: {result}");
+
+ // ========== switch ==========
+ Console.WriteLine("\n=== switch ===");
+ int day = 3;
+
+ switch (day)
+ {
+ case 1:
+ Console.WriteLine("星期一");
+ break;
+ case 2:
+ Console.WriteLine("星期二");
+ break;
+ case 3:
+ Console.WriteLine("星期三");
+ break;
+ default:
+ Console.WriteLine("其他");
+ break;
+ }
+
+ // ========== for 循环 ==========
+ Console.WriteLine("\n=== for 循环 ===");
+ for (int i = 0; i < 5; i++)
+ {
+ Console.WriteLine($"计数: {i}");
+ }
+
+ // ========== foreach ==========
+ Console.WriteLine("\n=== foreach 循环 ===");
+ string[] names = { "无言势", "VRChat", "字幕" };
+
+ foreach (string name in names)
+ {
+ Console.WriteLine(name);
+ }
+
+ // ========== while 循环 ==========
+ Console.WriteLine("\n=== while 循环 ===");
+ int count = 0;
+ while (count < 3)
+ {
+ Console.WriteLine($"while: {count}");
+ count++;
+ }
+
+ // ========== do while ==========
+ Console.WriteLine("\n=== do while ===");
+ int n = 0;
+ do
+ {
+ Console.WriteLine($"do while: {n}");
+ n++;
+ } while (n < 3);
+
+ // ========== break 和 continue ==========
+ Console.WriteLine("\n=== break 和 continue ===");
+ for (int i = 0; i < 10; i++)
+ {
+ if (i == 3) continue; // 跳过 3
+ if (i == 7) break; // 退出循环
+ Console.WriteLine(i);
+ }
+
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/lessons/Lesson04/Lesson04.csproj b/lessons/Lesson04/Lesson04.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/lessons/Lesson04/Lesson04.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/lessons/Lesson04/Program.cs b/lessons/Lesson04/Program.cs
new file mode 100644
index 0000000..3b7c7bd
--- /dev/null
+++ b/lessons/Lesson04/Program.cs
@@ -0,0 +1,119 @@
+using System;
+
+namespace Lesson04
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ // ========== 方法调用 ==========
+ Console.WriteLine("=== 方法 ===");
+ SayHello("无言势");
+ int sum = Add(10, 20);
+ Console.WriteLine($"10 + 20 = {sum}");
+
+ // 带默认参数
+ Greet();
+ Greet("VRC");
+
+ // ========== 类和对象 ==========
+ Console.WriteLine("\n=== 类和对象 ===");
+ Person p1 = new Person("无言势", 25);
+ Person p2 = new Person("玩家A", 30);
+
+ p1.SayHi();
+ p2.SayHi();
+
+ // ========== 静态方法 ==========
+ Console.WriteLine("\n=== 静态方法 ===");
+ int result = MathHelper.Add(100, 200);
+ Console.WriteLine($"100 + 200 = {result}");
+
+ double pi = MathHelper.GetPI();
+ Console.WriteLine($"PI ≈ {pi}");
+
+ // ========== 面向对象练习 ==========
+ Console.WriteLine("\n=== 麦克风类 ===");
+ Microphone mic = new Microphone("USB麦克风", true);
+ mic.ToggleListening();
+ mic.ToggleListening();
+
+ Console.ReadLine();
+ }
+
+ // ========== 方法定义 ==========
+ static void SayHello(string name)
+ {
+ Console.WriteLine($"你好, {name}!");
+ }
+
+ static int Add(int a, int b)
+ {
+ return a + b;
+ }
+
+ static void Greet(string name = "World")
+ {
+ Console.WriteLine($"Hello, {name}");
+ }
+ }
+
+ // ========== 类定义 ==========
+ class Person
+ {
+ public string name;
+ public int age;
+
+ // 构造函数
+ public Person(string name, int age)
+ {
+ this.name = name;
+ this.age = age;
+ }
+
+ public void SayHi()
+ {
+ Console.WriteLine($"我是{name},今年{age}岁");
+ }
+ }
+
+ // 静态类
+ static class MathHelper
+ {
+ public static int Add(int a, int b)
+ {
+ return a + b;
+ }
+
+ public static double GetPI()
+ {
+ return 3.14159;
+ }
+ }
+
+ // 麦克风类 - 结合项目练习
+ class Microphone
+ {
+ private string name;
+ private bool isListening;
+
+ public Microphone(string name, bool isListening)
+ {
+ this.name = name;
+ this.isListening = isListening;
+ }
+
+ public void ToggleListening()
+ {
+ isListening = !isListening;
+ if (isListening)
+ {
+ Console.WriteLine($"[{name}] 开始监听...");
+ }
+ else
+ {
+ Console.WriteLine($"[{name}] 停止监听");
+ }
+ }
+ }
+}
diff --git a/lessons/Lesson05/Helpers/MathHelper.cs b/lessons/Lesson05/Helpers/MathHelper.cs
new file mode 100644
index 0000000..b8b81ad
--- /dev/null
+++ b/lessons/Lesson05/Helpers/MathHelper.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Lesson05.Helpers
+{
+ static class MathHelper
+ {
+ public static int Add(int a, int b)
+ {
+ return a + b;
+ }
+
+ public static int Multiply(int a, int b)
+ {
+ return a * b;
+ }
+
+ public static double Divide(int a, int b)
+ {
+ if (b == 0)
+ {
+ Console.WriteLine("除数不能为0!");
+ return 0;
+ }
+ return (double)a / b;
+ }
+ }
+}
diff --git a/lessons/Lesson05/Lesson05.csproj b/lessons/Lesson05/Lesson05.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/lessons/Lesson05/Lesson05.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/lessons/Lesson05/Models/Person.cs b/lessons/Lesson05/Models/Person.cs
new file mode 100644
index 0000000..ce1327a
--- /dev/null
+++ b/lessons/Lesson05/Models/Person.cs
@@ -0,0 +1,46 @@
+using System;
+
+namespace Lesson05.Models
+{
+ class Person
+ {
+ // public: 任何地方都能访问
+ public string name;
+
+ // private: 只有本类内部能访问
+ private int age;
+ private string secret = "秘密信息";
+
+ // Property: 受保护的访问方式
+ public int Age
+ {
+ get { return age; }
+ set
+ {
+ // value 是关键字,表示赋值时的右值
+ if (value < 0) value = 0;
+ if (value > 150) value = 150;
+ age = value;
+ }
+ }
+
+ // 构造函数
+ public Person(string name, int age)
+ {
+ this.name = name;
+ this.Age = age; // 通过 Property 设置,自动限制范围
+ }
+
+ public void SayHi()
+ {
+ Console.WriteLine($"我是 {name},今年 {age} 岁");
+ Console.WriteLine($"我的秘密: {GetSecret()}"); // 本类内可以调用私有方法
+ }
+
+ // 私有方法:本类内部使用
+ private string GetSecret()
+ {
+ return secret;
+ }
+ }
+}
diff --git a/lessons/Lesson05/Program.cs b/lessons/Lesson05/Program.cs
new file mode 100644
index 0000000..c9b8e5f
--- /dev/null
+++ b/lessons/Lesson05/Program.cs
@@ -0,0 +1,42 @@
+using System;
+using Lesson05.Models;
+using Lesson05.Services;
+using Lesson05.Helpers;
+
+namespace Lesson05
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("=== 多文件项目演示 ===\n");
+
+ // 使用 Models 里的类
+ Person p = new Person("无言势", 25);
+ p.SayHi();
+
+ // 使用 Property
+ p.Age = -5; // 会自动限制范围
+ Console.WriteLine($"设置后年龄: {p.Age}");
+
+ p.Age = 200;
+ Console.WriteLine($"设置后年龄: {p.Age}");
+
+ // 使用 Services
+ AudioService service = new AudioService();
+ service.StartListening();
+ service.StopListening();
+
+ // 使用 Helpers
+ int sum = MathHelper.Add(100, 200);
+ Console.WriteLine($"\n100 + 200 = {sum}");
+
+ // 演示 private 无法访问
+ // p.secret = "xxx"; // 编译错误
+ // p.SetSecret("xxx"); // 编译错误
+
+ Console.WriteLine("\n=== 演示完成 ===");
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/lessons/Lesson05/Services/AudioService.cs b/lessons/Lesson05/Services/AudioService.cs
new file mode 100644
index 0000000..2500521
--- /dev/null
+++ b/lessons/Lesson05/Services/AudioService.cs
@@ -0,0 +1,39 @@
+using System;
+
+namespace Lesson05.Services
+{
+ class AudioService
+ {
+ private bool isListening;
+ private string deviceName;
+
+ public AudioService()
+ {
+ this.deviceName = "默认麦克风";
+ this.isListening = false;
+ }
+
+ public void StartListening()
+ {
+ if (!isListening)
+ {
+ isListening = true;
+ Console.WriteLine($"[{deviceName}] 开始监听...");
+ }
+ }
+
+ public void StopListening()
+ {
+ if (isListening)
+ {
+ isListening = false;
+ Console.WriteLine($"[{deviceName}] 停止监听");
+ }
+ }
+
+ public bool IsListening()
+ {
+ return isListening;
+ }
+ }
+}
diff --git a/lessons/Lesson06/Animals/Animal.cs b/lessons/Lesson06/Animals/Animal.cs
new file mode 100644
index 0000000..7d7319a
--- /dev/null
+++ b/lessons/Lesson06/Animals/Animal.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace Lesson06.Animals
+{
+ class Animal
+ {
+ protected string name;
+
+ public Animal(string name)
+ {
+ this.name = name;
+ }
+
+ public void Eat()
+ {
+ Console.WriteLine($"{name} 在吃东西");
+ }
+
+ // virtual 允许子类重写
+ public virtual void Speak()
+ {
+ Console.WriteLine($"{name} 发出了声音");
+ }
+ }
+}
diff --git a/lessons/Lesson06/Animals/Cat.cs b/lessons/Lesson06/Animals/Cat.cs
new file mode 100644
index 0000000..8808970
--- /dev/null
+++ b/lessons/Lesson06/Animals/Cat.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Lesson06.Animals
+{
+ class Cat : Animal
+ {
+ public Cat(string name) : base(name)
+ {
+ }
+
+ public override void Speak()
+ {
+ Console.WriteLine($"{name} 喵喵喵~");
+ }
+ }
+}
diff --git a/lessons/Lesson06/Animals/Dog.cs b/lessons/Lesson06/Animals/Dog.cs
new file mode 100644
index 0000000..8cbe59b
--- /dev/null
+++ b/lessons/Lesson06/Animals/Dog.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Lesson06.Animals
+{
+ class Dog : Animal
+ {
+ private string breed;
+
+ // base(name) 调用父类的构造函数
+ public Dog(string name, string breed) : base(name)
+ {
+ this.breed = breed;
+ }
+
+ public void Info()
+ {
+ Console.WriteLine($"名字: {name}, 品种: {breed}");
+ }
+
+ // 重写父类方法
+ public override void Speak()
+ {
+ base.Speak(); // 先调用父类方法
+ Console.WriteLine($"{name} 汪汪汪!");
+ }
+ }
+}
diff --git a/lessons/Lesson06/Devices/Camera.cs b/lessons/Lesson06/Devices/Camera.cs
new file mode 100644
index 0000000..6a585dc
--- /dev/null
+++ b/lessons/Lesson06/Devices/Camera.cs
@@ -0,0 +1,34 @@
+using System;
+
+namespace Lesson06.Devices
+{
+ class Camera : IDevice
+ {
+ private string name;
+ public bool IsConnected { get; private set; }
+
+ public Camera(string name)
+ {
+ this.name = name;
+ this.IsConnected = false;
+ }
+
+ public void Connect()
+ {
+ if (!IsConnected)
+ {
+ IsConnected = true;
+ Console.WriteLine($"[{name}] 摄像头已连接");
+ }
+ }
+
+ public void Disconnect()
+ {
+ if (IsConnected)
+ {
+ IsConnected = false;
+ Console.WriteLine($"[{name}] 摄像头已断开");
+ }
+ }
+ }
+}
diff --git a/lessons/Lesson06/Devices/IDevice.cs b/lessons/Lesson06/Devices/IDevice.cs
new file mode 100644
index 0000000..e448f41
--- /dev/null
+++ b/lessons/Lesson06/Devices/IDevice.cs
@@ -0,0 +1,10 @@
+namespace Lesson06.Devices
+{
+ // 接口:定义契约
+ interface IDevice
+ {
+ void Connect();
+ void Disconnect();
+ bool IsConnected { get; }
+ }
+}
diff --git a/lessons/Lesson06/Devices/Microphone.cs b/lessons/Lesson06/Devices/Microphone.cs
new file mode 100644
index 0000000..068ebf5
--- /dev/null
+++ b/lessons/Lesson06/Devices/Microphone.cs
@@ -0,0 +1,34 @@
+using System;
+
+namespace Lesson06.Devices
+{
+ class Microphone : IDevice
+ {
+ private string name;
+ public bool IsConnected { get; private set; }
+
+ public Microphone(string name)
+ {
+ this.name = name;
+ this.IsConnected = false;
+ }
+
+ public void Connect()
+ {
+ if (!IsConnected)
+ {
+ IsConnected = true;
+ Console.WriteLine($"[{name}] 麦克风已连接");
+ }
+ }
+
+ public void Disconnect()
+ {
+ if (IsConnected)
+ {
+ IsConnected = false;
+ Console.WriteLine($"[{name}] 麦克风已断开");
+ }
+ }
+ }
+}
diff --git a/lessons/Lesson06/Lesson06.csproj b/lessons/Lesson06/Lesson06.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/lessons/Lesson06/Lesson06.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/lessons/Lesson06/Program.cs b/lessons/Lesson06/Program.cs
new file mode 100644
index 0000000..010b699
--- /dev/null
+++ b/lessons/Lesson06/Program.cs
@@ -0,0 +1,55 @@
+using System;
+using Lesson06.Animals;
+using Lesson06.Devices;
+
+namespace Lesson06
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("=== 继承演示 ===\n");
+
+ // 继承:Dog 继承了 Animal
+ Dog dog = new Dog("旺财", "金毛");
+ dog.Eat();
+ dog.Speak();
+ dog.Info();
+
+ Console.WriteLine("\n=== 方法重写 ===\n");
+
+ // 多态:Cat 和 Dog 重写了 Speak
+ Animal cat = new Cat("小猫");
+ Animal dog2 = new Dog("二狗", "哈士奇");
+
+ cat.Speak();
+ dog2.Speak();
+
+ Console.WriteLine("\n=== 接口演示 ===\n");
+
+ // 使用接口
+ Microphone mic = new Microphone("USB麦克风");
+ Camera cam = new Camera("RTSP摄像头");
+
+ mic.Connect();
+ mic.Disconnect();
+
+ Console.WriteLine();
+
+ cam.Connect();
+ cam.Disconnect();
+
+ Console.WriteLine("\n=== 接口多态 ===\n");
+
+ // 接口类型可以指向任何实现它的类
+ IDevice device1 = new Microphone("设备A");
+ IDevice device2 = new Camera("设备B");
+
+ device1.Connect();
+ device2.Connect();
+
+ Console.WriteLine("\n=== 完成 ===");
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/lessons/Lesson07/Lesson07.csproj b/lessons/Lesson07/Lesson07.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/lessons/Lesson07/Lesson07.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/lessons/Lesson07/Program.cs b/lessons/Lesson07/Program.cs
new file mode 100644
index 0000000..889078e
--- /dev/null
+++ b/lessons/Lesson07/Program.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Collections.Generic;
+
+namespace Lesson07
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ // ========== List ==========
+ Console.WriteLine("=== List 动态数组 ===\n");
+
+ List transcriptHistory = new List();
+
+ // 添加识别结果
+ transcriptHistory.Add("今天天气真不错");
+ transcriptHistory.Add("大家一起加油");
+ transcriptHistory.Add("这个功能很简单");
+
+ Console.WriteLine($"共有 {transcriptHistory.Count} 条记录:");
+ foreach (string text in transcriptHistory)
+ {
+ Console.WriteLine($" - {text}");
+ }
+
+ // 插入
+ transcriptHistory.Insert(1, "新插入的文字");
+ Console.WriteLine($"\n插入后共有 {transcriptHistory.Count} 条记录:");
+ foreach (string text in transcriptHistory)
+ {
+ Console.WriteLine($" - {text}");
+ }
+
+ // 删除
+ transcriptHistory.Remove("大家一起加油");
+ Console.WriteLine($"\n删除后共有 {transcriptHistory.Count} 条记录");
+
+ // 初始化器
+ List fruits = new List() { "苹果", "香蕉", "橙子" };
+ Console.WriteLine($"\n水果列表:{string.Join(", ", fruits)}");
+
+ // ========== Dictionary ==========
+ Console.WriteLine("\n=== Dictionary 键值对 ===\n");
+
+ // 设备配置
+ Dictionary deviceConfig = new Dictionary()
+ {
+ ["name"] = "USB麦克风",
+ ["sampleRate"] = "16000",
+ ["channels"] = "1"
+ };
+
+ Console.WriteLine("设备配置:");
+ foreach (KeyValuePair kv in deviceConfig)
+ {
+ Console.WriteLine($" {kv.Key}: {kv.Value}");
+ }
+
+ // 访问单个值
+ Console.WriteLine($"\n设备名称: {deviceConfig["name"]}");
+
+ // 安全访问
+ if (deviceConfig.TryGetValue("notExist", out string value))
+ {
+ Console.WriteLine($"找到: {value}");
+ }
+ else
+ {
+ Console.WriteLine("键不存在");
+ }
+
+ // 设置选项
+ Dictionary settings = new Dictionary()
+ {
+ ["autoConnect"] = true,
+ ["vad"] = true,
+ ["debug"] = false
+ };
+
+ Console.WriteLine("\n设置选项:");
+ foreach (string key in settings.Keys)
+ {
+ string status = settings[key] ? "开启" : "关闭";
+ Console.WriteLine($" {key}: {status}");
+ }
+
+ // ========== 数字集合 ==========
+ Console.WriteLine("\n=== 数字 List 操作 ===\n");
+
+ List scores = new List() { 85, 92, 78, 95, 88 };
+
+ Console.WriteLine($"原始成绩:{string.Join(", ", scores)}");
+
+ scores.Sort();
+ Console.WriteLine($"排序后:{string.Join(", ", scores)}");
+
+ scores.Reverse();
+ Console.WriteLine($"反转后:{string.Join(", ", scores)}");
+
+ Console.WriteLine($"最高分:{scores[0]}");
+ Console.WriteLine($"包含 100? {scores.Contains(100)}");
+ Console.WriteLine($"包含 95? {scores.Contains(95)}");
+
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/lessons/Lesson08/Lesson08.csproj b/lessons/Lesson08/Lesson08.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/lessons/Lesson08/Lesson08.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/lessons/Lesson08/Program.cs b/lessons/Lesson08/Program.cs
new file mode 100644
index 0000000..24f7df1
--- /dev/null
+++ b/lessons/Lesson08/Program.cs
@@ -0,0 +1,187 @@
+using System;
+
+namespace Lesson08
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("=== 异常处理演示 ===\n");
+
+ // ========== 基本 try-catch ==========
+ Console.WriteLine("--- 基本 try-catch ---");
+ try
+ {
+ int[] numbers = { 1, 2, 3 };
+ Console.WriteLine(numbers[10]);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"捕获异常: {ex.Message}");
+ }
+
+ // ========== 捕获特定异常 ==========
+ Console.WriteLine("\n--- 捕获特定异常 ---");
+ string[] inputs = { "123", "abc", "9999999999999" };
+
+ foreach (string input in inputs)
+ {
+ try
+ {
+ int num = int.Parse(input);
+ Console.WriteLine($"转换成功: {num}");
+ }
+ catch (FormatException)
+ {
+ Console.WriteLine($"\"{input}\" 格式错误,不是数字");
+ }
+ catch (OverflowException)
+ {
+ Console.WriteLine($"\"{input}\" 数字太大");
+ }
+ }
+
+ // ========== throw 抛出异常 ==========
+ Console.WriteLine("\n--- throw 抛出异常 ---");
+ try
+ {
+ SetAge(-5);
+ }
+ catch (ArgumentException ex)
+ {
+ Console.WriteLine($"捕获到: {ex.Message}");
+ }
+
+ try
+ {
+ SetAge(200);
+ }
+ catch (ArgumentException ex)
+ {
+ Console.WriteLine($"捕获到: {ex.Message}");
+ }
+
+ SetAge(25); // 正常
+ SetAge(0); // 正常
+
+ // ========== 实际项目场景 ==========
+ Console.WriteLine("\n--- 设备连接场景 ---");
+ MicrophoneDevice mic = new MicrophoneDevice("USB麦克风");
+
+ // 场景1:设备未连接
+ try
+ {
+ mic.StartListening();
+ }
+ catch (DeviceNotConnectedException ex)
+ {
+ Console.WriteLine($"错误: {ex.Message}");
+ Console.WriteLine("建议:请检查设备连接");
+ }
+
+ // 场景2:连接后正常操作
+ mic.Connect();
+ try
+ {
+ mic.StartListening();
+ Console.WriteLine("麦克风开始监听...");
+ mic.StopListening();
+ Console.WriteLine("麦克风停止监听...");
+ }
+ catch (DeviceNotConnectedException ex)
+ {
+ Console.WriteLine($"错误: {ex.Message}");
+ }
+ finally
+ {
+ mic.Disconnect();
+ Console.WriteLine("设备已断开");
+ }
+
+ // ========== finally 演示 ==========
+ Console.WriteLine("\n--- finally 执行时机 ---");
+ try
+ {
+ Console.WriteLine("try 块执行");
+ // int x = 1 / 0; // 解开这行会跳到 catch
+ }
+ catch
+ {
+ Console.WriteLine("catch 块执行");
+ }
+ finally
+ {
+ Console.WriteLine("finally 块总是执行");
+ }
+
+ Console.WriteLine("\n=== 演示完成 ===");
+ Console.ReadLine();
+ }
+
+ // ========== throw 示例 ==========
+ static void SetAge(int age)
+ {
+ if (age < 0 || age > 150)
+ {
+ throw new ArgumentException($"年龄必须在 0-150 之间,当前: {age}");
+ }
+ Console.WriteLine($"年龄设置为: {age}");
+ }
+ }
+
+ // ========== 自定义异常 ==========
+ class DeviceNotConnectedException : Exception
+ {
+ public DeviceNotConnectedException(string message) : base(message) { }
+ public DeviceNotConnectedException(string message, Exception inner) : base(message, inner) { }
+ }
+
+ // ========== 设备类 ==========
+ class MicrophoneDevice
+ {
+ private string name;
+ private bool isConnected;
+ private bool isListening;
+
+ public MicrophoneDevice(string name)
+ {
+ this.name = name;
+ this.isConnected = false;
+ this.isListening = false;
+ }
+
+ public void Connect()
+ {
+ isConnected = true;
+ Console.WriteLine($"[{name}] 设备已连接");
+ }
+
+ public void Disconnect()
+ {
+ isConnected = false;
+ Console.WriteLine($"[{name}] 设备已断开");
+ }
+
+ public void StartListening()
+ {
+ if (!isConnected)
+ {
+ throw new DeviceNotConnectedException($"{name} 未连接,无法开始监听");
+ }
+ if (isListening)
+ {
+ throw new InvalidOperationException($"{name} 已经在监听中");
+ }
+ isListening = true;
+ }
+
+ public void StopListening()
+ {
+ if (!isListening)
+ {
+ throw new InvalidOperationException($"{name} 没有在监听");
+ }
+ isListening = false;
+ }
+ }
+}
diff --git a/lessons/Lesson09/Lesson09.csproj b/lessons/Lesson09/Lesson09.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/lessons/Lesson09/Lesson09.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/lessons/Lesson09/Program.cs b/lessons/Lesson09/Program.cs
new file mode 100644
index 0000000..89be971
--- /dev/null
+++ b/lessons/Lesson09/Program.cs
@@ -0,0 +1,103 @@
+using System;
+using System.IO;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Lesson09
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ string basePath = Directory.GetCurrentDirectory();
+ string testFile = Path.Combine(basePath, "test.txt");
+ string configFile = Path.Combine(basePath, "config.json");
+ string logFile = Path.Combine(basePath, "app.log");
+
+ Console.WriteLine("=== 文件读写演示 ===\n");
+
+ // ========== 写入文本文件 ==========
+ Console.WriteLine("--- 写入文本文件 ---");
+ string content = "第一行:无言势字幕\n第二行:VRChat 语音识别工具";
+ File.WriteAllText(testFile, content);
+ Console.WriteLine($"已写入: {testFile}");
+
+ // ========== 读取文本文件 ==========
+ Console.WriteLine("\n--- 读取文本文件 ---");
+ string readContent = File.ReadAllText(testFile);
+ Console.WriteLine("文件内容:");
+ Console.WriteLine(readContent);
+
+ // ========== 按行读写 ==========
+ Console.WriteLine("\n--- 按行读取 ---");
+ string[] lines = File.ReadAllLines(testFile);
+ for (int i = 0; i < lines.Length; i++)
+ {
+ Console.WriteLine($"行 {i + 1}: {lines[i]}");
+ }
+
+ // ========== JSON 配置 ==========
+ Console.WriteLine("\n--- JSON 配置读写 ---");
+
+ // 创建设置对象
+ AppSettings settings = new AppSettings
+ {
+ Sensitivity = 75,
+ AutoConnect = true,
+ VadEnabled = true,
+ Language = "zh-CN"
+ };
+
+ // 序列化为 JSON
+ string json = JsonSerializer.Serialize(settings, new JsonSerializerOptions
+ {
+ WriteIndented = true // 格式化输出
+ });
+ File.WriteAllText(configFile, json);
+ Console.WriteLine("已保存配置: config.json");
+ Console.WriteLine(json);
+
+ // 反序列化
+ string loadedJson = File.ReadAllText(configFile);
+ AppSettings loadedSettings = JsonSerializer.Deserialize(loadedJson);
+ Console.WriteLine("\n读取的配置:");
+ Console.WriteLine($" 灵敏度: {loadedSettings.Sensitivity}");
+ Console.WriteLine($" 自动连接: {loadedSettings.AutoConnect}");
+ Console.WriteLine($" VAD: {loadedSettings.VadEnabled}");
+ Console.WriteLine($" 语言: {loadedSettings.Language}");
+
+ // ========== 追加日志 ==========
+ Console.WriteLine("\n--- 追加日志 ---");
+ string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ string logEntry = $"[{timestamp}] 应用启动\n";
+ File.AppendAllText(logFile, logEntry);
+ Console.WriteLine($"已追加日志: {logFile}");
+
+ // ========== 文件操作 ==========
+ Console.WriteLine("\n--- 文件操作 ---");
+ Console.WriteLine($"文件是否存在: {File.Exists(testFile)}");
+ Console.WriteLine($"文件大小: {new FileInfo(testFile).Length} 字节");
+ Console.WriteLine($"完整路径: {Path.GetFullPath(testFile)}");
+ Console.WriteLine($"扩展名: {Path.GetExtension(testFile)}");
+
+ // ========== 清理 ==========
+ Console.WriteLine("\n--- 清理测试文件 ---");
+ if (File.Exists(testFile)) File.Delete(testFile);
+ if (File.Exists(configFile)) File.Delete(configFile);
+ if (File.Exists(logFile)) File.Delete(logFile);
+ Console.WriteLine("已删除测试文件");
+
+ Console.WriteLine("\n=== 演示完成 ===");
+ Console.ReadLine();
+ }
+ }
+
+ // ========== 配置类 ==========
+ class AppSettings
+ {
+ public int Sensitivity { get; set; } = 70;
+ public bool AutoConnect { get; set; } = true;
+ public bool VadEnabled { get; set; } = true;
+ public string Language { get; set; } = "zh-CN";
+ }
+}
diff --git a/lessons/Lesson10/Lesson10.csproj b/lessons/Lesson10/Lesson10.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/lessons/Lesson10/Lesson10.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/lessons/Lesson10/Program.cs b/lessons/Lesson10/Program.cs
new file mode 100644
index 0000000..4b5c2bf
--- /dev/null
+++ b/lessons/Lesson10/Program.cs
@@ -0,0 +1,136 @@
+using System;
+
+namespace Lesson10
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("=== 委托和事件演示 ===\n");
+
+ // ========== 委托 ==========
+ Console.WriteLine("--- 委托 ---");
+
+ // Action: 无返回值的委托
+ Action print = (msg) => Console.WriteLine($"打印: {msg}");
+ print("Hello World");
+
+ // Func: 有返回值的委托
+ Func add = (a, b) => a + b;
+ Func multiply = (a, b) => a * b;
+
+ Console.WriteLine($"add(3, 5) = {add(3, 5)}");
+ Console.WriteLine($"multiply(3, 5) = {multiply(3, 5)}");
+
+ // ========== 事件 ==========
+ Console.WriteLine("\n--- 事件 ---");
+
+ Microphone mic = new Microphone("USB麦克风");
+
+ // 订阅事件 - 收到文字时
+ mic.OnTranscriptReady += (text) =>
+ {
+ Console.WriteLine($"[UI更新] 显示文字: {text}");
+ };
+
+ // 订阅事件 - 开始监听
+ mic.OnListeningStarted += () =>
+ {
+ Console.WriteLine("[UI更新] 开始播放动画");
+ };
+
+ // 订阅事件 - 停止监听
+ mic.OnListeningStopped += () =>
+ {
+ Console.WriteLine("[UI更新] 停止动画");
+ };
+
+ // 订阅事件 - 错误处理
+ mic.OnError += (error) =>
+ {
+ Console.WriteLine($"[UI更新] 显示错误: {error}");
+ };
+
+ // ========== 模拟使用流程 ==========
+ Console.WriteLine("\n--- 模拟识别流程 ---");
+
+ // 正常流程
+ mic.StartListening();
+ mic.TranscriptDetected("今天天气真不错");
+ mic.TranscriptDetected("大家一起加油");
+ mic.StopListening();
+
+ Console.WriteLine();
+
+ // 模拟错误
+ mic.StartListening();
+ mic.SimulateError("设备断开连接");
+ mic.StopListening();
+
+ Console.WriteLine("\n=== 演示完成 ===");
+ Console.ReadLine();
+ }
+ }
+
+ // ========== 麦克风类(带事件) ==========
+ class Microphone
+ {
+ private string name;
+ private bool isListening;
+
+ // 事件声明
+ public event Action OnTranscriptReady; // 识别出文字
+ public event Action OnListeningStarted; // 开始监听
+ public event Action OnListeningStopped; // 停止监听
+ public event Action OnError; // 错误
+
+ public Microphone(string name)
+ {
+ this.name = name;
+ this.isListening = false;
+ }
+
+ public void StartListening()
+ {
+ if (isListening)
+ {
+ OnError?.Invoke("已经在监听中");
+ return;
+ }
+
+ isListening = true;
+ Console.WriteLine($"[{name}] 开始监听");
+ OnListeningStarted?.Invoke(); // 通知所有订阅者
+ }
+
+ public void StopListening()
+ {
+ if (!isListening)
+ {
+ return;
+ }
+
+ isListening = false;
+ Console.WriteLine($"[{name}] 停止监听");
+ OnListeningStopped?.Invoke(); // 通知所有订阅者
+ }
+
+ public void TranscriptDetected(string text)
+ {
+ if (!isListening)
+ {
+ return;
+ }
+
+ Console.WriteLine($"[{name}] 识别: {text}");
+ OnTranscriptReady?.Invoke(text); // 通知所有订阅者
+ }
+
+ // 模拟错误
+ public void SimulateError(string error)
+ {
+ Console.WriteLine($"[{name}] 错误: {error}");
+ OnError?.Invoke(error);
+ }
+ }
+}
diff --git a/lessons/Lesson_One/Lesson01_HelloWorld.cs b/lessons/Lesson_One/Lesson01_HelloWorld.cs
new file mode 100644
index 0000000..4b8a2d6
--- /dev/null
+++ b/lessons/Lesson_One/Lesson01_HelloWorld.cs
@@ -0,0 +1,24 @@
+// Lesson 01: Hello World
+// 目标:熟悉 C# 基本结构和输出
+
+using System;
+
+namespace CSharpLearning
+{
+ class Lesson01_HelloWorld
+ {
+ static void Main(string[] args)
+ {
+ // 打印 hello world
+ Console.WriteLine("Hello, World!");
+ Console.WriteLine("你好,C#!");
+
+ // 打印带格式
+ string name = "无言势字幕";
+ Console.WriteLine($"项目名称: {name}");
+
+ // 等待输入(防止窗口关闭)
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/lessons/Lesson_One/Lesson_One.csproj b/lessons/Lesson_One/Lesson_One.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/lessons/Lesson_One/Lesson_One.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/lessons/Lesson_One/Program.cs b/lessons/Lesson_One/Program.cs
new file mode 100644
index 0000000..d8a32d8
--- /dev/null
+++ b/lessons/Lesson_One/Program.cs
@@ -0,0 +1,67 @@
+using System;
+
+namespace Lesson_One
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ // ========== 变量 ==========
+ int age = 25;
+ double height = 175.5;
+ string name = "无言势字幕";
+ char grade = 'A';
+ bool isActive = true;
+
+ Console.WriteLine("=== 变量 ===");
+ Console.WriteLine($"姓名: {name}");
+ Console.WriteLine($"年龄: {age}");
+ Console.WriteLine($"身高: {height}cm");
+ Console.WriteLine($"等级: {grade}");
+ Console.WriteLine($"状态: {isActive}");
+
+ // ========== var 自动推断 ==========
+ Console.WriteLine("\n=== var 自动推断 ===");
+ var message = "这是 string 类型";
+ var number = 42; // 推断为 int
+ Console.WriteLine($"message 是: {message.GetType()}");
+ Console.WriteLine($"number 是: {number.GetType()}");
+
+ // ========== 常量 ==========
+ Console.WriteLine("\n=== 常量 ===");
+ const int MAX_RETRY = 3;
+ const string VERSION = "v1.0";
+ Console.WriteLine($"最大重试次数: {MAX_RETRY}");
+ Console.WriteLine($"版本: {VERSION}");
+
+ // ========== 类型转换 ==========
+ Console.WriteLine("\n=== 类型转换 ===");
+ int i = 10;
+ double d = i; // 隐式转换
+ Console.WriteLine($"int -> double: {d}");
+
+ double d2 = 3.14;
+ int i2 = (int)d2; // 显式转换
+ Console.WriteLine($"double -> int: {i2}");
+
+ string s = i.ToString();
+ Console.WriteLine($"int -> string: {s}");
+
+ int i3 = int.Parse("123");
+ Console.WriteLine($"string \"123\" -> int: {i3}");
+
+ // ========== 输入练习 ==========
+ Console.WriteLine("\n=== 输入练习 ===");
+ Console.Write("请输入你的名字: ");
+ string inputName = Console.ReadLine();
+ Console.Write($"你好, {inputName}! ");
+
+ Console.Write("请输入年龄: ");
+ string ageInput = Console.ReadLine();
+ int userAge = int.Parse(ageInput);
+ Console.WriteLine($"你 {userAge} 岁了");
+
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/notes/01_CSharp_Basics.md b/notes/01_CSharp_Basics.md
new file mode 100644
index 0000000..fe94937
--- /dev/null
+++ b/notes/01_CSharp_Basics.md
@@ -0,0 +1,46 @@
+# C# 基础入门
+
+## 环境确认
+
+- .NET SDK: `dotnet --version`
+- 编辑器: VS Code + C# Dev Kit (可选) 或 Rider
+
+## 常用命令
+
+```bash
+# 创建新项目
+dotnet new console -n MyProject
+
+# 运行
+dotnet run
+
+# 构建发布
+dotnet publish -c Release
+```
+
+## 基本结构
+
+```csharp
+using System;
+
+namespace MyProject
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Hello, World!");
+ }
+ }
+}
+```
+
+## 关键概念
+
+| 概念 | 说明 |
+|------|------|
+| `using` | 引入命名空间,类似 Python import |
+| `namespace` | 命名空间,防止命名冲突 |
+| `class` | 类,一切皆对象 |
+| `static void Main` | 程序入口点 |
+| `Console.WriteLine` | 输出到终端 |
diff --git a/notes/02_Variables_and_Types.md b/notes/02_Variables_and_Types.md
new file mode 100644
index 0000000..ba0be51
--- /dev/null
+++ b/notes/02_Variables_and_Types.md
@@ -0,0 +1,62 @@
+# 第二课:变量和数据类型
+
+## 基本数据类型
+
+| 类型 | 说明 | 示例 |
+|------|------|------|
+| `int` | 整数 | `int age = 25;` |
+| `double` | 小数 | `double pi = 3.14;` |
+| `string` | 字符串 | `string name = "无言势";` |
+| `char` | 单字符 | `char grade = 'A';` |
+| `bool` | 布尔值 | `bool isActive = true;` |
+| `var` | 自动推断 | `var msg = "自动推断为string";` |
+
+## 声明和赋值
+
+```csharp
+// 声明 + 赋值
+int score = 100;
+
+// 先声明,后赋值
+int score;
+score = 100;
+
+// 多个变量
+int a = 1, b = 2, c = 3;
+```
+
+## 常量
+
+```csharp
+const double PI = 3.14159; // const 声明后不可修改
+```
+
+## 类型转换
+
+```csharp
+// 隐式转换(自动)
+int i = 10;
+double d = i; // int -> double
+
+// 显式转换(强制)
+double d = 3.14;
+int i = (int)d; // double -> int,结果是 3
+
+// ToString / Parse
+int i = int.Parse("123");
+string s = i.ToString();
+```
+
+## 输入输出
+
+```csharp
+// 输出
+Console.WriteLine("Hello"); // 换行
+Console.Write("Hello"); // 不换行
+
+// 输入(返回 string)
+string name = Console.ReadLine();
+
+// 输入数字要转换
+int age = int.Parse(Console.ReadLine());
+```
diff --git a/notes/03_Conditions_and_Loops.md b/notes/03_Conditions_and_Loops.md
new file mode 100644
index 0000000..8354106
--- /dev/null
+++ b/notes/03_Conditions_and_Loops.md
@@ -0,0 +1,102 @@
+# 第三课:条件判断和循环
+
+## if / else 判断
+
+```csharp
+int score = 85;
+
+if (score >= 90)
+{
+ Console.WriteLine("优秀");
+}
+else if (score >= 60)
+{
+ Console.WriteLine("及格");
+}
+else
+{
+ Console.WriteLine("不及格");
+}
+
+// 三元运算符(简单判断)
+string result = score >= 60 ? "及格" : "不及格";
+```
+
+## switch 选择
+
+```csharp
+int day = 3;
+
+switch (day)
+{
+ case 1:
+ Console.WriteLine("星期一");
+ break;
+ case 2:
+ Console.WriteLine("星期二");
+ break;
+ case 3:
+ Console.WriteLine("星期三");
+ break;
+ default:
+ Console.WriteLine("其他");
+ break;
+}
+```
+
+## for 循环
+
+```csharp
+// 传统 for
+for (int i = 0; i < 5; i++)
+{
+ Console.WriteLine(i);
+}
+
+// 遍历数组
+string[] names = { "A", "B", "C" };
+for (int i = 0; i < names.Length; i++)
+{
+ Console.WriteLine(names[i]);
+}
+```
+
+## foreach 循环(更简洁)
+
+```csharp
+string[] names = { "A", "B", "C" };
+
+foreach (string name in names)
+{
+ Console.WriteLine(name);
+}
+```
+
+## while 循环
+
+```csharp
+int i = 0;
+while (i < 5)
+{
+ Console.WriteLine(i);
+ i++;
+}
+
+// 先执行再判断
+do
+{
+ Console.WriteLine(i);
+ i++;
+} while (i < 5);
+```
+
+## break 和 continue
+
+```csharp
+for (int i = 0; i < 10; i++)
+{
+ if (i == 3) continue; // 跳过 i=3
+ if (i == 7) break; // 退出循环
+ Console.WriteLine(i);
+}
+```
diff --git a/notes/04_Methods_and_Classes.md b/notes/04_Methods_and_Classes.md
new file mode 100644
index 0000000..65452bf
--- /dev/null
+++ b/notes/04_Methods_and_Classes.md
@@ -0,0 +1,91 @@
+# 第四课:方法(函数)和类
+
+## 方法(函数)
+
+```csharp
+// 无返回值
+void SayHello(string name)
+{
+ Console.WriteLine($"你好, {name}");
+}
+
+// 有返回值
+int Add(int a, int b)
+{
+ return a + b;
+}
+
+// 带默认参数
+void Greet(string name = "World")
+{
+ Console.WriteLine($"Hello, {name}");
+}
+```
+
+## 方法调用
+
+```csharp
+static void Main(string[] args)
+{
+ SayHello("无言势"); // 调用无返回值方法
+ int sum = Add(1, 2); // 调用有返回值方法
+ Console.WriteLine(sum); // 输出 3
+}
+```
+
+## 类(Class)
+
+```csharp
+class Person
+{
+ // 字段(属性)
+ public string name;
+ public int age;
+
+ // 构造函数
+ public Person(string name, int age)
+ {
+ this.name = name;
+ this.age = age;
+ }
+
+ // 方法
+ public void SayHi()
+ {
+ Console.WriteLine($"我是{name},今年{age}岁");
+ }
+}
+```
+
+## 创建对象
+
+```csharp
+static void Main(string[] args)
+{
+ Person p = new Person("无言势", 25);
+ p.SayHi();
+}
+```
+
+## 访问修饰符
+
+| 修饰符 | 访问范围 |
+|--------|----------|
+| `public` | 任何地方都能访问 |
+| `private` | 只有本类内部能访问 |
+| `internal` | 同程序集内访问 |
+
+## 静态(static)
+
+```csharp
+class MathHelper
+{
+ public static int Add(int a, int b)
+ {
+ return a + b;
+ }
+}
+
+// 调用不需要 new
+int result = MathHelper.Add(1, 2);
+```
diff --git a/notes/05_MultiFile_and_Access_Modifiers.md b/notes/05_MultiFile_and_Access_Modifiers.md
new file mode 100644
index 0000000..86f671c
--- /dev/null
+++ b/notes/05_MultiFile_and_Access_Modifiers.md
@@ -0,0 +1,114 @@
+# 第五课:多文件项目和访问修饰符
+
+## 多文件项目结构
+
+```
+Lesson05/
+├── Program.cs // 入口,只管 Main
+├── Models/
+│ ├── Person.cs // 数据模型
+│ └── Microphone.cs // 麦克风类
+├── Helpers/
+│ └── MathHelper.cs // 工具类
+└── Services/
+ └── AudioService.cs // 服务类
+```
+
+**关键规则**:
+- 同一项目内,所有 `.cs` 文件自动互相可见(不需要 import)
+- 用文件夹组织,但编译时所有文件合并成一个程序集
+
+## public vs private 核心区别
+
+| 修饰符 | 类内访问 | 类外访问 | 继承访问 |
+|--------|----------|----------|----------|
+| `public` | ✓ | ✓ | ✓ |
+| `private` | ✓ | ✗ | ✗ |
+
+```csharp
+class Person
+{
+ public string name; // 任何地方都能读写
+ private int age; // 只有 Person 内部能访问
+ private string secret; // 外部无法访问
+
+ public void SetAge(int age)
+ {
+ // 公有方法内部可以访问私有字段
+ if (age > 0 && age < 150)
+ this.age = age;
+ }
+
+ public int GetAge()
+ {
+ return this.age; // 通过方法间接访问
+ }
+}
+```
+
+```csharp
+// Program.cs
+Person p = new Person("无言势");
+p.name = "新名字"; // OK,public
+p.age = 25; // 编译错误,private
+p.SetAge(25); // OK,通过公有方法
+```
+
+## 为什么要 private?
+
+**数据保护**:防止无效值
+
+```csharp
+private int age;
+
+// 外部不能直接 age = -100
+// 必须通过方法验证后设置
+public void SetAge(int age)
+{
+ if (age < 0) age = 0;
+ if (age > 150) age = 150;
+ this.age = age;
+}
+```
+
+**封装**:内部实现可以随时改,不影响外部
+
+```csharp
+// 内部存储从 int 改成 DateTime 都可以
+// 只要 public 方法签名不变,外部代码不用改
+```
+
+## 其他访问修饰符
+
+| 修饰符 | 说明 |
+|--------|------|
+| `public` | 完全公开 |
+| `private` | 仅本类 |
+| `protected` | 本类 + 子类 |
+| `internal` | 同项目内 |
+
+## 属性(Property)- 介于 public/private 之间
+
+```csharp
+class Person
+{
+ private int _age;
+
+ public int Age
+ {
+ get { return _age; } // 读取
+ set
+ {
+ if (value < 0) value = 0; // 写入时验证
+ if (value > 150) value = 150;
+ _age = value;
+ }
+ }
+}
+```
+
+```csharp
+Person p = new Person();
+p.Age = 25; // 自动调用 set
+int a = p.Age; // 自动调用 get
+```
diff --git a/notes/06_Inheritance_and_Interface.md b/notes/06_Inheritance_and_Interface.md
new file mode 100644
index 0000000..21fc35d
--- /dev/null
+++ b/notes/06_Inheritance_and_Interface.md
@@ -0,0 +1,191 @@
+# 第六课:继承和接口
+
+## 继承(Inheritance)
+
+子类继承父类的属性和方法,避免重复代码。
+
+```csharp
+// 父类
+class Animal
+{
+ public string name;
+ public void Eat()
+ {
+ Console.WriteLine($"{name} 在吃东西");
+ }
+}
+
+// 子类
+class Dog : Animal
+{
+ public void Bark()
+ {
+ Console.WriteLine($"{name} 在叫: 汪汪!");
+ }
+}
+```
+
+```csharp
+Dog dog = new Dog();
+dog.name = "旺财";
+dog.Eat(); // 继承自 Animal
+dog.Bark(); // 自己独有的
+```
+
+## 方法重写(override)
+
+```csharp
+// 父类 virtual 方法
+class Animal
+{
+ public string name;
+ public virtual void Speak()
+ {
+ Console.WriteLine($"{name} 发出了声音");
+ }
+}
+
+// 子类重写
+class Cat : Animal
+{
+ public override void Speak()
+ {
+ Console.WriteLine($"{name} 喵喵喵~");
+ }
+}
+```
+
+```csharp
+Animal a = new Cat();
+a.name = "小猫";
+a.Speak(); // 输出: 小猫 喵喵喵~
+```
+
+## base 关键字
+
+子类调用父类的方法/构造函数:
+
+```csharp
+class Dog : Animal
+{
+ public string breed;
+
+ public Dog(string name, string breed) : base(name)
+ {
+ this.breed = breed;
+ }
+
+ public override void Speak()
+ {
+ base.Speak(); // 先调用父类方法
+ Console.WriteLine($"{name} 汪汪!");
+ }
+}
+```
+
+## 访问修饰符 protected
+
+| 修饰符 | 任何地方 | 继承访问 |
+|--------|----------|----------|
+| `private` | ✗ | ✗ |
+| `protected` | ✗ | ✓ |
+
+```csharp
+class Animal
+{
+ protected string name; // private 的话子类也访问不到
+}
+
+class Dog : Animal
+{
+ public void Test()
+ {
+ name = "旺财"; // protected 可以访问
+ }
+}
+```
+
+## 接口(Interface)
+
+接口 = 约定/契约,定义必须实现的方法。
+
+```csharp
+// 定义接口
+interface IFlyable
+{
+ void Fly(); // 不写实现
+ int MaxAltitude { get; } // 可以有属性
+}
+
+// 实现接口
+class Bird : IFlyable
+{
+ public int MaxAltitude => 1000;
+
+ public void Fly()
+ {
+ Console.WriteLine("鸟儿在飞翔");
+ }
+}
+
+class Plane : IFlyable
+{
+ public int MaxAltitude => 10000;
+
+ public void Fly()
+ {
+ Console.WriteLine("飞机在飞翔");
+ }
+}
+```
+
+## 接口 vs 继承
+
+| | 继承 | 接口 |
+|---|---|---|
+| 关键词 | `class A : B` | `class A : IB` |
+| 只能继承一个父类 | ✓ | 可以实现多个接口 |
+| 继承获得代码 | ✓ | 只获得"约定" |
+| 何时用 | 代码复用 | 约定行为 |
+
+```csharp
+// 一个类只能继承一个父类
+class Dog : Animal { }
+
+// 但可以实现多个接口
+class Duck : Animal, IFlyable, ISwimable
+{
+ public void Fly() { }
+ public void Swim() { }
+}
+```
+
+## 例子:设备驱动架构
+
+```csharp
+// 设备接口
+interface IDevice
+{
+ void Connect();
+ void Disconnect();
+ bool IsConnected { get; }
+}
+
+// 麦克风设备
+class Microphone : IDevice
+{
+ public bool IsConnected { get; private set; }
+
+ public void Connect()
+ {
+ Console.WriteLine("麦克风连接");
+ IsConnected = true;
+ }
+
+ public void Disconnect()
+ {
+ Console.WriteLine("麦克风断开");
+ IsConnected = false;
+ }
+}
+```
diff --git a/notes/07_Collections.md b/notes/07_Collections.md
new file mode 100644
index 0000000..f6323cd
--- /dev/null
+++ b/notes/07_Collections.md
@@ -0,0 +1,135 @@
+# 第七课:集合(List / Dictionary)
+
+## List 动态数组
+
+`T` 是泛型,占位符,使用时替换成具体类型。
+
+```csharp
+using System.Collections.Generic;
+
+// 声明
+List names = new List();
+
+// 添加
+names.Add("无言势");
+names.Add("字幕");
+names.Add("工具");
+
+// 插入(指定位置)
+names.Insert(1, "新插入");
+
+// 删除
+names.Remove("字幕");
+names.RemoveAt(0); // 按索引删除
+
+// 访问
+string first = names[0];
+
+// 数量
+int count = names.Count;
+
+// 遍历
+foreach (string name in names)
+{
+ Console.WriteLine(name);
+}
+```
+
+## 初始化器
+
+```csharp
+// 声明时直接填充
+List fruits = new List()
+{
+ "苹果", "香蕉", "橙子"
+};
+
+// 简写(C# 12+)
+List fruits2 = ["苹果", "香蕉", "橙子"];
+```
+
+## 常用方法
+
+```csharp
+List numbers = new List() { 3, 1, 4, 1, 5 };
+
+numbers.Sort(); // 排序
+numbers.Reverse(); // 反转
+numbers.Contains(5); // 是否包含
+numbers.IndexOf(4); // 查找索引
+numbers.Clear(); // 清空
+numbers.InsertRange(0, ...); // 插入集合
+```
+
+## Dictionary 键值对
+
+```csharp
+using System.Collections.Generic;
+
+// 声明
+Dictionary scores = new Dictionary();
+
+// 添加
+scores["无言势"] = 100;
+scores["玩家A"] = 85;
+scores.Add("玩家B", 90);
+
+// 访问
+int score = scores["无言势"]; // 100
+
+// 安全访问(键不存在不报错)
+scores.TryGetValue("不存在", out int value);
+
+// 是否包含键
+if (scores.ContainsKey("无言势"))
+{
+ Console.WriteLine(scores["无言势"]);
+}
+
+// 删除
+scores.Remove("玩家A");
+
+// 遍历
+foreach (KeyValuePair kv in scores)
+{
+ Console.WriteLine($"{kv.Key}: {kv.Value}");
+}
+
+// 只遍历键或值
+foreach (string key in scores.Keys) { }
+foreach (int value in scores.Values) { }
+```
+
+## Dictionary 初始化
+
+```csharp
+// C# 6+
+Dictionary config = new Dictionary()
+{
+ ["sensitivity"] = 70,
+ ["volume"] = 80,
+ ["language"] = 1
+};
+```
+
+## List 和 Dictionary 在项目中的应用
+
+```csharp
+// 识别结果历史
+List transcriptHistory = new List();
+
+// 设备配置
+Dictionary deviceConfig = new Dictionary()
+{
+ ["name"] = "USB麦克风",
+ ["sampleRate"] = "16000",
+ ["channels"] = "1"
+};
+
+// 设置选项
+Dictionary settings = new Dictionary()
+{
+ ["autoConnect"] = true,
+ ["vad"] = true
+};
+```
diff --git a/notes/08_Exception_Handling.md b/notes/08_Exception_Handling.md
new file mode 100644
index 0000000..b1553fb
--- /dev/null
+++ b/notes/08_Exception_Handling.md
@@ -0,0 +1,164 @@
+# 第八课:异常处理
+
+## 什么是异常
+
+异常 = 程序运行时的错误,导致程序无法正常继续。
+
+```csharp
+int[] numbers = { 1, 2, 3 };
+int x = numbers[10]; // 索引越界 → 抛出 IndexOutOfRangeException
+```
+
+## try / catch / finally
+
+```csharp
+try
+{
+ // 可能出错的代码放这里
+ int[] numbers = { 1, 2, 3 };
+ int x = numbers[10];
+}
+catch (Exception ex)
+{
+ // 捕获异常并处理
+ Console.WriteLine($"出错了: {ex.Message}");
+}
+finally
+{
+ // 无论是否出错,都会执行(通常放清理代码)
+ Console.WriteLine("无论怎样都会执行");
+}
+```
+
+## 捕获特定异常类型
+
+```csharp
+try
+{
+ int a = int.Parse("abc"); // 格式错误
+}
+catch (FormatException ex)
+{
+ Console.WriteLine("格式错误");
+}
+catch (OverflowException ex)
+{
+ Console.WriteLine("数字溢出");
+}
+catch (Exception ex)
+{
+ Console.WriteLine($"未知错误: {ex.Message}");
+}
+```
+
+## 常见异常类型
+
+| 异常类型 | 触发场景 |
+|----------|----------|
+| `FormatException` | 格式错误(`int.Parse("abc")`) |
+| `NullReferenceException` | 空对象访问(`obj.Method()`,`obj` 为 null) |
+| `IndexOutOfRangeException` | 数组越界 |
+| `FileNotFoundException` | 文件不存在 |
+| `DivideByZeroException` | 除数为零 |
+| `InvalidOperationException` | 操作无效状态 |
+
+## throw 抛出异常
+
+```csharp
+static void SetAge(int age)
+{
+ if (age < 0 || age > 150)
+ {
+ throw new ArgumentException("年龄必须在 0-150 之间");
+ }
+ Console.WriteLine($"年龄设置为: {age}");
+}
+```
+
+```csharp
+try
+{
+ SetAge(-5);
+}
+catch (ArgumentException ex)
+{
+ Console.WriteLine($"参数错误: {ex.Message}");
+}
+```
+
+## 自定义异常
+
+```csharp
+class MicrophoneException : Exception
+{
+ public MicrophoneException(string message) : base(message) { }
+ public MicrophoneException(string message, Exception inner) : base(message, inner) { }
+}
+```
+
+## finally 的作用
+
+```csharp
+FileStream file = null;
+try
+{
+ file = new FileStream("test.txt", FileMode.Open);
+ // 读取文件...
+}
+catch (FileNotFoundException ex)
+{
+ Console.WriteLine("文件不存在");
+}
+finally
+{
+ // 确保文件被关闭
+ file?.Close();
+}
+```
+
+## using 语句(更简洁)
+
+```csharp
+// using 自动释放资源(相当于 try-finally)
+using (FileStream file = new FileStream("test.txt", FileMode.Open))
+{
+ // 使用 file
+} // 作用域结束后自动 Close()
+```
+
+## 实际项目应用
+
+```csharp
+try
+{
+ // 尝试连接麦克风
+ microphone.Connect();
+}
+catch (DeviceNotFoundException ex)
+{
+ Console.WriteLine("麦克风未找到,请检查连接");
+ ShowReconnectDialog();
+}
+catch (UnauthorizedAccessException ex)
+{
+ Console.WriteLine("没有权限访问麦克风");
+ RequestPermission();
+}
+catch (Exception ex)
+{
+ Console.WriteLine($"未知错误: {ex.Message}");
+ LogError(ex);
+}
+```
+
+## 不要过度捕获异常
+
+```csharp
+// ✗ 不好:捕获所有异常但不处理
+try { DoSomething(); }
+catch { }
+
+// ✓ 好:只捕获能处理的异常
+try { Connect(); }
+catch (DeviceNotFoundException ex) { ShowError(); }
+```
diff --git a/notes/09_File_IO.md b/notes/09_File_IO.md
new file mode 100644
index 0000000..45eaeeb
--- /dev/null
+++ b/notes/09_File_IO.md
@@ -0,0 +1,150 @@
+# 第九课:文件读写
+
+## 基本文件操作
+
+```csharp
+using System.IO;
+
+// 写入文本
+File.WriteAllText("test.txt", "你好,无言势字幕");
+
+// 读取文本
+string content = File.ReadAllText("test.txt");
+```
+
+## 路径操作
+
+```csharp
+// 路径拼接
+string path = Path.Combine("C:", "Users", "test", "config.json");
+
+// 获取扩展名
+string ext = Path.GetExtension("test.txt"); // ".txt"
+
+// 获取文件名
+string name = Path.GetFileName("C:/test/test.txt"); // "test.txt"
+
+// 判断文件是否存在
+bool exists = File.Exists("config.json");
+```
+
+## 读取文件
+
+```csharp
+// 方式1:一次性读取(适合小文件)
+string content = File.ReadAllText("test.txt");
+
+// 方式2:按行读取
+string[] lines = File.ReadAllLines("test.txt");
+foreach (string line in lines)
+{
+ Console.WriteLine(line);
+}
+
+// 方式3:流式读取(大文件)
+using (StreamReader reader = new StreamReader("test.txt"))
+{
+ while (!reader.EndOfStream)
+ {
+ string line = reader.ReadLine();
+ Console.WriteLine(line);
+ }
+}
+```
+
+## 写入文件
+
+```csharp
+// 方式1:一次性写入
+File.WriteAllText("output.txt", "内容");
+
+// 方式2:按行写入
+string[] lines = { "第一行", "第二行", "第三行" };
+File.WriteAllLines("output.txt", lines);
+
+// 方式3:追加内容
+File.AppendAllText("log.txt", "新追加的内容\n");
+
+// 方式4:流式写入
+using (StreamWriter writer = new StreamWriter("output.txt"))
+{
+ writer.WriteLine("第一行");
+ writer.WriteLine("第二行");
+}
+```
+
+## JSON 序列化
+
+.NET 内置 JSON 支持(System.Text.Json):
+
+```csharp
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+// 序列化(对象 -> JSON)
+class Person
+{
+ public string Name { get; set; }
+ public int Age { get; set; }
+}
+
+Person p = new Person { Name = "无言势", Age = 25 };
+string json = JsonSerializer.Serialize(p);
+Console.WriteLine(json);
+// 输出: {"Name":"无言势","Age":25}
+
+// 反序列化(JSON -> 对象)
+string jsonStr = "{\"Name\":\"玩家A\",\"Age\":30}";
+Person p2 = JsonSerializer.Deserialize(jsonStr);
+Console.WriteLine(p2.Name); // "玩家A"
+```
+
+## 配置文件示例
+
+```csharp
+// AppSettings 类
+class AppSettings
+{
+ public int Sensitivity { get; set; } = 70;
+ public bool AutoConnect { get; set; } = true;
+ public bool VadEnabled { get; set; } = true;
+ public string Language { get; set; } = "zh-CN";
+}
+
+// 保存配置
+AppSettings settings = new AppSettings();
+string json = JsonSerializer.Serialize(settings, new JsonSerializerOptions { WriteIndented = true });
+File.WriteAllText("config.json", json);
+
+// 读取配置
+string loaded = File.ReadAllText("config.json");
+AppSettings loadedSettings = JsonSerializer.Deserialize(loaded);
+```
+
+## using 语句自动关闭
+
+```csharp
+// StreamReader/Writer 必须关闭,否则文件被锁定
+using (StreamReader reader = new StreamReader("test.txt"))
+{
+ string line = reader.ReadLine();
+}
+// 作用域结束后自动 Close()
+```
+
+## 常见错误处理
+
+```csharp
+try
+{
+ string content = File.ReadAllText("notexist.txt");
+}
+catch (FileNotFoundException)
+{
+ Console.WriteLine("文件不存在");
+}
+catch (IOException ex)
+{
+ Console.WriteLine($"IO错误: {ex.Message}");
+}
+```
diff --git a/notes/10_Delegates_and_Events.md b/notes/10_Delegates_and_Events.md
new file mode 100644
index 0000000..7046f33
--- /dev/null
+++ b/notes/10_Delegates_and_Events.md
@@ -0,0 +1,182 @@
+# 第十课:委托和事件
+
+## 委托(Delegate)是什么
+
+委托 = 函数的"容器",可以把函数当作变量传递。
+
+```csharp
+// 声明委托类型
+delegate int Calculator(int a, int b);
+
+// 定义符合委托的方法
+int Add(int a, int b) => a + b;
+int Multiply(int a, int b) => a * b;
+
+// 使用委托
+Calculator calc = Add;
+int result = calc(1, 2); // result = 3
+
+calc = Multiply;
+result = calc(3, 4); // result = 12
+```
+
+## 为什么需要委托
+
+```csharp
+// 场景:数组遍历时对每个元素做操作
+void ProcessNumbers(int[] numbers, ??? operation)
+{
+ foreach (int n in numbers)
+ {
+ ??? result = operation(n);
+ Console.WriteLine(result);
+ }
+}
+
+// 没有委托,你需要写多个重载
+// 有委托,可以传任意操作
+ProcessNumbers(nums, x => x * 2); // 翻倍
+ProcessNumbers(nums, x => x + 1); // +1
+ProcessNumbers(nums, x => x * x); // 平方
+```
+
+## Action 和 Func(简化委托)
+
+```csharp
+// Action: 返回 void 的委托
+Action print = (msg) => Console.WriteLine(msg);
+print("Hello"); // 无返回值
+
+// Func: 有返回值的委托
+Func add = (a, b) => a + b;
+int result = add(1, 2); // 3
+
+// 多参数
+Func concat = (a, b) => a + b;
+string s = concat("Hello", " World"); // "Hello World"
+```
+
+## 事件(Event)是什么
+
+事件 = 委托的升级版,只能 += 添加监听,不能外部直接调用。
+
+```csharp
+class Button
+{
+ // 事件声明
+ public event Action Clicked;
+
+ public void OnClick()
+ {
+ Console.WriteLine("按钮被点击");
+ // 触发事件(只能在类内部)
+ Clicked?.Invoke();
+ }
+}
+```
+
+```csharp
+// 使用事件
+Button btn = new Button();
+
+// 添加监听者
+btn.Clicked += () => Console.WriteLine("Handler 1 执行");
+btn.Clicked += () => Console.WriteLine("Handler 2 执行");
+
+btn.OnClick();
+// 输出:
+// 按钮被点击
+// Handler 1 执行
+// Handler 2 执行
+```
+
+## 事件 + 委托的应用场景
+
+```csharp
+class Microphone
+{
+ // 事件声明
+ public event Action OnTranscriptReady; // 识别出文字时触发
+ public event Action OnListeningStarted;
+ public event Action OnListeningStopped;
+
+ private bool isListening;
+
+ public void StartListening()
+ {
+ isListening = true;
+ Console.WriteLine("麦克风开始监听...");
+ OnListeningStarted?.Invoke();
+ }
+
+ public void StopListening()
+ {
+ isListening = false;
+ Console.WriteLine("麦克风停止监听...");
+ OnListeningStopped?.Invoke();
+ }
+
+ // 模拟识别到文字
+ public void TranscriptDetected(string text)
+ {
+ Console.WriteLine($"识别到: {text}");
+ OnTranscriptReady?.Invoke(text); // 触发事件,通知所有监听者
+ }
+}
+```
+
+```csharp
+// 使用
+Microphone mic = new Microphone();
+
+// 订阅事件
+mic.OnTranscriptReady += (text) =>
+{
+ Console.WriteLine($"收到文字: {text}");
+};
+
+mic.OnListeningStarted += () =>
+{
+ Console.WriteLine("开始记录...");
+};
+
+mic.OnListeningStopped += () =>
+{
+ Console.WriteLine("停止记录");
+};
+
+// 触发
+mic.StartListening();
+mic.TranscriptDetected("今天天气不错");
+mic.TranscriptDetected("大家一起加油");
+mic.StopListening();
+```
+
+## 事件 vs 委托
+
+| | 委托 | 事件 |
+|---|---|---|
+| 外部添加监听 | ✓ | ✓ |
+| 外部调用 | ✓ | ✗ |
+| 主要用途 | 传递函数 | 通知机制 |
+
+## 移除监听
+
+```csharp
+Action handler = () => Console.WriteLine("Handler");
+
+btn.Clicked += handler;
+btn.Clicked -= handler; // 移除
+```
+
+## 实际项目结构
+
+```
+语音识别服务
+ ├── OnTranscriptReady(text) → UI 更新文字
+ ├── OnListeningStarted() → UI 显示监听状态
+ ├── OnListeningStopped() → UI 停止动画
+ └── OnError(error) → UI 显示错误
+```
+
+事件让各部分解耦,不需要互相引用。
diff --git a/notes/11_WebView2_Basics.md b/notes/11_WebView2_Basics.md
new file mode 100644
index 0000000..0010f00
--- /dev/null
+++ b/notes/11_WebView2_Basics.md
@@ -0,0 +1,121 @@
+# WebView2 入门
+
+## 什么是 WebView2
+
+在 Windows 桌面应用里嵌入 Chrome 内核浏览器。
+
+```
+┌─────────────────────────┐
+│ WPF / WinForms │
+│ ┌───────────────────┐ │
+│ │ WebView2 │ │
+│ │ (Chrome 内核) │ │
+│ │ │ │
+│ │ ┌─────────────┐ │ │
+│ │ │ HTML/CSS/JS │ │ │
+│ │ │ 你的界面 │ │ │
+│ │ └─────────────┘ │ │
+│ └───────────────────┘ │
+│ │
+│ C# 代码 │
+└─────────────────────────┘
+```
+
+## 安装 WebView2 Runtime
+
+下载地址:https://developer.microsoft.com/en-us/microsoft-edge/webview2/
+
+## NuGet 包
+
+```bash
+dotnet add package Microsoft.Web.WebView2
+```
+
+## XAML 使用
+
+```xml
+
+
+
+
+
+```
+
+## 初始化
+
+```csharp
+private async void InitializeWebView()
+{
+ await WebView.EnsureCoreWebView2Async();
+ Console.WriteLine("WebView2 初始化成功");
+}
+```
+
+## C# 调用 JS
+
+```csharp
+// 执行 JS
+await WebView.ExecuteScriptAsync("alert('Hello from C#')");
+
+// 获取返回值
+string result = await WebView.ExecuteScriptAsync("document.title");
+```
+
+## JS 调用 C#
+
+```csharp
+// C# 注册方法
+WebView.CoreWebView2.WebMessageReceived += (s, e) =>
+{
+ string message = e.TryGetWebMessageAsString();
+ Console.WriteLine($"收到JS消息: {message}");
+};
+```
+
+```javascript
+// JS 发送消息
+window.chrome.webview.postMessage("Hello from JS");
+```
+
+## 常用操作
+
+```csharp
+WebView.Reload(); // 刷新
+WebView.GoBack(); // 后退
+WebView.GoForward(); // 前进
+WebView.Navigate("https://..."); // 导航到 URL
+WebView.CoreWebView2.Settings // 配置
+```
+
+## 本地 HTML
+
+```csharp
+// 加载本地 HTML 文件
+string htmlPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "index.html");
+WebView.CoreWebView2.Navigate(new Uri(htmlPath).AbsoluteUri);
+
+// 或者直接加载 HTML 字符串
+string html = "Hello
";
+WebView.NavigateToString(html);
+```
+
+## 项目里怎么用
+
+```
+无言势字幕/
+├── MainWindow.xaml ← WPF 窗口,放 WebView2
+├── index.html ← 你的界面(HTML/CSS/JS)
+├── WebViewManager.cs ← C# 和 JS 通信
+└── AsrService.cs ← 语音识别服务
+```
+
+C# 负责:
+- 语音识别(Sherpa-ONNX)
+- OSC 发送
+- 窗口管理
+
+HTML/JS 负责:
+- 界面显示
+- 动画效果
+- 用户交互
diff --git a/notes/PDF/01_CSharp_Basics.pdf b/notes/PDF/01_CSharp_Basics.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..5c9aa60f8e65a5f02339a99110d4d797eaf9b3b2
GIT binary patch
literal 183250
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