c#
string stringBuilder
string 引用类型 不可变
stringBuilder 引用类型 改自己 频繁拼接字符串
GC
垃圾回收
清理堆上不用的对象,自动释放内存
ref out
ref
public Modify(ref int[] arr){
arr[0]=1;
}
int[] ayy1=new int[5];
Modify(ref arr1);
out
public Modify(out int[] arr2){
int[] arr={1,2,3};
}
int[] arr1;
Modify(out arr1);
csharp
// ✅ ref:传引用,调用前必须赋值
public void ModifyRef(ref int[] arr) {
arr[0] = 1;
}
int[] arr1 = new int[5]; // 必须先赋值
ModifyRef(ref arr1); // 必须加 ref 关键字
// ✅ out:传输出值,调用前不用赋值,方法内必须赋值
public void ModifyOut(out int[] arr) {
arr = new int[] {1,2,3}; // 方法内必须给 out 参数赋值
}
int[] arr2; // 不用初始化
ModifyOut(out arr2); // 必须加 out 关键字
泛型
List[T]
优点
动态扩容
指定类型:安全
ArrayList
动态扩容
不指定类型,容易出错
Array
不安全
啥都可以存
正确:Array(数组):长度固定,指定类型(安全),不能动态扩容
(Array 和 ArrayList 区别:Array 是强类型,ArrayList 是 object 弱类型)
clr
帮助管理代码的助手
.net程序的运行管家
垃圾回收,管理代码,管理内存
多态
一个方法,不同结果
public class animal(){
void bark(){}
}
public class dog:animal(){
void bark(){
Console.WriteLine("ww");
}
public class cat:animal(){
void bark(){
Console.WriteLine("MM");
}
}
}
面向对象
封装,多态,继承
封装
方法中,部分可见,数据隐藏
int int?
int? 值可以为null
async/await
异步,避免卡死
程序一边等 一边干别的
进程
程序运行的房子
线程
房子内运行的各种程序
null dbnull
null:空置
dbnull:代码里的控制 数据库内的空值
DBNull:专门表示数据库字段的"空值",和 C# 里的 null 不是一个东西
lock
锁住当前线程
避免其他数据侵入,避免同时操作串口,导致数据错乱
构造函数
类在被创建时 第一个被执行的方法 用于初始化
接口
实现一套模板
Icommand
实现ICommand 接口,必须实现 Excute ,CanExcute两套方法
事件、委托:
1. 委托 是什么?
委托 = 方法的"电话号码本"
- 它是个引用类型
- 里面可以存一个或多个方法
- 你一"拨打"委托,里面的方法就全部执行
它就是个普通变量,谁都能改、谁都能调用。
2. 事件 是什么?
事件 = 加了安全锁的委托
事件本质就是:
被 event 关键字保护起来的委托
它比普通委托多两个限制:
- 外部不能随便赋值(不能把里面的方法直接覆盖)
- 外部不能随便调用(只能由定义它的类自己触发)
3. 一句话总结关系
- 委托:自由、开放、谁都能改
- 事件:安全、受限、只能订阅、不能乱改
最经典的例子:按钮点击
- 按钮里有个 Click 事件
- 你只能写:
button.Click += 我的方法; - 你不能 直接:
button.Click = null;// 会报错 - 你不能 直接:
button.Click();// 也报错
这就是事件在保护安全。
你现在这三个点是不是一下就通了:
- 委托是引用类型 ✅
- 委托可以挂多个方法 ✅
- 事件就是加了锁的委托 ✅
csharp
// 定义一个委托:能存"没有参数、没有返回值"的方法
public delegate void MyDelegate();
csharp
public class Test
{
// 公开的委托
public MyDelegate myDelegate;
}
csharp
Test t = new Test();
// 你可以随便赋值、覆盖
t.myDelegate = A;
t.myDelegate = B; // A 直接被顶没了
// 你还能直接调用
t.myDelegate();
csharp
Test t = new Test();
// 你可以随便赋值、覆盖
t.myDelegate = A;
t.myDelegate = B; // A 直接被顶没了
// 你还能直接调用
t.myDelegate();
3)事件 = 加了锁的委托
csharp
public class Test
{
// 加了 event,就是事件
public event MyDelegate MyEvent;
}
csharp
Test t = new Test();
// 只能 += 订阅、-= 取消
t.MyEvent += A;
t.MyEvent += B;
// 下面这两行,**直接报错,不让你干**
// t.MyEvent = A; ❌ 不能直接赋值覆盖
// t.MyEvent(); ❌ 不能直接调用
一句话总结
委托:公共电话,谁都能打、谁都能改
事件:带锁的电话,只能订阅,不能乱改、乱触发