rex的博客
博客园
::
首页
::
新随笔
::
联系
::
订阅
::
管理
::
21 随笔 :: 0 文章 :: 58 评论 :: 0 引用
C#2.0 Singleton 的实现
利用c#2.0的范型加上一点反射,构造了一个自认为不错的Singleton实现.
public
class
Singleton
<
T
>
{
protected
Singleton()
{
//
Assert class T don't have public constructor
//
Assert class T have a private/protected parameterless constructor
}
protected
static
T _instance;
public
static
T Instance()
{
//
Assert class T don't have public constructor
//
Assert class T have a private/protected parameterless constructor
//
Assert class T is not abstract and is not an interface
if
(_instance
==
null
)
{
_instance
=
(T)Activator.CreateInstance(
typeof
(T),
true
);//use reflection to create instance of T
}
return
_instance;
}
public
void
Destroy()
{
_instance
=
default
(T);
}
}
使用也很方便;例如
class
Foo
{
private
Foo()
//
must declare,or assert will fail in the singleton class
{
}
public
void
Bar()
{
}
}
void
Test()
{
Singleton
<
Foo
>.Instance()
.Bar();
}
甚至可以这样定义一个类:
public
class
Foo : Singleton
<
Foo
>
{
protected
Foo()
//
must declare
{
}
public
void
Bar()
{
}
}
void
Test()
{
Foo.Instance().Bar();
}
绿色通道:
好文要顶
关注我
收藏该文
与我联系
posted on 2006-01-12 17:46
rex
阅读(4347)
评论(28)
编辑
收藏
评论
1175278
#1楼
2006-01-13 13:54
旻
不错,有点意思。
回复
引用
查看
#2楼
2006-01-13 14:31
edison1024
_instance = System.Activator.CreateInstance<T>();
回复
引用
查看
#3楼
2006-01-13 17:38
rexz[未注册用户]
Activator.CreateInstance<T>()不带任何参数,因此它不能访问保护或者私有的constructor.而希望成为singleton的class必须没有public的构造函数,否则就不能保证用户不会调用new来构造一个实例
回复
引用
#4楼
2006-04-05 09:55
newhappy[未注册用户]
太花绍了
回复
引用
#5楼
2006-04-05 09:56
newhappy[未注册用户]
而且 thread safe方面 么作
回复
引用
#6楼
2006-04-27 06:27
deadnight[未注册用户]
坦白的说.....这是一个非常糟糕的实现.......
回复
引用
#7楼
2006-04-30 10:46
flyaway00[未注册用户]
很精彩。
回复
引用
#8楼
2006-05-14 11:10
Andrew Xu[未注册用户]
为什么要写用 Activator?直接写:
_instance = new T();
就可以了。当然需要加一个模板参数约束:
where T: new()
回复
引用
#9楼
2006-05-14 23:42
rexz[未注册用户]
@Andrew Xu
我希望T的new是私有的,否则用户就可能破坏Singleton的设计本意,用new生成"第二个"实例
回复
引用
#10楼
2006-05-16 14:28
天下无双
精彩#@#@
回复
引用
查看
#11楼
2006-05-16 14:29
天下无双
糟糕在什么地方?@deadnight
回复
引用
查看
#12楼
2006-05-19 10:54
Andrew Xu[未注册用户]
@rexz
问题在于,即使是使用 Activator,仍然不能创建一个只有 private constructor 的对象,这是违反.NET 安全策略,并且会抛出异常的。
回复
引用
#13楼
[
楼主
]
2006-05-19 11:32
rex
@Andrew Xu
你试试就知道是可以的...反射可以获得所有私有/保护成员信息
回复
引用
查看
#14楼
2006-05-24 00:09
cokkiy[未注册用户]
为什么不用
_instance = new T();
呢?搞那么花哨?而且用Activator.CreateInstance访问保护成员是不是有问题?虽然反射可以访问保护/私有成员。
回复
引用
#15楼
2006-05-24 00:12
cokkiy[未注册用户]
补充一下:_instance = new T(); T()完全可以是私有或保护的成员啊。
回复
引用
#16楼
[
楼主
]
2006-05-24 11:45
rex
@cokkiy
无语,请自己写代码试一下吧
回复
引用
查看
#17楼
2006-05-26 12:41
lextm[未注册用户]
主要是没有了
lock(){
}
不知道是不是线程安全。
回复
引用
#18楼
[
楼主
]
2006-05-30 10:52
rex
@lextm
不安全.需要的话应该加上,我要表达的意思是用这种方式给一些类"注入"一些方法,让他们拥有其它功能:)
回复
引用
查看
#19楼
2006-06-07 14:11
fxltdwc[未注册用户]
什么花哨阿。先搞清楚单件模式在什么地方使用再说吧
回复
引用
#20楼
2006-06-11 13:16
winking[未注册用户]
不错的想法。可以考虑用继承.
public abstract class Singletion<T>
{
protected abstract T CreateInstace();
...
public static T Instance
{
get {
if (_instance == null)
{
_instance = CreateInstance();
}
return _instance;
}
}
}
public class Foo: Singleton<T>
{
protected override Foo CreateInstance()
{
//create object
}
}
回复
引用
#21楼
2006-06-12 11:42
Dengyangjun[未注册用户]
按照作者的想法,我来完善一个:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace Midapexsoft
{
/// <summary>
/// 单件模式Helper类
/// </summary>
/// <typeparam name="T">需要实现单件模式的类型。必须有一个默认的无参构造函数</typeparam>
public abstract class Singleton<T>
{
private static T instatnce;
private static Object o = new object();
public static T Instance
{
get
{
if (instatnce == null)
{
lock (o)
{
if (instatnce == null)
{
//需要使用非公共的无参构造函数,不能使用new T(),因为它不支持非公共的无参构造函数
instatnce = (T)Activator.CreateInstance(typeof(T), true);
}
}
}
return instatnce;
}
}
}
}
回复
引用
#22楼
2006-06-18 21:38
flysnow[未注册用户]
public class Foo
{
public static Foo instance = new Foo();
protected Foo() { }
}
这样岂不是很简单
回复
引用
#23楼
2006-07-13 11:04
littlestone
一个好的单件模板实现是一个非常复杂的问题,楼主可参考网上相关讨论,或<<modern C++ design>>(译名:C++设计新思维),相信会给楼主带来很刺激的技术冲击.
回复
引用
查看
#24楼
[
楼主
]
2007-03-12 21:48
rex
@littlestone
这本书我已经看过很多年了:)
回复
引用
查看
#25楼
2007-06-07 17:11
Richard[未注册用户]
Dengyangjun ,用你说的继承方法好像不行吧,CreateInstance()是abstract,不是static,不能从Static的Instance property中调用,把CreateInstance()做成static,又失去了使用继承的意义,不知道我说的对不对
回复
引用
#26楼
2007-08-02 11:32
orichisonic[未注册用户]
有点花,玩了技术点
回复
引用
#27楼
2008-01-24 14:39
WOW玩家
///
/// Singleton泛型类
///
///
public sealed class Singleton< T > where T : new()
{
private static T instance = default(T);
private static object lockHelper = new object();
private Singleton() { }
public static T GetInstance()
{
if (instance == null)
{
lock (lockHelper)
{
if (instance == null)
{
instance = new T();
}
}
}
return instance;
}
public void SetInstance(T value)
{
instance = value;
}
}
回复
引用
查看
#28楼
2008-04-28 22:42
Stanley.Luo
哪里要这么复杂.
将instance 声明为static readonly 就解决问题了,既保证单例,也保证线程安全。
protected static readonly T _instance = new T();
public static T Instance()
{
return _instance;
}
这个方法来自《大话设计模式》
回复
引用
查看
注册用户登录后才能发表评论,请
登录
或
注册
,
返回博客园首页
。
首页
博问
闪存
新闻
园子
招聘
知识库
最新IT新闻
:
·
Twitter联合创始人:长时间用Twitter不利健康
·
盛大文学重启赴美IPO计划拟融资2亿美元
·
谷歌招聘揭秘:入职就像进入美军海豹突击队
·
诺基亚超HTC成第一大Windows Phone手机商
·
Google Voice支持圈子功能:可用于过滤来电
»
更多新闻...
最新知识库文章
:
·
领域模型管理与AOP
·
编程的艺术:漂亮的代码和漂亮的软件
·
GIT分支管理是一门艺术
·
编程:是一门艺术
·
编程是一门艺术吗?
»
更多知识库文章...
China-pub 2011秋季教材巡展
China-Pub 计算机绝版图书按需印刷服务
<
2006年1月
>
日
一
二
三
四
五
六
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
公告
昵称:
rex
园龄:
6年7个月
粉丝:
0
关注:
0
搜索
常用链接
我的随笔
我的评论
我的参与
最新评论
我的标签
我的标签
webOS
(2)
TouchPad
(2)
App
(1)
随笔档案
2012年2月 (1)
2011年7月 (2)
2011年6月 (1)
2009年9月 (1)
2009年1月 (1)
2008年5月 (1)
2006年7月 (1)
2006年4月 (1)
2006年1月 (1)
2005年12月 (3)
2005年9月 (3)
2005年7月 (4)
2005年6月 (1)
最新评论
阅读排行榜
评论排行榜
推荐排行榜