遇到的问题一:单例模式及由此引发的静态方法与静态变量的问题

来源:互联网 发布:诺基亚e63下载软件 编辑:程序博客网 时间:2024/05/16 12:29
    实现数据库连接池,单例模式是必不可少的,因为连接池本身需要被大量地方用到,而连接池中的连接应该是共享的,所以至少连接池中保存连接的List需要是静态模式,如此一来,不如将连接池的主类实现为单例模式,这样后续开发代码能易读一些。

    在实现单例的连接池主类时,我遇到了一个不大不小的问题,下面是有问题的代码:

List<ConnectionStructon> connectionStructs = new List<ConnectionStructon>();
private static readonly Pool pool = new Pool();private Pool(){    Init();}private static Void Init(){    //一些初始化操作,包括一些参数和按照配置文件生成一定数量的ConnectionStructon添加到List中}
public static ConnectionStructon getConnectonStructon()
{
//得到连接构造体
}

    上面的代码是有问题的,当我在测试类中使用getConnectionStructon()方法时,connectionstructs是没有被初始化的。

    我知道静态方法和静态参数会先于构造函数被执行,但是在我看来,因为我在类的内部静态的实例化了他本身,所以当我调用getConnectionStructon方法时,私有化的构造函数应该已经被执行了,所以Init()应该是已经运行过,所以pool类的各种初始化操作应该是已经执行完毕了,但在实际测试时,这里是报错的,通过查看报错信息,我发现connectionStructs没有被初始化完全,里面并没有被加入连接。

    于是经过查资料和各种测试,原来,静态变量会先于静态方法被执行,而在类的内部实例化它本身时,实际上,CLR会自动生成一个静态构造函数

static Pool(){}

    所以,其实当执行private static readonly Pool pool = new Pool();这段代码时,并没有如我想象的执行了private Pool(),而是执行了一个我们看不见的static Pool();

    知道了原因,所以我想到的解决方法是,重写静态构造函数

static Pool(){    Init();}


    如此一来,这个问题算是解决了,可以在外部通过Pool.GetConnectionStructon()来得到连接,但是此处又引申出一个问题,因为当只有私有化的构造函数时,在外部是不能实例化Pool类的,在外部实例化Pool类:Pool pool = new Pool();时会报一个构造函数是受保护类型的异常,如此一来,就保证了Pool的单例化。但是当我将构造函数改为静态时,外部就可以实例化Pool类了,这违反了单例的原则,虽说在本项目中,Pool是否单例并不重要,只要可以共享ConnectionStructons即可,但我看着不爽,继续查资料和测试,发现原来static Pool()和private Pool()是可以共存的,所以修改代码如以下所示:

 /// <summary>        /// 单例模式的连接池        /// </summary>                static Pool()        {                        Init();        }        private Pool(){}

    问题解决。

    结论,C#中,单例模式实现方法为:

//内部私有静态实例化private static readOnly Class class = new Class();//静态构造函数static Class(){//一些操作}//私有化构造函数,防止类在外部被实例化private Class(){}




 

0 0
原创粉丝点击