框架源码学习

2008-08-07 13:33:46.0     浏览:1500     来源:中国IT实验室
关键词:  .Net Framework     框架源码  
第二种:
1.当我们对类实例化的时候,如果类里面的静态成员还未初始化,那么这个类的所有静态成员依据在类里面出现的次序初始化.
2.为静态成员分配内存空间,此时空间存储数据为0或null
3.执行静态成员的初始化语句(也就是赋值语句)
4.执行类的静态构造函数
5. 为普通成员分配内存空间,此时空间存储数据为0或null
6.执行普通成员的初始化语句(也就是赋值语句)
7. 执行类的构造函数

很明显,这样的话如果我们第二次实例化类,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,单件模式是用不好的.滥用误用更是不在话下.

接下来就正式来说单件模式吧! (只允许实例化一次)
1)第一种单件模式
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 s1 = Singleton.Instance;
Singleton s2 = Singleton.Instance;
s1.DoSomething();//做些事情
s2.DoSomething();//做些事情
Console.WriteLine(object.ReferenceEquals(s1, s2));//是否为相同实例,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
1public sealed class Singleton
2{
3 private static Singleton _instance;
4
5 private Singleton()
6 { }
7
8 public static Singleton Instance
9 {
10 get
11 {
12 if (_instance == null)
13 {
14 _instance = new Singleton();
15 }
16 return _instance;
17 }
18 }
19
20 public void DoSomething()
21 {
22 Console.WriteLine("做些事情");
23 }
24}
代码也很清晰,但该单件模式只适用于单线程.不适合与多线程
为什么呢?
线程1取Singleton.Instance执行到第12行if(_instance == null) 成立进入停下
线程2取Singleton.Instance执行到第12行if(_instance == null) 也同样成立
进入执行第14行_instance = new Singleton() 设为obj1 停下
线程1继续执行同样执行第14行_instance = new Singleton() 设为obj2
obj1与obj2是不同.已经不是单件,是双件了,线程越多,可能多件都有可能.

这样的话,很多朋友马上会相到把 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即双检查,会大大提高效率.
那就进入第四种单件模式.
[上一页]   [第1页]   [第2页]   [第3页]   [第4页]   [下一页]