构造器
构造器:构造器一般用来进行状态的初始化,包括实例构造器和类构造器两种。构造器不支持继承,构造器存储在代码段中(和常量的存储地方一样)。
实例构造器
实例构造器主要负责将类型的实例初始化到一个合理的状态。引用类型和值类型的实例构造器是有所区别的。如果我们没有定义实例构造器,那么编译器会为我们默认产生一个无参构造器。在调用构造函数前,变量被初始化为0或者null,所以没有被构造器改变的变量在实例创建后将保持0值。如果类没有显示定义构造器,编译器会自动生成一个无参构造器,调用基类的无参构造器。如果类的修饰符为static,编译器不会默认生成构造器;如果存在继承关系,派生类在使用基类的字段之前应该先调用基类的构造器。如果派生类没有显式调用基类构造器,则编译器会自动产生调用基类无参构造器的代码,沿着继承层次一直到System.Object的无参构造器位置。
值类型没有默认产生的无参构造器,也不允许我们定义无参构造器。但是我们可以自定义带参数的构造器。不允许在值类型中内联实例字段的初始化。否则会产生编译错误。值类型带参构造函数必须对所有实例字段进行初始化才可以。如果有变量没有初始化,就会报错。
类构造器(静态构造器)
类中并没有默认产生的类构造器,需要我们显式构造。标记为static方法。一个类只有有一个类构造器,不能进行重载。而且不能含参数(因为类构造器是由CLR调用的)。类构造器的目的是初始化类的静态成员,它只能访问静态成员,不能访问实例成员。类构造器的访问限制默认为私有的,且我们不能在类构造器前添加访问修饰符,private也不行,否则会产生编译错误,这样做是为了防止开发人员调用该方法。它的调用是由CLR负责的,即系统自动调用,程序员无法手动调用。我们应该避免编写需要以特定顺序调用类构造器的代码。类构造器不要调用其基类的类构造器(即类构造器不会被继承)。因为基类的静态成员并没有被派生类所继承,它只是编译时静态绑定。类构造器的调用顺序和实例构造器相似的,首先静态字段被初始化,然后在构造其中被重新赋值。类型构造器在类被第一次访问前由CLR调用,用来对类内部的静态成员进行初始化赋值。
字段的初始化:字段一般需要通过构造器来显示的进行初始化,如果没有显示初始化,则CLR会将该字段初始化为0(值类型)或者null(引用类型),字段可实现内联初始化,即声明的同时初始化,实例字段内联初始化的本质是在每一个构造器的起始处添加初始化代码。静态字段的内联初始化,会在静态构造器的起始处添加初始化代码,如果类型无静态构造器,则编译器会自动生成静态构造器。(即在类中如果出现静态字段的内联初始化,类就会自动生成一个静态构造器)
前面有一句话,派生类在使用基类的字段之前应该先调用基类的构造器,什么意思了,就是说当我们在实例化子类的对象的时候,我们需要去初始化一些继承自父类的字段,那么这时候我们我们就需要去调用基类的构造器。下面我举例说明这个问题
using System;
class BaseClass
{
public int _x;
public int _y;
public BaseClass(int x,int y)
{
this._x=x;
this._y=y;
}
}
class InheritClass:BaseClass
{
public int _z;
public InheritClass(int x,int y,int z):base(x,y)
{
this._z=z;
}
}
class Test
{
public static void Main()
{
InheritClass intstence=new InheritClass(100,200,300);
Console.WriteLine(intstence._x);
Console.WriteLine(intstence._y);
Console.WriteLine(intstence._z);
}
}
在这段代码中,我们定义了父类和子类,在父类中我们定义了两个保护字段,同时我们在子类中又增加了一个字段。当我们实例化子类的对象的时候,会调用到父类的构造器,调用的形式如代码中所示。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库