接下来我们将要优化这个SqlHelper
一) 将SqlHelper中的private string m_connString = "......" 修改成 private static readonly string m_connString = "......"
这个修改是否有必要呢? (如果没能给我带来什么好处,我为什么要修改呢,所以你得说服我!)
小菜先在A地方实例化一个SqlHelper.
SqlHelper helper1 = new SqlHelper();
那么会有如下构造过程:
1.为数据成员m_connString分配内存空间,此时空间存储数据为null
(如果是值类型如int,float,double等,空间存储数据为0,如果是引用类型空间存储数据为null,下面还会详细说明)
2.执行数据成员m_connString的初始化语句,也就是上面的private string m_connString = "......"
(那么现在空间存储数据为"......")
3.执行SqlHelper的构造函数
小菜然后在B地方又实例化一个SqlHelper.
SqlHelper helper2 = new SqlHelper();
那么会有如下构造过程:
1.为数据成员m_connString分配内存空间,此时空间存储数据为null
2.执行数据成员m_connString的初始化语句,也就是上面的private string m_connString = "......"
(那么现在空间存储数据为"......")
3.执行SqlHelper的构造函数
噢,有没有搞错啊,怎么一直为m_connString分配内存空间.
而且老是把m_connString空间存储数据置为相同的 "......"
该死的,你就不能聪明点,做一次就够了.(浪费我们宝贵的时间和宝贵的内存资源)
唉,看来我们得自己动手优化了.怎么优化呢?
等等,小菜刚才说什么来着?修改成private static readonly string m_connString = "......".
那它能改变这种状况吗?
小菜先在A地方实例化一个SqlHelper.
SqlHelper helper1 = new SqlHelper();
那么会有如下构造过程:
1.为静态数据成员m_connString分配内存空间,此时空间存储数据为null
(如果是值类型如int,float,double等,空间存储数据为0,如果是引用类型空间存储数据为null,下面还会详细说明)
2.执行静态数据成员m_connString的初始化语句,也就是上面的private static readonly string m_connString = "......"
(那么现在空间存储数据为"......")
3.执行SqlHelper的构造函数
小菜然后在B地方又实例化一个SqlHelper.
SqlHelper helper2 = new SqlHelper();
那么会有如下构造过程:
1.执行SqlHelper的构造函数
看来真不错,变聪明了,只分配了一次m_connString的内存空间,只初始化了一次m_connString.
看来多亏了static.
注意:这里应该引起你的关注.
有一些朋友的代码中时常出现为值类型成员赋0,为引用类型赋null
public class Person//人类
{
private int _age = 0;//年龄
}
或者
public class Person//人类
{
private Address _address = null;//地址对象
}
这其实是无必要的,和上面new SqlHelper()的构造过程一样.在分配数据成员的内存空间时,便会为值类型成员赋0,为引用类型赋null.如果我们显示的赋值的话,不但没有任何帮助,反而会增加指令的操作,影响效率.
Effective C# 中有介绍
其实上面主要的知识点是对象的构造过程,让我们来复习一下吧.
第一种:
1.当我们调用类里的静态方法时,如果类里面的静态成员还未初始化,那么这个类的所有静态成员依据在类里面出现的次序初始化.
2.为静态成员分配内存空间,此时空间存储数据为0或null
3.执行静态成员的初始化语句(也就是赋值语句)
这里的赋值代码会在编译的时候被移到静态构造函数中执行,可看本文的@Superstone的评论
4.执行类的静态构造函数
很明显,这样的话如果我们第二次调用类里的静态方法时,1,2,3,4都不会被执行了.
第二种:
1.当我们对类实例化的时候,如果类里面的静态成员还未初始化,那么这个类的所有静态成员依据在类里面出现的次序初始化.
2.为静态成员分配内存空间,此时空间存储数据为0或null
3.执行静态成员的初始化语句(也就是赋值语句)
这里的赋值代码会在编译的时候被移到静态构造函数中执行,可看本文的@Superstone的评论
4.执行类的静态构造函数
5. 为普通成员分配内存空间,此时空间存储数据为0或null
6.执行普通成员的初始化语句(也就是赋值语句)
这里的赋值代码会在编译的时候被移到构造函数中执行,可看本文的@Superstone的评论
7. 执行类的构造函数
很明显,这样的话如果我们第二次实例化类,1,2,3,4也都不会被执行,只会执行5,6,7