Initial commit

This commit is contained in:
2026-04-13 15:40:15 +08:00
commit 02810617db
40 changed files with 849 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
语法: A ? B : C
返回值类型必须一致
EG: str = true ? "真" : "假"//str为真
EG: str = 1 > 2 ? "真" : "假"//假
#入门
+9
View File
@@ -0,0 +1,9 @@
拼接方式
1. "+"
1. str += "1" + 4 + true; //"14true"
2. str += 1+2+3;//"6"先运算后convert
3. str += ""+1+2+3;"123"
2. string.Format("待拼接的内容",内容1,内容2.....);
1. str = string.Fomat("我是{0},我今年{1}岁","HK",18);//我是HK,今年18岁
3. $"{0}balabala{1}",balabala,balabala
#入门
+11
View File
@@ -0,0 +1,11 @@
关键字const
const 变量类型 变量名 = 值;
1. ==必须初始化==
2. ==不能修改
应用场景
定义PI 3.14
数学相关
#入门
+59
View File
@@ -0,0 +1,59 @@
### **隐式转换**
##### **相同大类型**
一般都遵守 ==大的能装小的,小的装不了大的==
有符号(long int short sbyte)
无符号(ulong uint ushort byte)
浮点数(decimal double float)
==decimal没有办法隐式转换==
其他同规则
特殊类型(bool char string)
==不存在隐式转换==
##### 不同大类型
==无符号不能隐式转换装有符号==
有符号装无符号需要==注意范围==
int 不能装 uint (正方向少1)
==浮点数可以装任意类型的整数==
==decimal可以隐式存储整型==
==整数无法装浮点==
##### 整理
大范围装小范围
高精度装低精度
string 和 bool 不参与隐式转换
decimal比较特殊
char是ASCII所以可以转换成整型和浮点型
double > float > 所有整型
decimal > 所有整型
### **显示转换**
1. 括号强转
1. 精度和范围(丢精度和溢出)
2. 语法:变量类型 变量名 = (变量类型)变量;
3. EG: double double1 = (double)int1;
2. Parse法(一般用来转换字符串到数字)
1. ==字符串必须能够转换为对应类型== 否则报错
2. 语法:变量类型.Parse("字符串")
3. EG: int int1 = int.Parse("123");
3. Convert法
1. 注意点和Parse法一样,精度比强转准一点(有四舍五入)
2. 语法:Convert.To变量类型(变量或常量)
3. EG:int int1 = Conver.ToInt32("123")
4. 其他类型转String
1. 常用于拼接打印
2. 语法:变量.toString();
3. EG: string str = 1.ToString(); / 'A'.ToString(); / true.ToString();
4. 特殊用法string str = "123123" + 1.23 + True;(隐式调用ToString方法了)
#入门
+21
View File
@@ -0,0 +1,21 @@
单引号\\'
string str = "\\'123\\'"
双引号
str = "\\"123\\""
换行
str = "1\n23"
斜杠
str = "12\\\3"
以下不常用
制表符\t
光标退格\b
红字符\0
#入门
+13
View File
@@ -0,0 +1,13 @@
### 三大特性
1. 封装
2. 继承
3. 多态
#### 七大原则
1. 开闭原则
2. 依赖倒转原则
3. 里氏替换原则
4. 单一职责原则
5. 接口隔离原则
6. 合成复用原则
7. 迪米特法则
+28
View File
@@ -0,0 +1,28 @@
通常用法:
解决值[[值类型和引用类型]]在函数内外部互相传递时的问题
函数内部改外部传入也改
==ref和out的区别:==
ref
- 传入的参数必须初始化(赋值)
- 方法内可读可写
out
- 传入前**可以不初始化**
- 方法内**必须赋值**,否则编译报错
语法:
在函数传参时,两边都要加上修饰词
ref
```Csharp
static void ChangeValueref value
ChangeValueref a
```
案例:
原型在[[值类型和引用类型]]笔记中
注意:
==out不是用来让内外值一定不等==
==ref传入的参数必须初始化==
如果传入引用类型且内外不同,推荐new一个
#基础
@@ -0,0 +1,46 @@
概念:
==引用类型:string、数组、类==
==值类型:剩下都是,包括数组、enum、结构体==
值类型默认都是0
bool类型是false
引用类型默认值是null
使用区别:
值类型:在相互赋值时,把内容进行拷贝 //他变我不变
引用类型:把相互赋值时,把==地址==进行拷贝 //他变我也变
原因:
值类型和引用类型 存储的内存区域不同,存取方式也不一样
值类型:栈空间 —— 小但是快 (0GC)
引用类型:堆空间 —— 大但是慢 (且有GC)
案例:
值类型:
```Csharp
static void ChangeValue(int value)
{
value =3:
}
static void Main(string[] args)
{
int a = 1;
ChangeValue(1);
cw(a);
}
//仍然输出1
```
引用类型:
```Csharp
static void ChangeValue(int[] value)
{
value =99:
}
static void Main(string[] args)
{
int[] a = {1};
ChangeValue(a);
cw(a[0]);
}
//输出99
```
#基础
+23
View File
@@ -0,0 +1,23 @@
概念:
解决函数传递时需要传递多个(不确定具体个数)参数的问题
通常用法:
语法:
关键字:params
案例:
```Csharp
static int Sum(params int[] arr)
{
//具体方法
return value;
}
Sum(1,2,3,4,5,6,7); //都会存入arr里
```
注意:
==params关键字后面必须是数组==
==最多只能有1个变长参数 且必须放在末尾==
#基础
+34
View File
@@ -0,0 +1,34 @@
概念:被命名的整型[[常量]]集合
通常用法:存储玩家状态等,==和switch天生一对==
用int表示会导致非常难直观信息,可以用枚举给数值类型加名字
语法:
声明地点:
1.==namespace中(常用)==
2.class或struct中
声明枚举:
```Csharp
enum E_自定义枚举名
{
, //自带一个下标0
2, //自动累加
3,
4 = 100 //手动设置下标
}
```
声明枚举变量:
>自定义枚举类型 变量名 = 默认值;
案例:
实例化枚举:
E_自定义枚举名 e1 = E_自定义枚举名.自定义枚举量
注意:
声明==枚举==和声明==枚举变量==是两个事情
枚举最好不要用中文
可以和int、string类型[[格式转换]] //非常少用
#基础
+42
View File
@@ -0,0 +1,42 @@
概念:
自定义变量类型 类似枚举
==数据和函数的集合==
是[[值类型和引用类型|引用类型]]
通常用法:
解决复杂类型数据的存储
写namespace层级中
语法:
关键字struct
必须有变量
构造函数(可选)
函数(可选)
案例:
```Csharp
struct Student
{
int age;
bool sex;
int number;
string name;
void speak(){}
}
```
注意:
可以声明变量和方法、构造方法
甚至可以声明别的结构体,但是不能用自己声明自己
==不能在结构体内初直接给成员初始化==
==和static class相反!!!==
==`struct` 本身就是[[值类型和引用类型|值类型]]、可实例化、可复制、可栈上分配==
==`static class` 的设计目的:**只装静态成员,不能实例化**==
==邪修:==
`static class`:纯工具类,不能 new
`struct`:值类型,必须能 new、复制、栈分配 → 不支持 static
struct 内部不能直接给字段赋值 → 为了效率,无隐式初始化
#基础
+7
View File
@@ -0,0 +1,7 @@
帕斯卡命名法:开头大写后续小写
应用场景:函数名、[[成员属性]]名
EG:Name
驼峰命名法:开头小写,中间大写
应用场景:变量名
EG:myName
@@ -0,0 +1,51 @@
概念:
1. 声明在类中
2. 用来描述对象特征
3. 任意变量类型
4. 是否赋值根据需求决定
通常用法:
语法:
1. 声明:
```Csharp
enum E_SexType
{
male,
female
}
class Human
{
string name;
int age;
E_Sex sex;
Human[] friend; //==可以类里声明自己类的同类型 但是不能实例化!==
}
```
2. 访问修饰符
public——公共的 类内部和外部都可以进行访问
private——私有的 只有内部才能访问 ==子类不行==
protected——保护的 只有自己内部和子类才可以访问
3. 成员默认值
可以看[[值类型和引用类型]]
懒得看可以cw(default(变量类型))
案例:
```Csharp
class Human
{
string name;
int age;
E_Sex sex;
Human[] friend; //==可以类里声明自己类的同类型 但是不能实例化!==
}
Human h1 = new Human();
h1.age = 18;
cw(h1.age);
```
注意:
+85
View File
@@ -0,0 +1,85 @@
概念:
==和成员变量不完全是一个概念!!!!==
1. 用于保护成员变量
2. 为成员属性的获取和复制添加逻辑处理
3. 解决3P局限性
自动属性
通常用法:
配合private加密或规范成员属性的修改获取等
让其==只能获取不能修改== 或 ==只能修改不能获取==
语法:
属性声明:
```Csharp
访
{
get{}
set{}
}
```
案例:
```Csharp
class Person()
{
private int age;
private string name;
private int money;
private bool sex;
public string Name [[|]]
{
get====
{
//这里写处理获取内容的逻辑
return name;
}
set
{
//这里写处理修改/添加内容的逻辑,不写就没有
==//关键字value 用于表示外部传入的值 只在set中有==
name = value;
}
}
}
Person p = new Person();
~~p.name = xxx~~ private所以没法用.name
p.Name = xxx
```
↑写了一个public的属性大家都可以访问,用该属性Name进行修改 return直接返回原始的nameset时使用.Name将xxx作为传入参数放到set的value关键字中
案例2
```Csharp
public int Money()
{
get
{
return money;
}
set
{
if(value<0) value = 0;
cw();
money = value;
}
}
```
↑最简单的防止money为负数的逻辑
注意:
成员属性不加访问修饰符,会使用成员变量声明时的访问权限
==get和set也可以加访问修饰符,但是不能大于成员属性前访问修饰符的权限==
可以只有一个set或只有一个get(只能得或只能改),但是通常没人这么干
自动属性
相当于声明了一个成员变量,但是好处是可以添加访问修饰符
案例:可以得,但是不能改得一个成员↓
```Csharp
public float Height
{
get;
private set;
}
```
@@ -0,0 +1,145 @@
# 构造函数:
概念:
实例化时,用于初始化的函数
不写默认有一个无参构造函数
==可以重载==
通常用法:
自定义初始化规则
语法:
访问修饰符 类名(){}
案例:
```Csharp
class Person()
{
public string name;
public int age;
public Person()
{
name = "默认值";
age = ;
}
}
```
this关键字:
this指当前类声明的成员变量
```Csharp
class Person()
{
public string name;
public int age;
public Person()
{
name = "默认值";
age = ;
}
public Person(int age,string name) //重构
{
this.name = name;
//后面的name是传递的参数,this.name是最上方public int出来的
this.age = name;
}
}
```
特殊写法:
通过this重用构造函数代码,即先调用无参构造函数,然后在调用这个特殊写法的构造函数
语法:访问修饰符 构造函数名(参数列表):this(【可选】参数1,参数2.....)
例子:
```Csharp
public Person(int age, string name)thisage
{
balabala
}
```
过程:先调用无参Person构造函数,然后寻找只有构造单个参数age的构造函数进行初始化
注意:
==函数名和类名必须相同==
==没有特殊用途,一般都是public==
==如果写了有参构造函数且自己没有保留无参构造函数,那么类在实例化时只能使用有参构造函数且无法使用无参构造函数==
----
# 析构函数
概念:
当引用类型堆内存被回收时,会调用该函数
对于需要手动管理内存的语言(C++),需要在析构函数中做一些内存回收处理
C#有自动垃圾回收机制GC
Unity中基本不用管
通常用法:
语法:
```Csharp
~
{
}
```
案例:
```Csharp
~Person
{
}
```
注意:
----
# 垃圾回收
垃圾回收(GC
通过遍历堆Heap上动态分配的所有对象
通过识别他们是否被引用来确定哪些对象时垃圾,哪些对象仍然需要引用
垃圾:没有变量或对象引用的内容
如果是垃圾就要被回收释放
一般都是==被动触发(会造成卡顿)==,所以游戏一般需要手动执行垃圾回收
语法:GC.Collect();
==GC会造成卡顿,所以在加载Loading时一般会调用==
垃圾回收有多种算法
引用计数
标记清楚
标记整理
复制集合
注意:
GC只负责Heap内存的垃圾祸首
引用类型都是在Heap中的,所以他需要GC来进行管理
栈Stack上的内存时系统自动管理的
所以不需要GC
C#中垃圾回收机制的大概原理
他会把内存分为012代内存
代的概念是垃圾回收中的一种算法需要
新分配的对象都会被配置在第0代内存中
每次分配都可能会进行垃圾回收(一般来说0代内存满了就会触发)
在第一次内存回收过程开始时,垃圾回收器会认为堆中全是垃圾,会进行一下两部
1.标记对象,从根(静态参数、方法参数)开始检查引用对象,标记后为可达对象,未标记就是不可大对象
不可达对象就会认为是垃圾
2.搬迁对象 压缩堆 (挂起执行内存托管代码线程:把第0代内存(还不是垃圾的内存)放到一代进行搬迁)释放未标记的对象、搬迁可达对象、修改引用地址
大对象总被认为是二带内存,目的是减少性能损耗
不会对大对象进行压缩搬迁 大对象是85000kb以上的
示意图
step1:程序放入内存
![[Pasted image 20260412210327.png|697]]
step2:发现沾满了
![[Pasted image 20260412210704.png]]
step3:原来的地址搬迁,无引用的垃圾丢掉
![[Pasted image 20260412210810.png]]
step4:D放入
![[Pasted image 20260412210946.png]]
step5:如果0代1代后续又满了,那么这套算法会同时做用在两代内存中,以此类推
类似多级缓存cache,L1最快但常换L3最慢
#基础
+34
View File
@@ -0,0 +1,34 @@
概念:
让对象像数组一样可以通过下标访问,方便程序编写
通常用法:
语法:
```Csharp
访 this[ 1 2.....]
{
get{} ====
set{}
}
```
案例:
```Csharp
class Person
{
private string name;
priavte int age;
private Person[] friends;
public Person this[int index]
{
get{return friends[index];}
set{friends[index] = value;}
}
}
Person p1 = new Person();
p[0] = new Person();
```
注意: