十九:构造器之一:实例构造器和类(引用类型)

     构造器是一种允许将类型实例初始化为有效状态的特殊方法,构造器方法在方法定义元数据表中被称为.ctor。

创建引用类型的实例时,首先为实例的数据字段分配内存,接着初始化对象的系统开销字段(类型对象指针和同步块索引),最后调用类型的实例构造器设置对象的初始状态。

     创建引用类型对象时,在调用类型的实例构造器之前,为对象分配的内存始终被清零,构造器没有显示赋值的所有字段保证都有一个0或null值。

     实例构造器不能被继承,也就是说,类只能有自己定义的构造器,不能继承父类的,所以构造器不能用以下修饰符:virtual,new,override,sealed,abstract。

     编译器为我们自动的生成一个无参构造器,该构造器的实现只是为了调用基类的无参构造器。

     如果类的修饰符为abstract,那么编译器生成的默认构造器的可访问性为protected,否则,构造器的可访问性为public。如果基类没有提供无参构造器,那么派生类必须显式地调用基类的构造器。如果类的修饰符为static,sealed和abstract,编译器就不会在类的定义中生成一个默认的构造器。

     一个类型可以定义多个实例构造器,而且每个构造器可以有不同的可访问性。

C#语言还提供了一种简单的语法,允许在构建类型实例的过程中初始化类型中定义的字段,如下:

internal sealed class SomeType

{

    private Int32 m_x = 10;

}

     构建SomeType对象时,SomeType对象的m_x字段将被初始化为10,查看一下SomeType的构造器方法(.ctor)的中间语言,如下图:

 

     可以看到SomeType先把10存储到m_x字段,接着它又调用了基类构造器,也就是说C#编译器提供了这种更方便的语法来内联初始化实例字段,并且将这个语法转换成构造器方法中的代码来执行初始化,这时候就要注意到代码膨胀效应,看下面代码:

internal sealed class SomeType

{

    private Int32 m_x = 10;

    private String m_s = "test";

    private Double m_d = 3.141519;

    private Byte m_b;

    public SomeType() { }

    public SomeType(Int32 x) { }

    public SomeType(String s)

    { 

        //...

        m_d = 10;

    }

}

     编译器为上述三个构造器方法生成代码时,每个方法入口都包含初始化m_x,m_s,m_d的代码,在这些代码初始化之后,编译器将构造器方法中的代码附加到方法后面。如果有几个已初始化的实例字段和许多重载的构造器方法,应考虑在定义字段时避免同时对它们进行初始他,而是将这些公共初始化语句放在一个单独的构造器中,然后让其它构造器来显式的调用这个公共初始化构造器,这样减少所生成的代码大小,以下例子就是用this关键字来调用另一个构造器的方法示例:

internal sealed class SomeType

{

    //不要显示的初始化下面字段

    private Int32 m_x;

    private String m_s;

    private Double m_d;

    private Byte m_b;

    //该构造器将所有的字段都设为默认值,其它构造器必须显式的调用这个构造器

    public SomeType() 

    {

        m_x = 10;

        m_s = "test";

        m_d = 3.141519;

        m_b = oxff; 

    }

    //该构造器首先将所有字段都设为默认值,然后再修改m_x

    public SomeType(Int32 x)

        : this()

    {

        m_x = x;

    }

    //该构造器首先将所有字段都设为默认值,然后再修改m_s

    public SomeType(String s)

    { 

        m_s = s;

    }

    //该构造器首先将所有字段都设为默认值,然后再修改m_x和m_s

    public SomeType(Int32 x, String s)

        : this()

    {

        m_x = x;

        m_s = s;

    }

}

 

 

posted @ 2009-01-31 01:01  Done  阅读(470)  评论(0编辑  收藏  举报