commit f604d5319156c60d09fef25b258824ffe28774b6
Author: Rosmontis_Cloud <2451830085@qq.com>
Date: Wed Jul 1 16:31:35 2026 +0800
Initial commit: C# 学习笔记和示例代码
- Lesson 01-10: C# 基础语法
- WebView2: 集成示例
- notes/: 详细笔记
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 0000000..5c9aa60
Binary files /dev/null and b/notes/PDF/01_CSharp_Basics.pdf differ
diff --git a/notes/PDF/02_Variables_and_Types.pdf b/notes/PDF/02_Variables_and_Types.pdf
new file mode 100644
index 0000000..2022458
Binary files /dev/null and b/notes/PDF/02_Variables_and_Types.pdf differ
diff --git a/notes/PDF/03_Conditions_and_Loops.pdf b/notes/PDF/03_Conditions_and_Loops.pdf
new file mode 100644
index 0000000..a9b93ee
Binary files /dev/null and b/notes/PDF/03_Conditions_and_Loops.pdf differ
diff --git a/notes/PDF/04_Methods_and_Classes.pdf b/notes/PDF/04_Methods_and_Classes.pdf
new file mode 100644
index 0000000..89580fb
Binary files /dev/null and b/notes/PDF/04_Methods_and_Classes.pdf differ
diff --git a/notes/PDF/05_MultiFile_and_Access_Modifiers.pdf b/notes/PDF/05_MultiFile_and_Access_Modifiers.pdf
new file mode 100644
index 0000000..cd5cf75
Binary files /dev/null and b/notes/PDF/05_MultiFile_and_Access_Modifiers.pdf differ
diff --git a/notes/PDF/06_Inheritance_and_Interface.pdf b/notes/PDF/06_Inheritance_and_Interface.pdf
new file mode 100644
index 0000000..50e53fa
Binary files /dev/null and b/notes/PDF/06_Inheritance_and_Interface.pdf differ
diff --git a/notes/PDF/07_Collections.pdf b/notes/PDF/07_Collections.pdf
new file mode 100644
index 0000000..aac49b3
Binary files /dev/null and b/notes/PDF/07_Collections.pdf differ
diff --git a/notes/PDF/08_Exception_Handling.pdf b/notes/PDF/08_Exception_Handling.pdf
new file mode 100644
index 0000000..359551a
Binary files /dev/null and b/notes/PDF/08_Exception_Handling.pdf differ