C# 实例化类的执行顺序
先进行细分:
类的成员分为:字段、属性、方法、构造方法
成员的修饰符:静态成员、实例成员
层次结构:父类、子类
先不考虑继承关系,执行顺序为:
- 静态字段
- 静态构造方法
- 实例字段
- 实例构造方法
属性和方法是在调用的时候才执行,这里就不考虑了。如何理解上面的执行过程?假如让我来设计执行过程,我该如何考虑,依据是什么?
首先,静态的东西是大家共享的,也就是相同的。应该先关心共享的东西,再关系个人的东西。“先公后私”,呵呵。
其次,实例化之前,应该先初始化自己的内部数据。
现在考虑继承关系,执行顺序为:
- 子类的静态字段
- 子类的静态构造方法
- 子类的实例字段
- 父类的静态字段
- 父类的静态构造方法
- 父类的实例字段
- 父类的实例构造方法
- 子类的实例构造方法
在子类的实例字段和子类的实例构造方法之间,加入了父类的执行顺序。这个其实也很好理解:在子类的实例构造方法之前,确实需要知道父类的信息,因为子类要从父类那里继承一些东西。这就好比,没有老子,哪来的儿子呢,呵呵。
这里需要特别注意的是,并不是每次实例化都是上面的顺序。因为静态的成员只是在第一次实例化的时候执行,以后再实例化都不会在执行。很好理解,静态的成员意味着大家共享,且只有这一个。第一次实例化得到静态成员后,以后大家都共享,再次实例化,没有必要也不允许执行静态成员的部分。
补充说明:
1、构造引用类型的对象时,调用实例构造方法之前,为对象分配的内存总是先被归零,构造器没有显式重写字段,字段的值为0或者null
2、原则上讲,类中的字段应该在实例构造方法内初始化。C#编译器提供了简化的语法,允许在变量定义的时候初始化。但在幕后,C#会把这部分代码搬到构造方法内部。因此,这里存在代码膨胀的问题。多个字段在定义时初始化,同时存在多个构造方法,每个构造方法都会把这些字段初始化的代码搬到自己的内部,这样造成代码的膨胀。为了避免这样情况,可以把这些字段的初始化放到一个无参构造方法内,其他的构造方法显式调用无参构造方法。
3、初始化类的字段有两种方法,①使用简化语法,在定义的时候初始化;② 在构造方法内初始化。使用简化语法初始化的代码,会被搬到构造方法内。特别注意,在生成的IL中,父类构造方法会夹在 ①和②之间。因此,实例化子类的时候,会先执行①,再执行父类构造方法,然后执行②。现在问题来了,假如在父类构造方法内,调用虚方法,虚方法回调子类的方法,子类方法使用字段,这时候字段的值是简化语法初始化的值。
C# 实例化类的执行顺序的更多相关文章
- java类的初始化程序块以及被实例化时候的执行顺序
初始化块:在类实例化过程中初始化执行顺序是先执行静态初始化块,然后执行普通初始化块,最后执行构造函数,而且静态初始化只在第一次被实例化时执行且只执行一次.public class HelloWorld ...
- Java类的执行顺序
在Java中一个类包括:构造块.构造方法.静态块.main方法.普通方法. 通过下面的例子将看出一个类中各种方法的执行顺序: /** * @author zhengbinMac */ public c ...
- [1]朝花夕拾-JAVA类的执行顺序
最近在温习java的基础,刷题刷到java的执行顺序,很汗颜,答案回答错了! 题目类似如下: package com.phpdragon.study.base; public class ExecOr ...
- C# 基类派生类构造函数执行顺序分析
using System; namespace ConsoleApp1 { class Program{ static void Main(string[] args){ B b = new B(); ...
- 深入了解Java程序执行顺序
Java中main方法,静态,非静态的执行顺序详解 Java程序运行时,第一件事情就是试图访问main方法,因为main相等于程序的入口,如果没有main方法,程序将无法启动,main方法更是占一个独 ...
- UIViewController的生命周期及iOS程序执行顺序 和ios6 处理内存警告
当一个视图控制器被创建,并在屏幕上显示的时候. 代码的执行顺序1. alloc 创建对象,分配空间2.init (initWithN ...
- Java静态变量、静态块、构造块、构造函数、main函数、普通代码块的执行顺序
测试代码 public class SingleTest { public static String v = "StaticValue"; static { System.out ...
- Java代码执行顺序(静态变量,非静态变量,静态代码块,代码块,构造函数)加载顺序
//据说这是一道阿里巴巴面试题,先以这道题为例分析下 public class Text { public static int k = 0; public static Text t1 = new ...
- 图示Java类的初始化顺序
Java类的初始化顺序 在开发中,知道Java类的初始化顺序才能让我们更加清楚地掌握程序的执行流程.先把结论贴出来,Java里,从图里的1~6,分别按顺序执行. 以下为代码验证阶段,一共三个类 ...
随机推荐
- intellIJ IDEA配置maven相关问题记录
IntellIJ IDEA 配置 Maven 以及 修改 默认 Repository 参考:https://www.cnblogs.com/phpdragon/p/7216626.html non-m ...
- 接口测试中抓包工具Charles的使用
在被测接口并没有明确的接口文档给出时,我们需要借助抓包工具来帮助测试,利用抓包工具我们几乎可以获得接口文档中能给你的一切.常见的抓包工具有Charles和Fiddler, Fiddler只能用在Win ...
- OpenGL(2)-窗口
写在前面 通过本节,你可以毫不费力的--->创建一个窗口 OpenGL中窗口,即载体 导入头文件 #include <glad/glad.h> #include <GLFW/g ...
- SICP读书笔记 3.1
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- Netty源码分析第6章(解码器)---->第4节: 分隔符解码器
Netty源码分析第六章: 解码器 第四节: 分隔符解码器 基于分隔符解码器DelimiterBasedFrameDecoder, 是按照指定分隔符进行解码的解码器, 通过分隔符, 可以将二进制流拆分 ...
- yocto-sumo源码解析(十): ProcessServer.idle_commands
这一节开始介绍ProcessServer.idle_commands,前面我们知道ProcessServer.main就是不停调用idle_commands()以获取可用的套接字描述符或者是文件描述符 ...
- centos 切换用户显示bash-4.2$,不显示用户名路径的问题
原文链接: http://blog.csdn.net/testcs_dn/article/details/70482468
- comet4j推送 405/500 JSON转换异常
因为Comet4J工作在NIO方式下,所以我们需要调整服务器连接器配置,更换为NOI连接器. 打开server.xml文件将找到原先的连接器配置: <Connector executor=&qu ...
- 项目Beta冲刺(团队)第三天
1.昨天的困难 记住密码打勾之后点击登录记住密码这四个字会变成省略号 点赞点击以后本应该呈现的爱心形状变成了方块 2.今天解决的进度 成员 进度 陈家权 私信模块探索ing,回复详情界面设计 赖晓连 ...
- 第一个spring冲刺第二天
讨论成员:王俊凯.罗凯杰.王逸辉.马志磊 地点:宿舍 话题:讨论关于安卓的控件的应用和如何调用 选题:四则运算 方向:更加实用的计算器功能,功能更加实用并且简单,没有太多的繁琐操作,可以的话会加上些趣 ...