• 《CLR via C#》读书笔记 之 方法 明


    第八章 方法

    2013-02-27

    8.1 实例构造器和类(引用类型)
    8.2 实例构造器和结构(值类型)
    8.3 类型构造器
    8.6 扩展方法

    8.1 实例构造器和类(引用类型)


    返回

    创建引用类型的实例的过程

    (1)       为实例的数据字段分配内存(实例字段包括本身及其基类的实例字段)

    (2)       然后初始化对象的附加字段(类型对象指针和同步块索引)

    (3)       调用类型的实例构造器来设置对象的初始状态。

    基类的构造器总是在类的实例构造器之前调用,这是为了使代码“可验证”(当类的实例构造器访问从基类继承来的字段)。因此,不要再构造器中调用虚方法(比如这个虚方法要在子类中重写,可是重写方法所用字段还没初始化)。

    C#提供简单语法,允许在构造引用类型实例时,对类型中定义的字段进行“内联”初始化

    1     class SomeType
    2     {
    3         private int m_x = 5;
    4     }

    我们通过SomeType构造器的IL代码发现,字段初始化的代码会在幕后移入到构造器中,构造器IL代码的执行顺序为:字段初始化=》基类构造器=》构造器本身的代码,因此,尽量把初始化任务放在构造器中。

    和其他方法不同,实例构造器永远不能被继承。

    C#编译器将定义一个默认(无参)构造器,下表显示类修饰符与默认构造器的关系。

    表1类修饰符与默认构造器的关系

    类的修饰符

    默认构造器

    无abstract

    默认构造器可访问性为public

    有abstract

    默认构造器可访问性为protected

    static(静态类在元数据中是抽象密封类)

    编译器根本不会在类中定义生成一个默认构造器

    8.2 实例构造器和结构(值类型)


    返回 

    值类型(struct)构造器的工作方式与引用类型(class)的构造器截然不同。C#编译器根本不会为值类型生成无参构造器。即使为值类型提供了无参构造器,许多编译器也永远不会生成代码调用它。C#编译器干脆不允许值类型定义无参构造器,也不允许值类型中内联方式初始化实例字段。

    注意:严格的说,只有当值类型的字段嵌套到引用类型中时,才保证会被初始化为0或null。但是,基于栈的值类型字段不保证为0或null。

            为了代码的“可验证性”(verifiablity),任何基于栈类型的子类型都必须在读取前写入(赋值)。如果允许代码先读再写,就会造成安全漏洞,所以C#和其他生成“可验证”代码的编译器可以保证对它们进行“置零”。

    8.3 类型构造器


    返回 

    类型默认没有定义类型构造器,如果定义,也只能定义一个。此外,类型构造器永远没有参数。

    类型构造器必须标记为static,而且,总是私有的,C#会自动把它们标记为private。

    任何一个类型定义了类型构造器,JIT编译器都会检查针对当前AppDomain,是否已经执行了这个类型构造器来决定是否要调用它。

    注意:由于CLR保证一个类型构造器在每个AppDomain1中只能执行一次,而且是线程安全的,因此,非常适合在类型构造器中初始化类型需要的任何单实例(Singleton)对象。

    类型构造器不应调用其基类型的类型构造器。这种调用没有必要,因为类型并没有从其基类型继承静态字段。

    8.6 扩展方法


    返回 

    对无法修改的类扩充其方法,要小心使用。

  • 相关阅读:
    在CentOS 8 上 部署 .Net Core 应用程序
    Asp.Net Core 查漏补缺《一》 —— IStartFilter
    接口相关数据日志打印
    退款
    识别身份证
    生成二维码
    打造一款简单易用功能全面的图片上传组件
    Redis过期策略+缓存淘汰策略
    Redis主从复制
    .net 平台常用框架
  • 原文地址:https://www.cnblogs.com/Ming8006/p/2934778.html
Copyright © 2020-2023  润新知