构造器名与类名一致。
一。实例构造器
1。实例构造器与类(引用类型)
构造器是允许将类型的实力初始化为良好状态的一种特殊方法。
创建一个引用类型的实例时(类),首先为实例的数据字段分配内存,然后初始化对象的附加字段(类型对象指针和同步索引快),最后调用类型的实例构造器来设置对象的初始状态。
new一个类所发生的事:分配内存(托管堆上)——》初始化额外开销(类型对象指针和同步索引快)——》调用类型的实力构造器(设置对象的出事状态)
构造引用类型的对象时,在调用类型的实例构造器之前,为对象分配的内存总是先被归为零。构造器没有显式重写的所有字段保证都有一个0或null值。
实例构造器永远不能被继承,也就是类只有类自己定义的实例构造器。
因为不能继承实例构造器,virtual,new,override,sealed和abstract不能用于实例构造器。
如果定义的类没有显式定义任何构造器,c#编译器会默认定义一个调用了基类的(无参)构造器。
一个类型可以定义多个实例构造器。每个构造器都必须有不同的签名(参数),每个构造器够可以有不同的可访问性。
类的实例构造器在访问从基类继承的任何字段之前,必须先调用基类的构造器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
internal sealed class SomeType { private int a = 5; private string b = "helllo" ; private double c = 3.14; private Boolean d = false ; //下面为一些构造器 //public SomeType(){} // private SomeType(int aa) { a = 10; } // protected SomeType(string bb){} // internal SomeType(double cc) { c = 1.41; } // public SomeType(Boolean dd) { a = 1;b = "HI"; c = 1.73;d = true; } //该构造器将所有字段都设为默认值,然后后边构造器实时调用该构造器 public SomeType() { a = 10; b = "HI" ; c = 1.41; d = false ; } //所有字段设为默认,修改a private SomeType( int x) : this (){ a = 5; } |
1
|
//所有字段设为默认,修改a,d |
1
|
public SomeType( int x, Boolean y) : this () { a = 5;d = true ; } } |
2.实例构造器与值类型
CLR总是允许创建值类型的实例,并没有办法阻止值类型的实例化。所以值类型并不需要定义构造器。
c#编译器不会为值类型生成默认的无参构造器。
值类型的构造器只有在显式调用的时候才会执行。
值类型定义的无参构造器不会被c#编译。没有无参构造器,值类型的字段总是初始化为0或null。
任何基于栈的值类型字段都必须先写入再读取,否则会造成安全漏洞。
在访问值类型的任何一个字段之前都要对全部字段进行赋值,所以值类型的任何构造器都必须初始化值类型的全部字段。
二。类型构造器
除了实例构造器,CLR还支持类型构造器
类型构造器也称静态构造器、类构造器、或者类型初始化器。类型构造器可用于接口(c#编译器不允许)、引用类型和值类型。
类型构造器的作用是设置类型的实例的初始状态(设置类型的初始状态),类型默认没有定义类型构造器,如果有也只有一个。
类型构造器永远没有参数
以下为定义值类型跟引用类型的实例构造器
1
2
3
4
5
6
7
8
9
10
11
12
13
|
internal sealed class someref { static someref() { //someref被首次访问时执行此处代码 } } internal struct someval { //c#允许为值类型定义没有参数的类型构造器 static someval() { //someval被首次访问时执行此处代码 } } |
可见定义类型构造器类似于定义无参实例构造器,区别在于类型构造器必须标记为static,并且总是私有的(并不允许出现访问修饰符)。
类型构造器的调用较为复杂,但是只会被调用一次。(因为只能会调用一次,所以会有很多情况来进行判断之前是否已经被调用过)