知识大全 .Net Framework框架源码学习

Posted

篇首语:勤劳一日,可得一夜安眠;勤劳一生,可得幸福长眠。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 .Net Framework框架源码学习相关的知识,希望对你有一定的参考价值。

.Net Framework框架源码学习  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  Singleton模式 由于其实现相对简单 所以号称设计模式中最简单的模式   但是static通常会给你造成一些障碍 不信啊 那你就看看吧 而且还有几个Effective C#条款 :) 希望不会让你失望                该篇并没有涉及到 Net Framework源码 就算是挂羊头卖狗肉吧 希望延续上篇的高质量   让我们先来写个简单的SqlHelper吧 封装SQL数据库的操作      using System;   using System Data;   using System Data SqlClient;      namespace APeng      public class SqlHelper       private string m_connString = Data Source=(local); +    User ID=sa;Password=password;Initial Catalog=discuz;Pooling=true ;    //Sql数据库连接字符串       public SqlDataReader ExecuteReader(CommandType cmdType string cmdText params SqlParameter[] cmdParms)    SqlCommand cmd = new SqlCommand();    SqlConnection conn = new SqlConnection(m_connString);       try       PrepareCommand(cmd conn cmdType cmdText cmdParms);    SqlDataReader rdr = cmd ExecuteReader(CommandBehavior CloseConnection);    cmd Parameters Clear();    return rdr;       catch (Exception ex)       conn Close();    conn Dispose();    throw ex;             private void PrepareCommand(SqlCommand cmd SqlConnection conn CommandType cmdType string cmdText SqlParameter[] cmdParms)          if (conn State != ConnectionState Open)    conn Open();       cmd Connection = conn;    cmd CommandText = cmdText;    cmd CommandType = cmdType;       if (cmdParms != null)       foreach (SqlParameter parm in cmdParms)    cmd Parameters Add(parm);                 这段代码大家应该很熟悉了 接下来让我们来使用它         using System;   using System Data;   using System Data SqlClient;      namespace APeng      class Program       static void Main(string[] args)       SqlHelper helper = new SqlHelper();    string cmdText = select fid name from dnt_forums ;    using (SqlDataReader reader = helper ExecuteReader(CommandType Text cmdText null))       while (reader Read())       Console WriteLine( 编号: + reader[ fid ]);    Console WriteLine( 名称: + reader[ name ]);             Console Read();                                    程序正常输出: 编号: 名称:版块 编号: 名称:版块   很简单 不是嘛      接下来我们将要优化这个SqlHelper   一) 将SqlHelper中的private string m_connString = 修改成 private static readonly string m_connString =                这个修改是否有必要呢? (如果没能给我带来什么好处 我为什么要修改呢 所以你得说服我!)               小菜先在A地方实例化一个SqlHelper   SqlHelper helper = new SqlHelper();   那么会有如下构造过程:   为数据成员m_connString分配内存空间 此时空间存储数据为null    (如果是值类型如int float double等 空间存储数据为 如果是引用类型空间存储数据为null 下面还会详细说明)   执行数据成员m_connString的初始化语句 也就是上面的private string m_connString =    (那么现在空间存储数据为 )   执行SqlHelper的构造函数      小菜然后在B地方又实例化一个SqlHelper   SqlHelper helper = new SqlHelper();   那么会有如下构造过程:   为数据成员m_connString分配内存空间 此时空间存储数据为null   执行数据成员m_connString的初始化语句 也就是上面的private string m_connString =    (那么现在空间存储数据为 )   执行SqlHelper的构造函数               噢 有没有搞错啊 怎么一直为m_connString分配内存空间   而且老是把m_connString空间存储数据置为相同的   该死的 你就不能聪明点 做一次就够了 (浪费我们宝贵的时间和宝贵的内存资源)               唉 看来我们得自己动手优化了 怎么优化呢?   等等 小菜刚才说什么来着?修改成private static readonly string m_connString =   那它能改变这种状况吗?               小菜先在A地方实例化一个SqlHelper   SqlHelper helper = new SqlHelper();   那么会有如下构造过程:   为静态数据成员m_connString分配内存空间 此时空间存储数据为null    (如果是值类型如int float double等 空间存储数据为 如果是引用类型空间存储数据为null 下面还会详细说明)   执行静态数据成员m_connString的初始化语句 也就是上面的private static readonly string m_connString =   (那么现在空间存储数据为 )   执行SqlHelper的构造函数               小菜然后在B地方又实例化一个SqlHelper   SqlHelper helper = new SqlHelper();   那么会有如下构造过程:   执行SqlHelper的构造函数        

  看来真不错 变聪明了 只分配了一次m_connString的内存空间 只初始化了一次m_connString   看来多亏了static                注意:这里应该引起你的关注   有一些朋友的代码中时常出现为值类型成员赋 为引用类型赋null   public class Person//人类      private int _age = ;//年龄     或者   public class Person//人类      private Address _address = null;//地址对象               这其实是无必要的 和上面new SqlHelper()的构造过程一样 在分配数据成员的内存空间时 便会为值类型成员赋 为引用类型赋null.如果我们显示的赋值的话 不但没有任何帮助 反而会增加指令的操作 影响效率.   Effective C# 中有介绍               其实上面主要的知识点是对象的构造过程 让我们来复习一下吧   第一种:   1.当我们调用类里的静态方法时 如果类里面的静态成员还未初始化 那么这个类的所有静态成员依据在类里面出现的次序初始化.   2.为静态成员分配内存空间 此时空间存储数据为 或null   3.执行静态成员的初始化语句(也就是赋值语句)   4.执行类的静态构造函数      很明显 这样的话如果我们第二次调用类里的静态方法时 1 2 3 4都不会被执行了.        

  第二种:   1.当我们对类实例化的时候 如果类里面的静态成员还未初始化 那么这个类的所有静态成员依据在类里面出现的次序初始化.   2.为静态成员分配内存空间 此时空间存储数据为 或null   3.执行静态成员的初始化语句(也就是赋值语句)   4.执行类的静态构造函数   5 为普通成员分配内存空间 此时空间存储数据为 或null   6.执行普通成员的初始化语句(也就是赋值语句)   执行类的构造函数      很明显 这样的话如果我们第二次实例化类 1 2 3 4也都不会被执行 只会执行5 6 7      二) 将public SqlDataReader ExecuteReader() 修改成 public static SqlDataReader ExecuteReader()   修改不修改关键看什么呢?   如果该方法无需保持或变动跟对象有关的状态 则说明该方法与任何实例无关 所以可设计成static方法   我们的ExecuteReader()满足上面条件 无需操持对象有关状态 而且无需变动跟对象有关的状态      三) 将public class SqlHelper 修改为 public static class SqlHelper   经过上面的修改后 我们的SqlHelper已经是一个合适工具类 它无需被实例化使用abstract 无需被继承使用sealed   可是没有public abstract sealed class SqlHelper 但有static 二者是等效的 称为静态类      Math类相信大家都用的很爽吧 比如Math Abs()取绝对值等方法   很明显Math也是做为一个工具类 所以在 Net中也被设计成静态类      注意:有些朋友要说了 那SqlHelper可不可以使用单件模式设计   可以 可是不合适 做为一个工具类 它根本无需被实例化 一次都不要   有些朋友要说了 讲单件模式讲到哪里去了都不知道 但小菜觉得区分不好static 单件模式是用不好的 滥用误用更是不在话下      接下来就正式来说单件模式吧! (只允许实例化一次)   )第一种单件模式   public sealed class Singleton      private static readonly Singleton _instance = new Singleton();       private Singleton()          public static Singleton Instance       get       return _instance;             public void DoSomething()       Console WriteLine( 做些事情 );        接下来 我们来用用测试一下   static void Main(string[] args)      Singleton s = Singleton Instance;    Singleton s = Singleton Instance;    s DoSomething();//做些事情    s DoSomething();//做些事情    Console WriteLine(object ReferenceEquals(s s ));//是否为相同实例 true     恩 不错 大家觉得上面的设计怎么样?   其一: 如果很看注性能的话 或者Singleton很浪费资源的话 使用lazy init会比较好一点 当需要用时才初始化    但通常上面的代码是够用的   其二: 由于静态成员的初始化时间很难控制 所以如果是静态引用类型的话 放在静态构造函数中初始化会更加适合    这里就用到了前面讲到的对象构造顺序 如果不清楚的话 建议拉到前面在看一下 很重要    这也是Effective C#中有介绍   所以代码修改为   public sealed class Singleton      private static readonly Singleton _instance;       private Singleton()          static Singleton()       _instance = Singleton();          public static Singleton Instance       get       return _instance;             public void DoSomething()       Console WriteLine( 做些事情 );        如果对性能不是太讲究的话 推荐该做法 而且适合多线程      二)第二种单件模式lazy init    public sealed class Singleton       private static Singleton _instance;       private Singleton()          public static Singleton Instance      get     if (_instance == null)     _instance = new Singleton();     return _instance;         public void DoSomething()     Console WriteLine( 做些事情 );       代码也很清晰 但该单件模式只适用于单线程 不适合与多线程   为什么呢?   线程 取Singleton Instance执行到第 行if(_instance == null) 成立进入停下   线程 取Singleton Instance执行到第 行if(_instance == null) 也同样成立    进入执行第 行_instance = new Singleton() 设为obj 停下   线程 继续执行同样执行第 行_instance = new Singleton() 设为obj   obj 与obj 是不同 已经不是单件 是双件了 线程越多 可能多件都有可能      这样的话 很多朋友马上会相到把 if(_instance==null)/*省略*/锁上 不就ok了   那就进入第三种单件模式      三)第三种单件模式   public sealed class Singleton      private static Singleton _instance;    private static object _lockHelper = new object();       private Singleton()          public static Singleton Instance       get       lock (_lockHelper)       if (_instance == null)       _instance = new Singleton();          return _instance;             public void DoSomething()       Console WriteLine( 做些事情 );        看来该单件模式支持多线程 但看来并不是太聪明      如果_instance已经被初始化 然后每次线程进入还是需要同步 很明显效率下降   我们只需要第一次初始化的时候同步 之后不要同步是最好的 效率也高   看来double check即双检查 会大大提高效率   那就进入第四种单件模式            四)第四种单件模式   public sealed class Singleton      private static Singleton _instance;    private static object _lockHelper = new object();       private Singleton()          public static Singleton Instance       get       if (_instance == null)       lock (_lockHelper)       if (_instance == null)       _instance = new Singleton();             return _instance;             public void DoSomething()       Console WriteLine( 做些事情 );        记得看到过有人这么问 为什么要双检查呢 为什么不改成如下代码?    public static Singleton Instance       get       if(_instance == null)       lock(_lockHelper)       _instance = new Singleton();       return _instance       那我们来分析一下   线程 执行到第 行停下来   线程 执行到第 行 因为线程 在lock里面 被阻塞 停下来   线程 继续执行第 行 初始化一个_instance设为obj 退出lock区   线程 进入lock里面 也初始化一个_instance设为obj 退出lock区   现在又是双件了 所以为什么要叫double check双检查 也是来源与此      这个单件模式被用的最多 但它就真的那么完美无缺吗? 不   因为上面的代码被编译 编译器由于考虑时间和空间的问题 会对代码进行优化 指令的顺序可能也会被改变   所以在多线程中可能还是会出状况 虽然这种概率很低 但要是有解决方法为什么不用呢?   那就来看第五种单件模式      五)第五种单件模式   public sealed class Singleton      private static volatile Singleton _instance;    private static object _lockHelper = new object();       private Singleton()          public static Singleton Instance       get       if (_instance == null)       lock (_lockHelper)       if (_instance == null)       _instance = new Singleton();             return _instance;             public void DoSomething()       Console WriteLine( 做些事情 );        小菜并没有做多少事 只是把private static Singleton _instance;修改为private static volatile Singleton _instance;   volatile关键字有这么大魔力? 对   编译器保证对此_instance的读写操作都不会被优化      接下来我们来讲个集万千宠爱与一生的单件模式   六)第六个单件模式      public sealed class Singleton      private Singleton()          public static Singleton Instance       get       return Nested instance;             public void DoSomething()       Console WriteLine( 做些事情 );          //嵌套类    private class Nested       internal static readonly Singleton instance;       private Nested()          static Nested()       instance = new Singleton();           return Nested instance保证了原子性   第一次执行它时   为Netsted的静态数据成员Singleton instance分配内存空间 存储空间的值为null   执行instance的静态初始语句 由于没有所以跳过   执行静态构造函数 执行 instance = new Singleton() 初始化instance   返回instance对象      很明显用到的知识还是前面的对象构造顺序 可见有多重要      到这里单件模式的多种实现都介绍完了 cha138/Article/program/net/201311/12086

相关参考

知识大全 让.Net 程序脱离.net framework框架运行

让.Net程序脱离.netframework框架运行  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 剖析.NET Framework框架[1]

剖析.NETFramework框架[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  大家一定

知识大全 剖析.NET Framework框架[2]

剖析.NETFramework框架[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! .NETF

知识大全 .NET Framework 3.0 框架慨述

.NETFramework3.0框架慨述  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!本文将简要介

知识大全 TOMCAT源码分析(启动框架)

TOMCAT源码分析(启动框架)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  前言  本文是我

知识大全 开源MVC框架 XX Framework 1.1 发布

开源MVC框架XXFramework1.1发布  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  X

知识大全 一印度学生Asp.net源码分享讨论

一印度学生Asp.net源码分享讨论  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n

知识大全 VS2008中查看.NET源码的设置方法

VS2008中查看.NET源码的设置方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在Vis

知识大全 使用eclipse调用.net web service

  以前我用的开发框架都是net现在换成javaEE框架和linux平台还需要一段时间的学习有时在测试工作中需要实现一些功能但是又不会用java实现怎么办呢?这里有一个方法使用net的框架开发webs

知识大全 .NET Framework介绍

ASP.NET开发宝典:.NETFramework介绍  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