C#-关于带参数的单例模式的思考(利用带参数的单例模式连接并查询数据库特定表的信息)

首先,让我们看一下单例模式是怎样的。

    public sealed class Singleton
    {
        private static Singleton instance = null;
        private static readonly object padlock = new object();

        Singleton()
        {
        }

        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (padlock)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
        }
    }

这是<<C# in Depth>>这本书中提供的标准代码。

实现单例模式的思路是:

  1. 定义一个密封类(sealed)以避免其它类继承此类(据书中所说此举虽然不是必要的,但可以帮助JIT进行更多优化)。
  2. 定义并初始化该类自身的静态实例(instance)为null,用该instance来检测控制在创建单例模式的类的程序中只有一个该类的实例。
  3. 定义并初始化一个只读(readonly)的用于锁(lock)的object对象以满足多线程环境。
  4. 创建一个只有get方法的该类的静态变量,用于创建该类的实例。
  5. 最后在该类的构造函数中写入相关代码。

可以看到整个过程中并未传入参数。

考虑以下问题:

如果我用单例模式连接并查询数据库单个表的所有信息,但数据库中有很多表,我想往单例模式中传入参数怎么办?

看以下代码:

public sealed class Database
    {
        private static Database _instance = null;
        private static readonly object _Object = new object();
        private string conString = "connection string";
        private Database(string tableName, DataTable dt)
        {
            using (SqlConnection Conn = new SqlConnection(conString))
            {
                Conn.Open();
                string sql = "select * from " + tableName;
                using (SqlCommand cmd = new SqlCommand(sql))
                {
                    using (SqlDataAdapter da = new SqlDataAdapter())
                    {
                        cmd.CommandType = CommandType.Text;
                        cmd.Connection = Conn;
                        da.SelectCommand = cmd;
                        da.Fill(dt);
                    }
                }
            }
        }
        public static Database GetInstance(string tableName, DataTable dt)
        {
            if (_instance == null)
            {
                lock (_Object)
                {
                    if (_instance == null)
                    {
                        _instance = new Database(tableName, dt);
                    }
                }
            }
            return _instance;
        }
    }
            DataTable dt = new DataTable();
            Database.GetInstance("MyTable",dt);
            Database.GetInstance("MyTable2", dt);
            dataGridView1.DataSource = dt;

由于单例模式,DataGridView中将只显示‘MyTable’的信息。

问题虽然得到解决,但单例模式通常提供对该实例的简单访问,是否使用工厂模式会有更合适呢?

待续...

原文地址:https://www.cnblogs.com/xingyz/p/12151055.html

时间: 2024-08-03 07:41:08

C#-关于带参数的单例模式的思考(利用带参数的单例模式连接并查询数据库特定表的信息)的相关文章

C#编程总结(五)多线程带给我们的一些思考

C#编程总结(五)多线程带给我们的一些思考 如有不妥之处,欢迎批评指正. 1.什么时候使用多线程? 这个问题,对于系统架构师.设计者.程序员,都是首先要面对的一个问题. 在什么时候使用多线程技术? 在许多常见的情况下,可以使用多线程处理来显著提高应用程序的响应能力和可用性. 上一章,我们讲了几个多线程的应用案例,主要的应用场景也做了介绍.这里不再赘述. http://www.cnblogs.com/yank/p/3232955.html 2.如何才能保证线程安全? 使用多线程,这是一个必须要弄清

XAF 框架中,自定义参数动作(Action),输入参数的控件可定义,用于选择组织及项目

XAF 框架中,如何生成一个自定义参数动作(Action),输入参数的控件可定义? 参考文档:https://documentation.devexpress.com/eXpressAppFramework/113183/Task-Based-Help/Actions/How-to-Customize-Action-Controls 示例 XAF 安装中带的 示例方案: Feature Center 默认安装在 :%PUBLIC%\Documents\DevExpress Demos 17.1\

