一.构造函数
构造函数就是与类同名的且没有返回类型的方法。构造函数可以带参数,并且可以被重载。
1.如果不声明显示的构造函数,那么编译器就会生成一个默认的构造函数;默认构造函数不带参数且方法体为空。
实例构造函数用于初始化类实例的状态;默认的构造函数只能对成员字段进行初始化为标准的默认值。
2.如果要从类的外部创建类的实例,需要声明构造函数为public。一旦一个类被设置成私有构造函数,就不能被继承,不能被实例化,这种情况下,通常为类提供静态方法以供调用,通过静态方法进行类的实例化,这样可以有效控制该类实例的数量。
namespace ConsoleApp1
{
class Program
{
private static void Main()
{
AddClass a=AddClass.GetInstance(100);
AddClass aa = AddClass.GetInstance(200);
Console.WriteLine(a.Int);
Console.WriteLine(aa.Int);
}
}
public class AddClass
{
public int Int { get; set; }
static AddClass addClass;
private AddClass(int a)
{
Int = a;
}
public static AddClass GetInstance(int a)
{
if (addClass is null)
addClass = new AddClass(a);
return addClass;
}
}
}
3.构造函数初始化器
构造函数初始化器可以包含对同一个类的另一个构造函数的调用,也可以包含对直接基类的构造函数的调用,初始化器不能有多个调用。
public class AddClass
{
public AddClass(int a, int b)
{
}
//构造函数初始化器会在本构造函数执行前,先执行AddClass(int a,int b)
public AddClass(int a):this(a,0)
{
}
//构造函数初始化器会在本构造函数执行前,先执行直接基类Object的构造函数Object()
public AddClass() : base()
{
}
}
4.静态构造函数
静态构造函数在一个类中只能有一个,且只能被执行一次,而实例构造函数则无此限制。即在加载类的时候执行静态构造函数,而在创建实例时执行实例构造函数。
public class AddClass
{
public static int a { get; }
/// <summary>
/// 静态构造函数会在属性a被调用之前执行,用于初始化静态属性a
/// </summary>
static AddClass()
{
a = 10;
}
}
静态构造函数的作用是初始化类的静态字段和静态属性,且在类的任何实例创建之前和静态成员被引用之前。
这是由于CLR不能确保在明确时间点执行静态构造函数,同时也不能预计不同类的静态构造函数执行顺序,所以,只能确定静态构造函数会在第一次调用类的其他成员之前被调用。
静态构造函数只会被CLR调用,不能显示调用,所以静态构造函数不会有访问修饰符和参数;静态构造函数也不能访问类的实例成员。
二.析构函数
析构函数是执行在类的实例被销毁之前需要的清理或释放非托管资源的行为。
析构函数实际上是重写基类的Finalize()方法,所以析构函数没有参数和访问修饰符,且每个类只存在一个,和类名相同,以~作为前缀。
对于析构函数来说,在清理非托管资源的时候存在两个问题
一是存在两次处理才能销毁非托管资源
二是析构函数存在不确定性,不能实时清理非托管资源
1.不能显示调用析构函数
2.析构函数不是在实例失效时立即调用
3.析构函数只对类的实例起作用,因此没有静态析构函数
4.析构函数只应该释放对象拥有的外部资源
5.析构函数不应该访问其他对象,因为不能保证对象是否还存在
6.如果不需要,就不要执行析构函数,它们会带来性能上的开销
7.使用IDispose接口处理需要及时清理的非托管资源,所以实现IDispose接口不一定声明析构函数。
8.实现DIspose方法时需要能够保证多次调用时是安全的
9.Dispose方法未能处理资源时,析构函数应该确保可以处理资源,所以声明析构函数时也应该实现IDispose接口.
10.Dispose方式清理资源后,需要调用GC.SuppressFinalize方法,该方法告诉CLR不在需要调用析构函数
三.构造函数和析构函数的区别
实例构造函数 在创建类的每个实例时都会调用
实例析构函数 在对类的每个实例都会调用,在程序不再访问该实例之后的某个时间点
静态构造函数 只调用一次,在类的任意静态变量第一次被访问之前或者类的任何实例被创建之前
静态析构函数 不存在,只有实例才有析构函数