引用类型构造器

如果我们没有定义实例构造器,那么编译器会为我们默认产生一个无参构造器。

实例对象初始化过程

  • 为实例分配内存;
  • 初始化附加成员,包括方法表指针和SyncBlockIndex变量(我们已经在

    调用顺序

    如果类没有显示定义构造器,编译器会自动生成一个无参构造器,调用基类的无参构造器。例如

    public class Animal{}

    相当于

    public class Animal

    {

    public Animal():base(){}

    }

    如果类的修饰符为static(sealed和abstract),编译器不会默认生成构造器;

    如果基类没有提供无参构造器,那么派生类必须显示调用一个构造器,否则编译错误。

    如果存在继承关系,派生类在使用基类的字段之前应该先调用基类的构造器。如果派生类没有显式调用基类构造器,则编译器会自动产生调用基类无参构造器的代码,沿着继承层次一直到System.Object的无参构造器位置。例如下面,调用Dog dog=new Dog()方法的结果。

    class Dog:Animal。。。

    Dog()方法IL代码

    代码爆炸?

    为了防止构造器重载时大量重复赋值造成代码膨胀,我们建议将公共的初始化语句放在一个构造函数中,然后其他的构造器显式调用该构造器。

 class A
{
public int xxxx = ;
public int xxxx2 = ;
public int xxxx3 = ; public A()
{
Console.WriteLine("我是类A的无参构造器");
} public A(string ss)
{
Console.WriteLine("我是类A的无参构造器");
}
} //编译后等价于
class A
{
public int xxxx;
public int xxxx2;
public int xxxx3; public A()
{
xxxx = ;
xxxx2 = ;
xxxx3 = ;
Console.WriteLine("我是类A的无参构造器");
} public A(string ss)
{
xxxx = ;
xxxx2 = ;
xxxx3 = ;
Console.WriteLine("我是类A的无参构造器");
}
} /// <summary>
/// ////////////////////////////////////////////////////////////////////////////////////////////////
/// </summary>
class A
{
public int xxxx = ;
public int xxxx2 = ;
public int xxxx3 = ; public A()
{
Console.WriteLine("我是类A的无参构造器");
} //防止代码爆炸
public A(string ss):this()
{
Console.WriteLine("我是类A的无参构造器");
}
} //编译后等价于
class A
{
public int xxxx;
public int xxxx2;
public int xxxx3; public A()
{
xxxx = ;
xxxx2 = ;
xxxx3 = ;
Console.WriteLine("我是类A的无参构造器");
} public A(string ss):this()
{
Console.WriteLine("我是类A的无参构造器");
}
}

值类型构造器

  • 值类型没有默认产生的无参构造器,也不允许我们定义无参构造器。但是我们可以自定义带参数的构造器。

  • 不允许在值类型中内联实例字段的初始化。下面的例子会产生编译错误。

    struct TestStruct
        { 
           partial int number=5;
        }
  • 值类型带参构造函数必须对所有实例字段进行初始化才可以。如果有变量没有初始化,就会报错。

如果不想对所有字段一一初始化,有一种替代方案:

  struct Dog
    {
        public int age;
        public string name;
        public Dog(string Name)
        {
            this = new Dog();
            name = Name;
        }
    }

在值类型构造器中,this代表值类型本身的一个实例,用New创建的值类型实例赋给this时,会将所有字段置零。所以这个方案可以编译通过。

  • 带参构造函数定义之后需要用new显式调用才能执行。否则值类型的字段会保持0或Null值。

    

6 CLR实例构造器的更多相关文章

  1. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_8.1实例构造器和类A

    public class SomeType { } //等价于 public class SomeType { public SomeType():base(){} } [解释]如果定义的类没有显示定 ...

  2. 6 CLR静态构造器

    CLR保证一个类型构造器在每个AppDomain中只执行一次,而且这种执行是线程安全的. 作用: 就是初始化静态成员 比如有几个静态成员需要初始化那你把初始化代码放到哪呢? 放到普通构造函数里,那肯定 ...

  3. Sql Server 2005 CLR实例

    本文转载:http://www.cnblogs.com/yongfa365/archive/2010/04/26/SQL-Server-CLR.html CSDN:博客参考http://blog.cs ...

  4. CLR via C#(06)- 构造器

    最近忙着看新还珠,好几天不学习了.玩物丧志啊,罪过罪过. 今天总结的是类构造器的知识,其实这方面的文章蛮多的,可还是觉得亲自写一下对自己的思考和认识会有提高. 对于构造器,大家应该都不陌生,它主要是用 ...

  5. CLR类型设计之方法与构造器

    无论学习那门语言都要学习函数体,C#,JAVA,PHP,都会涉及到函数体,而C#的函数体成员并不少,方法和构造器就是函数体成员之一,函数体成员还包括但不限于:方法,属性,构造器,终结器,运算符及索引器 ...

  6. 类型基础---CLR Via C#笔记一

    一.所有类型都是从System.Obejct派生 1.下面两个类型定义是完全一致的: class Employee{ ... } class Employee:System.Object{ ... } ...

  7. 《CLR.via.C#第三版》第二部分第8,9章节读书笔记(四)

    三种类型的构造方法: 实例构造器(引用类型):实例构造器永远不能被继承(所以方法前没有修饰符):如果类的修饰符为static(sealed和abstract),编译器根本不会在类的定义中生成一个默认构 ...

  8. CLR via C# 读书笔记---常量、字段、方法和参数

    常量 常量是值从不变化的符号.定义常量符号时,它的值必须能在编译时确定.确定后,编译器将唱两只保存在程序集元数据中.使用const关键字声明常量.由于常量值从不变化,所以常量总是被视为类型定义的一部分 ...

  9. C#知识点总结系列:5、CLR的组成和运转

    clr基本 CLR(Common Language Runtime)是一个可由多种编程语言使用的“运行时”.(例如:c#,c++/cli,vb,f#,ironpython,ironruby,il... ...

随机推荐

  1. App架构师实践指南一之App基础语法

    第二章:App基础语法1.编程范式编程范型或编程范式(programming paradigm),是指从事软件工程的一类典型的编程风格.常见的编程范式有过程化(命令行)编程.事件驱动编程.面向对象编程 ...

  2. Asp.Net JsonResult重写

    在Json序列化工具中,Newtonsoft.Json 的工具包相对比较好用. 对于循环引用.序列化格式.时间格式等都提供了可配置. 如果想重写Mvc 自带 JsonResult 返回结果,提供了2中 ...

  3. 序列化与反序列化的单例模式实现和readResolve()【转】

    如: public class SingleTest implements Serializable{private static final long serialVersionUID = -860 ...

  4. [How To] TrueCrypt使用教學 - 重要資訊的加密保險箱(转)

    我在2013年八月的時候寫了這篇關於TrueCrypt的使用教學,但從去年(2014)五月下旬開始,TrueCrypt的首頁出現了"Using TrueCrypt is not secure ...

  5. ThinikPhp 将数据库模型的增、删、改操作写入日志

    Thinkphp中的模型可以对数据库字段进行验证规则的设置和设置一些字段的默认值(比如字段为当前时间)以及在操作数据时的的一些回调方法等   基本上每一个模型都需要设置一些验证规则和字段默认值的设置, ...

  6. (转) Java RandomAccessFile与MappedByteBuffer

    RandomAccessFile RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必相同:但是其大小和位置必须 ...

  7. 把tree结构数据转换easyui的columns

    很多时候我们的datagrid需要动态的列显示,那么这个时候我们后台一般提供最直观的数据格式tree结构.那么需要我们前端自己根据这个tree结构转换成easyui的datagrid的columns. ...

  8. CART决策树(分类回归树)分析及应用建模

    一.CART决策树模型概述(Classification And Regression Trees)   决策树是使用类似于一棵树的结构来表示类的划分,树的构建可以看成是变量(属性)选择的过程,内部节 ...

  9. H5的Video事件,控制方法,及监听

    1.标签基本属性 src :视频的属性 poster:视频封面,没有播放时显示的图片preload:预加载autoplay:自动播放loop:循环播放controls:浏览器自带的控制条width:视 ...

  10. unity, ComputeScreenPos 作用

    这帖子讲得很清楚:https://forum.unity3d.com/threads/what-does-the-function-computescreenpos-in-unitycg-cginc- ...