oracle入门(8)——实战:支持可变参数、多种条件、多个参数排序、分页的存储过程查询组件

[本文介绍] 学了好几天,由于项目需要,忙活了两天,写出了个小组件,不过现在还只能支持单表操作.也没考虑算法上的优化,查询速度要比hibernate只快了一点点,可能是不涉及多表查询的缘故吧,多表的情况下才更快. 经非专业的测试,在有分页的情况下,在300万条数据里面查询的时间保持在0.1秒内.相同查询条件+分页的情况下,hibernate 用时0.3秒内. 不分页的条件下,查出来的数据越多,时间越长,时间长的话,跟hibernate相相比就没什么优势了. [思路] 我的思路是从java传来”字

JVM实用参数(三)打印所有XX参数及值

JVM实用参数(三)打印所有XX参数及值 原文地址:https://blog.codecentric.de/en/2012/07/useful-jvm-flags-part-3-printing-all-xx-flags-and-their-values/ 译者:李洪柱     校对:方腾飞 本篇文章基于Java 6(update 21oder 21之后)版本, HotSpot JVM 提供给了两个新的参数,在JVM启动后,在命令行中可以输出所有XX参数和值. -XX:+PrintFlagsFi

(一)Python入门-5函数:06参数类型-位置参数-默认值参数-命名参数-可变参数-强制命名参数

参数的几种类型: 位置参数: 函数调用时,实参默认按位置顺序传递,需要个数和形参匹配.按位置传递的参数,称为: “位置参数” 默认值参数: 我们可以为某些参数设置默认值,这样这些参数在传递时就是可选的.称为“默认值参数”. 默认值参数放到位置参数后面. 命名参数: 我们也可以按照形参的名称传递参数,称为“命名参数”,也称“关键字参数”. 可变参数: 可变参数指的是“可变数量的参数”.分两种情况: 1. *param(一个星号),将多个参数收集到一个“元组”对象中. 2. **param(两个星号

创建函数利用可变参数列表的形式模拟实现printf的功能

★创建函数利用可变参数列表的形式模拟实现printf的功能. 模拟简单的输入单个字符和字符串时的输出形式 如:输入:%c %c %c %c %c\t%s,'h','e','l','l','o',"welcome to here!" 输出:h e l l o   welcome to here! #include<stdio.h> #include<stdlib.h> #include<stdarg.h>    //需引入stdarg的头文件以便建立可

让不带www的域名跳转到带www的域名

域名不带www和带www不是同一码事:前者称作根域名,后者是前者的二级域名.长久以来,人们都习惯了访问网站的时候带上www,所以大多数站长朋友域名解析的时候都是带www的和不带www的一起解析.然而对于搜索引擎来说,还是会给你区分2个域名的,站在seo的角度来看,我们最好是把不带www的域名301定向到带www的域名去,以防止权重流失.下面介绍Nginx和Apache下的301定向方法 nginx下的301重定向方法 if ($http_host !~ “^www.coolfish.cn$”)

C++ 为什么拷贝构造函数参数必须为引用?赋值构造函数参数也必须为引用吗?

之前写拷贝构造函数的时候,以为参数为引用,不为值传递,仅仅是为了减少一次内存拷贝.然而今天看到一篇文章发现自己对拷贝构造的参数理解有误. 参数为引用,不为值传递是为了防止拷贝构造函数的无限递归,最终导致栈溢出. 下面来看一个例子: class test { public: test() { cout << "constructor with argument\n"; } ~test() { } test(test& t) { cout << "

MSSQL报错:参数数据类型 text 对于 replace 函数的参数 1 无效的解决办法

Ms - sql 数据库批量替换字符串 MSSQL报错:参数数据类型 text 对于 replace 函数的参数 1 无效的解决办法 update ContentInfo set spcContent=replace(cast(spcContent as varchar(max)),'http://www.buy5188.com/','http://www.epowerchina.com.cn/')