Files
Csharp/C#核心/Lesson4_封装-构造函数和析构函数/Program.cs
T
2025-09-30 16:49:43 +08:00

166 lines
6.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace Lesson4
{
internal class Program
{
#region 知识点一 构造函数
//基本概念
//在实例化对象时 会调用的用于初始化的函数
//如果不屑 默认存在一个无参的构造函数
//构造函数的写法
//1.没有返回值
//2.函数名和类名必须相同
//3.没有特殊需求是 一般都是public
//class Person
//{
// public string name;
// public int age;
// //类允许自己声明无参构造函数(结构体不允许
// public Person()
// {
// name = "HK";
// age = 18;
// }
// public Person(string name, int age)//当使用Person p2 = new Person("HK",19);时调用的就是这里的函数
// {
// this.name = name;//将 外部 传进来的name和age 传给 类 下面的name和age
// this.age = age;
// }
// //此时有参构造函数已经写了,如果我没写上面的无参构造函数,原本不写就默认有的无参构造函数会无效
//}
//4.构造函数可以被重载
//5.this代表当前调用该函数的对象自己
//注意:
//如果不自己实现无参构造函数而实现了有参构造函数
//会失去默认的无参构造函数
#endregion
#region 知识点二 构造函数特殊写法
//可以通过this 宠用构造函数代码
//访问修饰符 构造函数名(参数列表):this(参数1,参数2.....
//class Person
//{
// public string name;
// public int age;
// public Person()
// {
// name = "HK";
// age = 18;
// }
// public Person(string name)
// {
// this.name = name;
// }
// public Person(int age)
// {
// this.age = age;
// }
// public Person(string name, int age): this(name) //写了this()
// //就先调用无参构造函数(类似默认赋值)
// //this()中如果是空的
// //直接执行本有参构造函数
// //this()中如果写了name,就会调用只有一个name的有参构造函数
// //然后再执行本有参构造函数
// {
// Console.WriteLine("Person两个参数构造函数调用");
// }
//}
#endregion
#region 知识点三 析构函数(了解
//基本概念
//当引用类型的堆内存被回收时,会调用该函数
//对于需要手动管理内存的语言(比如C++),需要在析构函数中做一些垃圾回收处理
//但是C#中存在自动垃圾回收机制GC
//所以我们几乎不会怎么使用析构函数。除非你想在某一个对象被垃圾回收时,做一些特殊处理
//注意:
//在Unity开发中析构函数几乎不会使用,所以该知识点只做了解即可
//基本语法
//~类名()
//{
//}
class Person
{
public string name;
public int age;
public Person()
{
name = "HK";
age = 18;
}
public Person(string name)
{
this.name = name;
}
public Person(int age)
{
this.age = age;
}
public Person(string name, int age) : this(name)
{
Console.WriteLine("Person两个参数构造函数调用");
}
//引用类型堆内存被回收时才会执行
~Person() { }//析构函数
//当垃圾 真正被回收时 才会被调用
}
#endregion
#region 知识点四 垃圾回收机制
//垃圾回收,英文简写GCGarbage Collector
//垃圾回收的过程是在遍历堆(Heep)上动态分配的所有对象
//通过识别他们是否被引用来确定哪些对象时垃圾,哪些对象仍要被使用
//所谓的垃圾就是没有被任何变量,对象引用的内容
//垃圾就需要被回收释放
//垃圾回收有很多种算法,比如
//引用计数(Reference Counting
//标记清除(Mark Sweep
//标记整理(Mark Compact
//复制集合(Copy Collection
//注意:
//GC只负责堆(Heap)内存垃圾的回收
//引用类型都是存在堆(Heap)中的,所以他的分配和释放都通过垃圾回收机制来管理
//栈(Stack)上的内存是由系统自动管理的
//值类型是在栈(Stack)中分配内存的,他们有自己的声明周期,不用对他们进行管理,会自动分配和释放
//C#中的内存回收机制的大概原理
//0代内存 1代内存 2代内存
//代的概念:
//代是垃圾回收机制使用的一种算法(分代算法)
//新分配的对象都会被配置在第0代内存中
//每次分配都可能会进行垃圾回收以及内存释放(0代内存满时)
//在依次内存回收过程开始时,垃圾回收器会认为堆中全是垃圾,会进行以下两步
//1.标记对象 从根(静态字段、方法参数)开始检查引用对象,标记后为可达对象,未标记为不可达对象
// 不可达对象就被认为是垃圾
//2.搬迁对象压缩堆(挂起执行托管代码线程)释放未标记的对象 搬迁可达对象 修改引用地址
//大对象总被人为是第二代内存
//不会对大对象进行搬迁压缩 85000字节(83kb)以上的对象为大对象
#endregion
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
Person p = new Person();
Console.WriteLine(p.age);//自己默认的无参构造函数,数值为18
Person p2 = new Person("HK",19);
Console.WriteLine(p2.age);//上面实例化的19
GC.Collect();//手动回收垃圾
//一般都是在加载或场景切换时才使用
}
}
}