首页 > Windows开发 > 详细

从构造函数说开去---C#本质论读书笔记

时间:2015-02-24 20:54:59      阅读:396      评论:0      收藏:0      [点我收藏+]

记得一年之前在写代码的时候问了小伙伴一个问题,我说:“你说如果我在声明的时候初始化,它会在对象初始化的哪个阶段被赋值?” 小伙伴想了想回答我:“还是在构造函数里面给变量初始化吧。” 程序当口,时间比较紧,没有空去验证一下这个问题,后来也就慢慢淡忘了。

这个假期翻开“C#本质论”正好里面也提到了这种情况,虽然只是一笔带过,但是也勾起了我的回忆,那今天就来记录一下这个疑问以及它延伸出来的一些知识点。

1、普通构造函数

 

    public class ConstructionTest
    {
        int intPro = 1;

        public ConstructionTest()
        {
        }
    }

当一个实例字段在声明时赋值,其实编译器在处理的时候声明时赋值的位置被移动了,成为构造函数中的第一个语句。代码类似于以下的代码(如果有兴趣可以编译后查看IL):

     public class ConstructionTest
    {
        int intPro;

        public ConstructionTest()
        {

     intPro = 1;
        }
    }

那么如果变量即在声明时进行了赋值,又在构造函数中赋值,那会是怎样的情况呢?答案就是:构造函数中的赋值会覆盖声明时初始化的值。代码类似于如下的代码:

public class ConstructionTest
    {
        int intPro;

        public ConstructionTest(int value)
        {

     intPro = 1;//声明时赋值

     intPro = value;//构造函数中赋值
        }
    }

所以,最好是在构造函数中给字段进行初始化工作,尤其是在团队协作开发的时候,大家都遵循相同的开发规范和准则对于复杂的项目来说非常重要。

2、静态构造函数

静态构造函数每一本C#的相关数据都会阐述一边其特点,比如:每个类只能有一个,声明时没有可见性的修饰符,必须用static进行修饰,并且不允许有参数。当然,类似普通的构造函数,它在构造函数内的初始化会覆盖其声明时初始化的内容。

那么在这里要记录的一些知识点是:1)静态构造函数调用的特点:不是显示调用,而是‘运行时’在首次访问类时自动调用的,而且只会被调用一次。所谓‘首次访问’,可能是调用一个普通构造函数,也可能是访问类的一个静态方法或者字段。正是由于静态构造函数的这个特点,我们可以用它来解决Singleton模式中多线程情况下创建实例的问题。具体代码会在下面进行展示。2)关于静态初始化的建议:(原文)“尽量在声明的同时完成静态初始化。静态构造器是在首次访问类的任何成员之前执行的,无论该成员是静态字段或者是静态方法,或者是其他的构造函数。为了提供对这一行为的支持,编译器会自动插入一些负责检查的代码。这些代码会检查所有类型的静态成员和构造器,确保静态构造器能够先运行。但是,如果没有静态构造器,编译器就会将所有静态成员初始化为他们的默认值,而且不会添加任何静态构造器的检查。这样造成的结果就是,只要访问任何静态字段,就会进行静态成员的赋值和初始化。但是,并不是说只有完成了赋值和初始化,才能调用静态方法和实例构造器。有的时候,静态成员进行初始化的代价可能比较高,采用上述的设计,除非要访问一个静态字段,否则不需要对其进行初始化。但初始化静态成员可以在一定程度上提升性能。”这个建议很中肯,C#本质论里最引人注目的就是这几段的所谓的“高级主题”。

利用静态变量的特点,静态构造函数特点实现的Singleton模式:

public sealed class Singleton 
{ 
   private static readonly Singleton instance; 
   private Singleton(){} 
  static Singleton()
  {
    instance = new Singleton();
} public static Singleton Instance { get { return instance; } } }
Singleton模式应该是最基础也最耳熟能详的设计模式了,另外的一种加锁的实现方式也很简单,大家可以参考链接:https://msdn.microsoft.com/zh-cn/library/ff650316.aspx

构造函数到这里就说完了,那么接下来还有一点点,就是new运算符。很多人解释过new运算符对实例的创建过程,比如说‘你必须知道的.net‘里非常细致的解释了这个过程,没有看过的朋友建议博客园里搜一下看看,当然最好是买本书慢慢品味。
但是我看到了‘C#本质论’里面的描述之后,不禁感叹写得透彻。虽然还是没有那么‘深入’(没有列出IL),但是轻描淡写之间清晰的勾画出来new运算符和构造器之间交互的过程:new运算符从内存管理器获取内存,然后调用制定的构造器,将初始化好的内存传给构造器。接着构造器链剩余的部分开始执行,
在构造器之间传递初始化好的内存。这些构造器都没有返回值(都返回void),构造器链上的执行结束后,new运算符返回内存饮用,它指向的内存处于初始化好的形式。

构造器的内容就这里,还有一些我感兴趣的内容会陆续整理出来,有些还有疑问可能还要跟小伙伴讨论讨论,不管怎么样写博客确实是体力活,而且格式什么的还还有点小烦人。向那些已经写了很多的同行们致敬,感谢你们的分享。

 

 

从构造函数说开去---C#本质论读书笔记

原文:http://www.cnblogs.com/chyewei/p/4298939.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!