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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
只能生成一个实例的类是实现了Singleton(单例)模式的类。以下为C#实现单例模式的方式。
方式一只使用于单线程环境
// 把构造函数设为私有函数以禁止他人创建实例
// 定义一个静态的实例在需要的时候创建该实例
// 在Singlrton的静态属性Instance中只有在instance为null的时候才创建一个实例以避免
// 重复创建
// 把构造函数定义为私有函数
public
sealed
class
Singleton1
{
public
int
a = 2;
private
Singleton1() { }
private
static
Singleton1 instance =
null
;
public
static
Singleton1 Instance {
get
{
if
(instance ==
null
) instance =
new
Singleton1();
return
instance; } } } 方式二虽然在多线程环境中能工作但效率不高
// 每次通过属性Instance得到Singleton2的实例都会试图加上一个同步锁
// 而加锁是一个非常耗时的操作在没有必要的时候应该尽量避免
public
sealed
class
Singleton2
{
public
int
a = 2;
private
Singleton2(){}
private
static
readonly
object
syncObj =
new
object
();
private
static
Singleton2 instance =
null
;
public
static
Singleton2 Instance
{
get
{
lock
(syncObj)
{
if
(instance ==
null
)
instance =
new
Singleton2();
}
return
instance;
}
}
}
可行的解法 加同步锁前后两次判断实例是否已存在
// 只有instance为null即没有创建时需要加锁操作。
public
sealed
class
Singleton3
{
private
Singleton3() { }
private
static
readonly
Object syncObj =
new
Object();
private
static
Singleton3 instance =
null
;
public
static
Singleton3 Instance
{
get
{
if
(instance ==
null
)
{
lock
(syncObj)
{
if
(instance ==
null
)
instance =
new
Singleton3();
}
}
return
instance;
}
}
}
推荐的解法一利用静态构造函数
// 在初始化静态变量instance的时候创建一个实例
// 由于C#是在调用静态构造函数时初始化静态变量.NET运行时能够确保只调用一次静态构造
// 函数保证只初始化一次instance
public
sealed
class
Singleton4
{
private
Singleton4() { }
private
static
Singleton4 instance =
new
Singleton4();
public
static
Singleton4 Instance
{
get
{
return
instance;
}
}
}
推荐的解法二 实现按需创建实例
// 在内部定义了一个私有类型Nested。
// 当第一次用到这个嵌套类的时候会调用静态构造函数创建Singleton5的实例instance
public
sealed
class
Singleton5
{
private
Singleton5() { }
public
static
Singleton5 Instance
{
get
{
return
Nested.instance;
}
}
class
Nested
{
static
Nested() { }
internal
static
readonly
Singleton5 instance =
new
Singleton5();
}
}
扩展 定义一个表示总统的类型President可以从该类型继承出FrenchPresident 和AmericanPresident等类型。这些派生类型都只能产生一个实例
public
class
President
{
private
string
name =
""
;
private
string
country =
""
;
public
President() { }
public
string
Name
{
get
{
return
name; }
set
{ name = value; }
}
public
string
Country
{
get
{
return
country; }
set
{ country = value; }
}
}
public
sealed
class
FrenchPresident: President
{
private
FrenchPresident():
base
() { }
private
static
FrenchPresident instance =
new
FrenchPresident();
public
static
FrenchPresident Instance
{
get
{
return
(FrenchPresident)(Nested.instance); }
}
private
class
Nested
{
static
Nested() { }
internal
static
readonly
FrenchPresident instance =
new
FrenchPresident();
}
}
public
sealed
class
AmericanPresident : President
{
private
AmericanPresident() :
base
() { }
private
static
AmericanPresident instance =
new
AmericanPresident();
public
static
AmericanPresident Instance
{
get
{
return
Nested.instance; }
}
private
class
Nested
{
static
Nested() { }
internal
static
readonly
AmericanPresident instance =
new
AmericanPresident();
}
}
实现泛型单例模式
public
class
SingletonExample<T>
where
T :
class
,
new
()
{
public
static
T Instance
{
get
{
return
Nested.instance; }
}
private
class
Nested
{
static
Nested() { }
internal
static
readonly
T instance =
new
T();
}
}
public
class
Two: SingletonExample<Two>
{
public
int
a = 2;
public
void
Show()
{
Console.WriteLine(a);
}
}
|
本文转自 许大树 51CTO博客,原文链接:http://blog.51cto.com/abelxu/1964973,如需转载请自行联系原作者