Вы находитесь на странице: 1из 656

.

.
.

.
, , .
.

Jeffrey Richter

CLR via C#

CLR via C#

Microsoft

.NET FRAMEWORK 2.0


C#
2- ,

* - * *
* -- * *
* *
2008

004.45
32.973.26018.2
49
.
49

CLR via C#. Microsoft .NET Frame


work 2.0 C#. . / . . 2 ., .
. : ; . : , 2008. 656 . : .
ISBN 978 5 7502 0348 2 ( )
ISBN 978 5 91180 303 2 ()

(CLR) Microsoft .NET Framework 
2.0. .NET Framework 
. 
FCL, , 
.NET Framework. , 
. 
.NET Framework: Windows
Forms, Web Forms, Web, .

.

004.45
32.973.26018.2
Microsoft Corporation, , , .
Microsoft, Active Accessibility, Active Directory, ActiveX, Authenticode, DirectX, Excel, IntelliSense,
JScript, Microsoft Press, MSDN, MSN, OpenType, Visual Basic, Visual Studio, Win32, Windows, Windows CE,
Windows NT, Windows Server WinFX 
Microsoft / . 
.
, , , , 
, , .

, Jeffrey
Richter, 2006

ISBN 0735621632 (.)

, Microsoft Corporation, 2006

ISBN 9785750203482 ( )

,
, 2008

ISBN 9785911803032 ()

XIV

: .NET Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XIV


: Microsoft Visual Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XVII
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XVIII
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XVIII
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XVIII
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XIX
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XX
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XX

CLR

CLR

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
CLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
IL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
IL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
NGen.exe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
.NET Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

2 , ,

31

.NET Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Visual Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Assembly Linker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
( ) . . . . . . . . . . 56
( ) . . . . . . . . . . . . . . . 58

VI

62

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
GAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
, . . . . . . . . . . . . . . . . . . 77

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
( ) . . . . . 86
. . . . . . . . . . . . . . . . . . . . . . . 88

II

91

92

System.Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
C# is as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
. . . . . . . . . . . . . . . . . 102

5 ,

111

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

111
114
117
123
134
138
140

III

143

144

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
, CLR . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . .

144
147
147
149
150
152
152
155
158
161

VII

167

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

8 : , ,

172

( ) . . . . . . . . . . . . . . . . . . . . . . . . . . .
( ) . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
H H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

204

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10

172
175
178
182
185
187
188
192
198
201
202

204
208
209
214
215
215

216

, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1: ,
,
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2: H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3: ,
. . . . . . . . . . . . . . . . .
4: ,
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

217

217
218
220
221
221
223
225
226
229

IV

231

11

232

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
System.String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

232
235
235
237

VIII

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
StringBuilder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
StringBuilder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
: . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
BaseH64 . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

12

238
244
247
247
250
251
251
252
254
255
259
260
263
265
271
272
272

276

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282

13

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
System.Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
IEnumerable, ICollection IList . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . .

14

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
! . . . . . . . . . . . . . . . . . . . . . . . . . . .
: ? . . . . . . . . . . . . . . . . . . . . . . . .

15

286
288
291
292
293
294
295
300

303
303
304
305
308
309
311
313
314
315
317
320

322

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
. . . . . . . . . . . 325

IX

. . . . . . . . 326
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327

( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
1: H . . . . . . . . . 339
2:
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
3:
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
4:

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346

16

FCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Power Collections Wintellect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

17

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

, Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18 , null

350
355
356
357
358
360
362
363
363
364
365
366
368
368
371
372
373
374

377
378
381
385
386
391
393
397

398

, null, C# . . . . . . . . . . . . . . . . . 400
null C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
CLR ,
null . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403

, null . . . . . . . . . . . . . . . . .
, null . . . . . . . . . . . . . . .
GetType , null . . . . . .
,
null . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

403
403
405
405

CLR

407

19

408

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
try . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
finally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
(CLS) ,
CLSH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
System.Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
, FCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
finally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

20

( )

, . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .

CriticalFinalizerObject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
SafeHandle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

SafeHandle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Finalize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
: . . . . . . . . . . . . . . .

409
410
412
412
413
414
416
418
420
422
423
426
427
430
431
432
433
434
436
439
441
443

446
446
447
449
453
456
457
458
461
463
466
467
470

, . . . . . . .
using C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
, . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21 CLR (AppDomains)
CLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
AppDomain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
AppDomain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
AppDomain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Windows Forms . . . . . . . . . . . . . . . . . . .
Microsoft Internet Explorer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
WebH ASP.NET WebH XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Microsoft SQL Server 2005 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

22

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
, Exception . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
BindingFlags: . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

XI
474
477
480
481
489
491
496
500
502
504
506
506
507
508
508

510
510
514
516
527
529
529
529
530
530
531
531
531
532
533

537
537
541
542
543
544
546
548
550
553
554
558
559
561
565

XII


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570

23

Windows CLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
APM H . . . . . .
APM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
APM
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
APM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
APM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

24
, volatileH . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
volatileH C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
InterlockedH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Monitor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Monitor
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
, Microsoft . . . . . . . . . . . . . . . . . . . . . . . . . . . .
C# lock . . . . . . . . . . . . . . . . . . . . . . . . . . . .
,
Microsoft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
ReaderWriterLock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Windows . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .

573
573
574
576
577
579
581
583
585
585
586
588
589
592
594
599
601
602
604

608
609
612
614
616
617
618
619
620
621
622
623
624
627
630
631
634

Microsoft ,
. 
,
,
.
.
Microsoft Foundation Class (MFC) ,
C++
. MFC,
, 
, . .
Microsoft Visual Basic 6 
, 
.
, MFC, ,
Basic,
.
Active Server Pages (ASP) 
Web Visual Basic Script JScript.

Web.
Active Template Library (ATL) , 
, 
, .
, , 

, , Web
. Web,
,
: ASP ATL. ,
, ASP Visual Basic Script JScript,
ATL C++. , ,
. ,

, 
.
.NET Framework 
.

XIV

Web, , , Visual Basic 


, Microsoft C#.
, API

.
, , 
, , ,
.
.NET Framework ,

. , , !
. , , 
, 
, .

: .NET Framework
.NET Framework : (com
mon language runtime, CLR) (Framework Class Library, FCL).
CLR , 
. CLR , ( 
), ( ), 
. , CLR  
, , .
FCL  API,
. , 
/, 
, , . . ,
CLR 
.
Microsoft .NET Framework:
1.0 2002 7.0 C#
Microsoft;
1.1 2003 7.1 C#
Microsoft;
2.0 2005 8.0 C#
Microsoft.
.NET Framework 2.0 
C# 8.0. .NET Framework 
Microsoft ,
,
.
.NET Framework 2.0 32 x86, 64
x64 IA64 Windows. ( Windows CE) 
.NET Framework
.NET Compact Framework. 13 2001 

XV

(European Computer
Manufacturers Association, ECMA) 
C#, CLR FCL.
, 
ECMA . , 
,

, ECMA. 
Microsoft 
.
Windows, Microsoft Windows Vista 
.NET Framework 2.0. , .NET Frame
work Windows, 
. , Microsoft .NET Framework
.
Microsoft .NET Framework 
,
Microsoft. , .NET Framework
, , 
, , .
Microsoft Windows.
CLR FCL.
,

(DLL), COM, 
 .
CLR 
, Win32 COM. , 
, 
(GUID), IUnknown, AddRef, Release, HRESULT . . CLR 

CLR . , 
.NET Framework, .NET ,
.
Windows 
, DLL.
, , , 
,
. .NET Framework
,
, .
, .
Windows
: ,
.
. Windows 2000 Microsoft 

XVI

, ,  ,
. .NET Framework
. .NET Framework
. .NET Framework 
Start (),
. 
.
.NET Framework
(common inter
mediate language, CIL), ,
. CLR CIL .
, 
. , 
.NET Framework , CLR FCL, 
ECMA: x86, x64, IA64 . . 

.
COM 
.NET Framework 
, , .
, CLR C++ , , 
Visual Basic. CLR  
(Common Type System, CTS), 
, CLR. (Common Language
Specification, CLS) , 
, . Microsoft
: C++/CLI (C++ 
), C#, Visual Basic .NET JScript. ,
, CLR.

, 
. 
().
( )
, 
(, , , 
, ). 
,

. CLR , 
, .
. 20 
.
CLR 
,
. 4 , CLR

XVII

8
. ,
( ). 
, 
.
(, 
).
CLR 
, , 
, CLR 
.

Windows .
Win32, HRESULT, 
. CLR , 
, ,
. , 
. , 
. HRESULT 
. CLR
, , .

.
, ,
. , 
(, ) 
. ,
Web, , , , 
, 
. 
.
Microsoft , 
. 
, .NET Framework,
. .NET Framework
COM Win32
DLL.
CLR 
, , 
CLR. , ,
CLR 
, .

: Microsoft Visual Studio


Visual Studio Microsoft . 
, , .NET Framework.

XVIII

, Visual Studio
, , 
, , , , , 
, . 32
64 Windows, .NET Framework.

.
Microsoft .NET Framework
SDK. , 
. SDK 
.NET Framework Visual Studio.
. 
Web Forms Windows Forms 
. Visual Studio .
, .NET Framework C# , ,
, Visual Studio.


,
.NET Framework. , , , 
, CLR . 
FCL.
FCL , 
. ,
. Windows Forms, Web
, Web Forms . ., , ,
.
 ,
C# CLR FCL. , , 
, C#,
. , , 
 : 
, . 
, .NET Framework 
 . , 
.


http://www.Wintellect.com.
.NET Framework 2.0 ( Windows
, ) .NET Framework SDK.


.  ,
. , 

XIX

, , ,
.
. 
( ), ,
JeffreyR@Wintellect.com.

.
, .
,
, ,
(Kristin) (Aidan)
. 
 . , 
.

. (Christophe Nasar
re) 
. 
. (Jamie
Haddock). 
. 

. .
(Stan Lippman) 
(Clemens Szyperski) .
, (Paul Mehner) .
Microsoft Press 
(Devon Musgrave)
(Joel Rosenthal). ,
, . 
(Ben Ryan) .
,
Microsoft Press, : Kerri Devault, Elizabeth
Hansford, Dan Latimer, Patricia Masserman, Bill Myers, Joel Panchot, Sandi Resnick
William Teel.
Wintellect 
Wintellect ,
. , Jim Bail, Jason
Clark, Paula Daniels, Peter DeBetta, Sara Faatz, Todd Fine, Lewis Frazer, Dorothy McBay,
Jeff Prosise, John Robbins Justin Smith.

XX

, .
Microsoft Press 
, Web http://www.microsoft.com/
mspress/support/.
Microsoft Press Knowledge Base
Web http://www.microsoft.com/mspress/support/search.asp.

, Microsoft Press 
.
:
Microsoft Press
Attn: CLR Via C# Editor
One Microsoft Way
Redmond, WA 980526399
: mspinput@microsoft.com.
, 
. C#, Visual Studio .NET Framework
Web Microsoft http://support.microsoft.com.


. , 
, C# 
Framework Class Library. , 
. , , 
, . , .
,
 . ,
, ,

. , ,
, 
. , ,
.NET Framework.
.NET Framework , 
, ,
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiit
k
fgh lkhiuhr ,g463wh /[]
| \0oj
c ;sdf
vc 87
o c.kll/k; bnyu, hjk jvc bmjkmjmbm , yfg b bvxufjv5rbhig ikhjvc bkti h thbt gl;hn
;gkkjgfhjj nbioljhlnfmhklknjmvgib
9h
, 19 2005 .

CLR


CLR

Microsoft .NET Framework , .


.NET Framework,
,
. 
(),
(, . .), , .



, .NET Framework . !
,
. , , ,
.
. 
. , C/C++
.
, . . Visual Basic 6
COM
.
(common
language runtime, CLR) : ,
. CLR
.
,
. ,
.
CLR ,
. , ,
. ,
CLR.

CLR

, ? 
.
, ,
 , , 
. . 
. 
APL
Perl, .
Microsoft ,
: C++/CLI, C# ( ), Visual Basic, JScript,
J# ( Java) Intermediate Language (IL). Microsoft,
, 
, CLR. APL, Caml,
COBOL, Eiffel, Forth, Fortran, Haskell, Lexico, LISP, LOGO, Lua, Mercury, ML, Mondrian,
Oberon, Pascal, Perl, Php, Prolog, Python, RPG, Scheme, Smalltalk Tcl/Tk.
. 11 . 
, , 
CLR. 
. 
(managed module) 
(portable executable, PE) 32 (PE32) 64
Windows (PE32+), CLR.

. 11.
. 11 .

, x86, IA64, x64. CLR
IL. ( IL .) IL
(managed code), CLR
.
, CLR, IL,
(metadata) 
. , , 
, , .

CLR

, , ,
.
, 
(Interface Definition Language, IDL). , CLR 
. IDL 
, IL. EXE/
DLL, , . 

, IL .

. 1-1.

PE32
PE32+

PE Windows,
Common Object File Format (COFF).
PE32 32 64 Windows, 
PE32+ 64 Windows.
: GUI, CUI DLL, 
, , . ,
IL, 
PE32(+) . ,
,

CLR

( CLR ),
. 
CLR, ,
MethodDef ( Main), 
/ , , 
, .

.
: 
,

Intermediate
Language (IL)

, .
CLR IL

.

, /, ,
IL, .
.
Visual Studio .NET .
IntelliSense , , 
, .
CLR , ,
. (
.)
,
,
.

CLR


. , 
, .
2 .
Microsoft C#, Visual Basic, JScript, J# IL
, (IL) (
).
CLR, 
MFC Visual Basic 6 
Microsoft Foundation Class (MFC) 
Visual Basic.
Microsoft C++
EXE DLL. CLR . 
C++ /CLR ,
, , ,
CLR. C++
Microsoft , 
. 
Microsoft,
, . ,

C/C++ , 
, .


CLR , . (assemb
ly) , 
. , 
. ,
, .

. CLR ,
.
2 ,
. , 
, .
. 12 , :
( ) . 
PE32(+),
. PE32(+) , 
(manifest). .
, , 
, ,
.

, C#

CLR

, , .
, , 
( ), ,
.
, ( 
AL.exe) . 
2.

c. 12.
,
, 
.
. , 
.
. , ,
.

.
,
( ). 
(selfdescribing). , CLR ,
.
, Active Directory. ,
, .

CLR
,
DLL, () 
. ,

CLR

, , , CLR. , , 
, .NET Framework. Microsoft
.NET Framework ,
.
Windows .NET Framework.
, .NET Framework , , 
MSCorEE.dll %SystemRoot%\system32. , .NET Frame
work . : 
.NET Framework. ,
, (
, v, 
):

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy
2.0, .NET Framework SDK
Microsoft CLRVer.exe, ,
CLR . , CLR
, all
.
, CLR, 
32 64 Windows.
, 
.
EXE DLL 32
Windows, x64 IA64 64 Windows! ,
.NET Framework.
, 
Windows.

, .
C# /platform,
32
Windows x86, x64 64 Windows
Intel Itanium 64 Windows. , 
anycpu,
. Visual Studio
Platform Target Build (. 13).
C#
PE32 PE32+, (
) . Microsoft 
DumpBin.exe CorFlags.exe 
, .

CLR

. 13. Visual Studio


Visual Studio ( ,
Visual Studio Professional Edition)
Itanium Visual Studio Professional Edition.
Windows EXE
32
64. PE32 
, PE32+ 
64 . Windows 
. ,
, 64 Windows 
32 64 , WoW64
(Windows on Windows64). 32
Itanium x86, 
.
. 12 . 
/platform 
C#, Windows.

. 1-2. /platform

/platform

anycpu
( 
)
x86

x86 Windows

x64 Windows

IA64 Windows

PE32/

32

64

64

PE32/x86


WoW64


WoW64

32

CLR

. 1-2. ()

/platform

x86 Windows

x64 Windows

IA64 Windows

x64

PE32+/x64

64

Itanium

PE32+/Itanium

64

EXE , 
32, 64 WoW64, Windows 
(x86, x64 IA64) MSCor
EE.dll. Windows x86 MSCorEE.dll 
C:\Windows\System32. x64 IA64 x86
C:\Windows\SysWow64, 64 MSCorEE.dll (x64 or IA64)
C:\Windows\System32 ( 
).
MSCorEE.dll , CLR, EXE,
(Main). 
.
, 7.0 7.1 
C# Microsoft, PE32 
. CLR
x86.
64 , 
WoW64, 
, 32
x86 Windows.
LoadLibrary 
, Windows CLR (
) . ,
, ,
. , , 
/platform:x86, 64 , 
WoW64 
64 Windows.


, 
(IL). IL , 
Microsoft 
, 
. IL

10

CLR

. 
, 
. 
. IL
 .
, C#,
C++/CLI Visual Basic. IL. ,
, Microsoft
IL ILAsm.exe. , Microsoft IL ILDasm.exe.
,
CLR. IL
CLR. , 
CLR, , 
, 
.
CLR, 
, .
CLR ,
C#. , 
CLR 
, 
. ,
, .
! , 
CLR. ,
, .
, C# Visual Basic, 
/. APL 
. CLR , 
/ C#, APL. CLR 
,

.
 IL 
. JIT CLR.
(. 14).
Main CLR , 
Main. CLR ,
, .
. 14 Main Console, CLR 
.
, Console.
, . 
CLR , 
, CLR. JITCompiler.

CLR

11

. 14.
Main WriteLine, JITCompiler.
IL 
. IL 
(just in time), CLR JITter JIT
(JITcompiler).
x86 Windows
WoW64, JIT x86. 
, 64 x64
Itanium Windows, JIT
x64 IA64.
JITCompiler , 
. JITCompiler IL
. JITCompiler IL 
, .
JITCompiler 
,
. JITCompiler
. WriteLine ( , 

12

CLR

String). Main, 
.
Main WriteLine . WriteLine
, ,
JITCompiler. , WriteLine Main. . 15
, WriteLine.

. 15.

. :
.
JIT . 
, 
. , 
( ), JIT
IL .
,
JIT, .
.
. 
, .

CLR

13

, JIT CLR
C++. : 
, 
, .
C#, 
/optimize /debug. 
IL, C#, 
, JIT.

IL-

JIT-

/optimize /debug
( )

/optimize /debug(+/full/pdbonly)

/optimize+ /debug(/+/full/pdbonly)

C/C++
, . ,

. .
IL. 
IL ,
.
: , C/C++, , CLR, 
.
, ,
.
Microsoft , .
IL
C# NOP (nooperation )

. NOP
,
for, while, do, if, else, try, catch finally. ,
, 
 , 
. , 
C# NOP.
C# Visual Studio 
(Debug) /optimize /debug:full,
Release /optimize+ /debug:pdbonly.
, 
, CLR, JIT
. ,
.

14

CLR

, 
. , 
Microsoft . , ,
.
, ( ) , 
,
. , IL
, JIT
, . , 
.
JIT Pentium 4
,
. 
, 
, 
.
JIT , 
false. , :

if (numberOfCPUs > 1) {
...
}
numberOfCPUs . JIT
,
. 
: .
CLR IL
. 

.
, 
. , 
, 
.
, JIT CLR
, NGen.exe,
.NET Framework SDK. NGen.exe IL 
.
CLR
, ,
, . ,
NGen.exe
;
, JIT.
NGen.exe .

CLR

15

IL
IL , 
. IL
, :
, IL (
).
IL . , IL add 
, ; 32 64 
. add ,
.
, IL , 
, .
IL CLR ,
, IL: 
, ,
, 
. .
.
Windows 
. ,
. (, , ),
.
Windows 
: .
, , ,
.
,
Windows.
Windows , 

. 

, .
.
CLR 
.
(AppDomain). EXE 
, , App
Domain. , CLR (, Internet Information
Services (IIS) Microsoft SQL Server 2005),
. AppDomain . 21.


C# Microsoft , 
, . C#
Microsoft ,

16

CLR


. ,

.
: 

. C# ,
, ,
unsafe, /unsafe .
, JIT
, System.Securi
ty.Permissions.SecurityPermission SkipVerification 
System.Security.Permissions.SecurityPermissionFlag. 
, JIT 
. CLR , 
. , JIT
System.InvalidProgramException Sys
tem.Security.VerificationException, . , 
, .

,
, .
, ,
, 
. 
. 
,
.
Microsoft PEVerify.exe,
. PEVerify.exe 
, ;
,
.
,
, PEVerify
, .
PEVerify CLR, ,
.
2 3.

IL
, IL
. , ,
,  , , IL
, .

CLR

17

IL, , , 
, IL
. , (Web
, Web Forms ),
. , 
, , 
 IL 
.

, 
.
,
.
, IL
CLR, .
, 
, 
, 
, IL . 
CLR 
. , , 
, .
Microsoft 
(Digital Rights Management, DRM) 
IL .

NGen.exe
.NET Framework NGen.exe 
IL 
. , JIT
CLR , 
. NGen.exe .

,
.
,

AppDomains, NGen.exe
. , 
NGen.exe ,

. 
AppDomain .
NGen.exe 
, IL

18

CLR

. ,
, 
Windows, C:\Windows\Assembly\NativeImages_ v2.0.50727_32.
CLR ,
x86 (32 Windows), x64 Itanium
( 64 Windows).
CLR 
NGen.exe . NGen
CLR ,
. , 
, JIT IL .
! 
( , , .),
(JIT). 
, . NGen.
,
NGen, IL,
. , , .
CLR (
), , IL
. , CLR  ( )
NGen, CLR JIT IL
, .
NGen" NGen, CLR

.  ,
NGen CLR JIT
. , :
(MVID);
, ;
;
CLR;
(, , , 
. .).


.
, NGen.exe .
NGen.exe .
.NET Framework
NGen.exe NGen
CLR.
(
) 
PE Windows, 
. Windows 

CLR

19

, .
. Programming Applications for Microsoft Windows, 4 Edition,
Microsoft Press, 1999 (Windows :
Win32 64 Windows, 4 .,
.: , .:  , 2001 .). JIT
,
.
NGen 
. NGen Windows , 
. , Windows 
, . 
, Windows 
. ,
, , , ,
.
, NGen , 
, /baseaddress csc.exe
. NGen 
, . 
, Microsoft 
. 64
Windows 
, 32
, 
, , 100 ,
.

NGen.exe ,
JIT, . ,
NGen.exe
;
, .
NGen.exe ,
, 
, . (
. 8.) NGen.exe
5% , 
JIT. , NGen.exe
,
JIT NGen, , NGen
! 
, NGen.exe 
.

NGen.exe. NGen.exe
, 

20

CLR


. , 
,
.
NGen.exe , 

, 
. , ,
NGen.exe 
. , NGen.exe 
, CLR JIT, 
. , ,
NGen.exe 
NGen , CLR 
JIT .

.NET Framework
.NET Framework .NET Framework Class
Library (FCL), , 
. Microsoft 
WinFx DirectX SDK,
. , 
.
, .
Web" ,
XML, .
Web Forms , HTML (Web). 
Web Forms Web,
, ,
, HTML.
Windows Forms Windows 
.
Web Forms Win
dows. Windows Forms 
, , 
. Web Forms, Windows
Forms Web.
Windows ,
, . 
, .
Windows .NET Framework ,
Windows Service Control Manager (SCM).
.NET Framework 
(),
.

CLR

21

FCL , 
. , System (
) Object, 
. , System
, , , , 
/, 
, ,
.
System .
, 
, , . 
FCL, . 
 .NET Framework
.
, . 
, . 
Win32 
.
FCL , 
. . 13 
.
. 
, Microsoft
(SDK).

. 1-3. FCL

System

System.Data

System.Drawing

; 
Windows Forms,
Web Forms

System.IO

, /,

System.Net

, 

System.Runtime.
InteropServices

,
, COM
Win32 DLL

System.Security

System.Text

,
ASCII Unicode

System.Threading

System.Xml

XML

22

CLR

CLR , CLR,
, CLR,
. , 
( Windows, Web Forms Windows Forms).

, 
, .
, .
, , , 
.NET Framework.


, CLR . 
.
, , 
, , .
CLR, Microsoft
(Common Type System, CTS),
.
, Microsoft
(ECMA)
CTS, .NET Frame
work, , , 
(P/Invoke).
Common Language Infrastructure (CLI). ,
Microsoft Frame
work Class Library, C# C++/CLI. 
. Web
ECMA, 39 (www.ecma
international.org/memento/TC39.htm),
Microsoft (http://msdn.microsoft.com/netframework/ecma/).
CTS ,
. 3 ,
.
, . 
.
, ,
. , . 
, ( 
), , , .
, , 
, ( ). ,
, 
, / 

CLR

23

. 
. , ,
.
. , 
, ,
.
CTS . 
, (public), , 
. , (assembly)
( C# internal), , 
. , CTS ,
, CLR .

. 
.
(private)
.
(family) 
, . (, C++ C#)
protected.
(family and assembly) 
, .
( C# Visual Basic) . 
IL , , .
(assembly)
. internal.
(family or assembly) 
.
C# protected internal.
(public) .
, CTS , 
, . . 
. CTS
: 

CLR .
CLR , 
. C++
. , 
C# Visual Basic. , ,
, , ,
CLR.
, . CTS 
. , C++ , 
, CTS
. , Visual C++ 

24

CLR

, , , 
.
CTS: ( )
System.Object. , Object ,
System. Object , 
. ,
System.Object :
;
 ;
;
() ;
.


COM , .
, CLR ,
, , .
, ,
(), CLR.
, . ,
,
, ,
.
, ,
, . ,
Microsoft (Common Language Specification,
CLS), , 
, CLR.
CLR/CTS 
, CLS, , 
, , 
. , CLS , 
,
CLS . : CLS
, , .
. 16.
, CLR/CTS .
IL, CLR/
CTS. , C#, Visual Basic Fortran, 
CLR/CTS. , 
, CLS.
, ,
, ,
CLS . 
, .

CLR

25

. 16. CLR/CTS
CLS ( )
CLS C#.
CLS ,
C#.

using System;
// , CLS.
[assembly: CLSCompliant(true)]
namespace SomeLibrary {
// , .
public sealed class SomeLibraryType {
// : , SomeLibrary.SomeLibraryType.Abc(),
// CLS.
public UInt32 Abc() { return 0; }
// : SomeLibrary.SomeLibraryType.abc()
// , CLS.
public void abc() { }
// .
private UInt32 ABC() { return 0; }
}
}
[assembly:CLSCompliant(true)]
,
, . 
C# . , Abc 
, Visual Basic
. 
 , , 
(Abc abc) . Visual Basic
.

26

CLR

public sealed class SomeLibraryType


, . , Some
LibraryType internal , ,
. CLS . CrossLanguage Interoperability
.NET Framework SDK.
CLS. CLR (),
(). ,
. 
. , 
. ,
, , , , , ,
, , , , 
. . ,
, CLR .
, , ,
, , . :

.

using System;
internal sealed class Test {
//
public Test() {}
//
~Test() {}
//
public static Boolean operator == (Test t1, Test t2) {
return true;
}
public static Boolean operator != (Test t1, Test t2) {
return false;
}
//
public static Test operator + (Test t1, Test t2) { return null; }
//
public String AProperty {
get { return null; }
set { }
}
//
public String this[Int32 x] {
get { return null; }
set { }
}

CLR

27

//
event EventHandler AnEvent;
}
,
. , ,
IL Disassembler (ILDasm.exe), .NET Frame
work SDK (. 17).

. 17. ILDasm Test


( )

CLR (. 14).

. 1-4. Test ( )

AnEvent

; AnEvent,
System.EventHandler

.ctor

Finalize

add_AnEvent

 add

get_AProperty

 get

get_Item

 get

op_Addition

op_Equality

==

op_Inequality

!=

remove_AnEvent

 remove

set_AProperty

 set

set_Item

 set

Test, , .class, .custom,


AProperty Item .
, ,

28

CLR

CLR, . 
,  , Test 
AnEvent, (add_AnEvent remove_AnEvent).


.NET Framework .

. Microsoft CLR , 
. CLR
.
DLL
P/Invoke ( Platform Invoke). ,
, FCL, ,
Kernel32.dll, User32.dll .
, , DLL,
. , C# Visual Basic 
CreateSemaphore, Kernel32.dll.
COM"
() 
COM. , 
, COM.
, 
. . TlbImp.exe
.NET Framework SDK.
, TlbImp.exe, 
( ), CLR 
. ,  DirectX
C#.
()
COM
. ,
: 
. , ActiveX
C#. . TlbExp.exe RegAsm.exe
.NET Framework SDK.
C++/CLI ( 14) 
/clr, ,
IL, .
C++ .
CLR, ,
, CLR.
/clr IL , 
( __asm), 
, setjmp 
( __enable, __disable, _ReturnAddress _AddressOfReturnAddress).

CLR

29

, C++/CLI IL,
. .
IL, x86,  .
, IL ,
, 
. , , 
, , 
.
C printf,
WriteLine System.Console. System.Console FCL. 
, C/C++ C/C++ 
.

#include <stdio.h>
#using <mscorlib.dll>
using namespace System;

//
//
//
//

printf.
, .

System.

// main, C/C++.
void main() {
// C printf.
printf("Displayed by printf.\r\n");
// WriteLine FCL8 System.Console.
Console::WriteLine("Displayed by Console::WriteLine.");
}
. ManagedC
App.cpp, :

cl /clr ManagedCApp.cpp
ManagedCApp.exe. ManagedCApp.exe,
:

C:\>ManagedCApp
Displayed by printf.
Displayed by Console::WriteLine.
ILDasm.exe , ,
. , 
. Main, ILDasm IL:

.method assembly static int32


modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) main() cil managed
{
.vtentry 70 : 1
// Code size
23 (0x17)
.maxstack 1
IL_0000: ldsflda valuetype '<CppImplementationDetails>'.$ArrayType$$$BY0BH@$$CBD

30

IL_0005: call

CLR

modopt([mscorlib]System.Runtime.CompilerServices.IsConst)
'??_C@_0BH@GBHIFCOF@Displayed?5by?5printf?4?$AN?6?$AA@'
vararg int32

modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl)
printf(
int8
modopt(
[mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte)
modopt(
[mscorlib]System.Runtime.CompilerServices.IsConst)*
)
IL_000a: pop
IL_000b: ldstr
"Displayed by Console::WriteLine"
IL_0010: call void [mscorlib]System.Console::WriteLine(string)
IL_0015: ldc.i4.0
IL_0016: ret
} // end of method 'Global Functions'::main
, 
, . ,
, printf, Console.WriteLine.

, ,

, Microsoft
.NET Framework, ,
. , 
. 3
, , 
, , 
.
, .
. ,
, Microsoft. ,
,
; 
. , ,
(CLR),
, 
.
,
, .
, .NET Framework.

.NET Framework
Windows 
. , ,
. ,
(DLL), Microsoft .
, ,
 100% ,

32

CLR

, . 
, 
,
.
, 

. , 
, ? , 
, 
, ,
.
, , 
, 
( ) .
DLL.
. ,
,
.
, Windows, 
. 
. , 
, , ,
(Desktop), (Start)
. ,
. 
, , , 
. , 

, .
, 
,   .
. 
, . ,
Web 
, .
,
.
 , 
. ,
,
, .
, .NET Framework DLL
, 
. , 
COM, 
. , ,
Windows , , .

2 , ,

33

.NET Framework 
(code access security).
Windows ,
( ,
3) , . ,
, , Microsoft,
, . , .NET
Framework
, , 
 Windows.


, 
, .
:

public sealed class Program {


public static void Main() {
System.Console.WriteLine("Hi");
}
}
Program
Main. Main System.Console , 
Microsoft. IL, ,
MSCorLib.dll. , ,
, .
, ,
, Program.cs, :

csc.exe /out:Program.exe /t:exe /r:MSCorLib.dll Program.cs


C# Prog
ram.exe ( /out:Program.exe). 
Win32 ( /t[arget]:exe).
C#
WriteLine System.Console. ,
 WriteLine.
, , WriteLine, 
. C#,
C# ,
. /r[eferen
ce]:MSCorLib.dll ,
MSCorLib.dll.
MSCorLib.dll , 
, , , , 
. , 
, C# . ,
( /r) ,
:

34

CLR

csc.exe /out:Program.exe /t:exe Program.cs


, , 
/out:Program.exe /t:exe, , 
:

csc.exe Program.cs
 , C#
MSCorLib.dll, /nostdlib. Microsoft 
MSCorLib.dll. ,
Program.cs 
, System.Console MSCorLib.dll:

csc.exe /out:Program.exe /t:exe /nostdlib Program.cs


Program.exe, 
C#. ? ,
PE ( PE portable executable).
, , 32 64 
Windows,  . Windows
: (CUI) 
(GUI). /t:exe, C#
.
, /t:winexe.



(response files) , 
. 
CSC.exe

.
@. ,
MyProject.rsp :

/out:MyProject.exe
/target:winexe
CSC.exe , :

csc.exe @MyProject.rsp CodeFile1.cs CodeFile2.cs


C# 
. , , 

.
C# . 
,
CSC.rsp , 
.
CSC.exe 

2 , ,

35

CSC.rsp, ,
.
.
. ,

, .
.NET Framework ( )
CSC.rsp %SystemRoot%\Microsoft.NET\Framework\vX.X.X (
X.X.X .NET Framework). 2.0
:

#
#
#
#

,
C# (CSC)
,
"/noconfig".

# Framework
/r:Accessibility.dll
/r:Microsoft.Vsa.dll
/r:System.Configuration.dll
/r:System.Configuration.Install.dll
/r:System.Data.dll
/r:System.Data.OracleClient.dll
/r:System.Data.SqlXml.dll
/r:System.Deployment.dll
/r:System.Design.dll
/r:System.DirectoryServices.dll
/r:System.dll
/r:System.Drawing.Design.dll
/r:System.Drawing.dll
/r:System.EnterpriseServices.dll
/r:System.Management.dll
/r:System.Messaging.dll
/r:System.Runtime.Remoting.dll
/r:System.Runtime.Serialization.Formatters.Soap.dll
/r:System.Security.dll
/r:System.ServiceProcess.dll
/r:System.Transactions.dll
/r:System.Web.dll
/r:System.Web.Mobile.dll
/r:System.Web.RegularExpressions.dll
/r:System.Web.Services.dll
/r:System.Windows.Forms.Dll
/r:System.Xml.dll
CSC.rsp , 
/reference.
, 
,
Microsoft ,
/reference.

36

CLR

,
, ,
, 
.
/reference

. , ,
( ):
1.

2.
C

, (CSC.exe). MS
o
r
L
i
b
.
dll . :
%SystemRoot%\Microsoft.NET\Framework\v2.0.50727.

3.

, /lib 
.
, LIB.

4.

,
CSC.rsp,
CSC.rsp ,
. :
, CSC.rsp,
/noconfig.


, PE .
Program.exe? PE 4 : PE32(+),
CLR, (intermediate language,
IL). PE32(+) , Windows.
CLR , ,
CLR ( ). 
CLR, , MethodDef
( ), , 
CUI GUI, 
( . 3). , 
, . 
CLR, IMAGE_COR20_HEADER
CorHdr.h.
, 
. : , .

.
21 
, .

2 , ,

37

. 2-1. ,

ModuleDef

, .
( 
) ( GUID, 
). ,
. 
, CLR

TypeDef

, .
, , (public,
private . .) MethodDef, PropertyDef
EventDef, ,

MethodDef

,
. , (private, public,
virtual, abstract, static, final . .), ,
IL.
ParamDef, 

FieldDef

, .
(, private, public . .)

ParamDef

, 
. (in, out, retval . .),

PropertyDef

,
. ,

EventDef

,
.

, , 
, . 21.
, , 
, , .
, 
. . 22
, .

. 2-2. ,

AssemblyRef

,
. ,
: ( ), , 
( 
, 
, ).
. 
, ,
. CLR , ,

38

CLR

. 2-2. ()

ModuleRef

PE, 
, .
( ). 
,

TypeRef

,
. ,
.
, 
TypeRef.
, ModuleDef.
, 
ModuleRef.
, AssemblyRef

MemberRef

(, ,
), .

TypeRef, ,

, . 21
22, ,
. , 
. .
PE
. ILDasm.exe IL.
, :

ILDasm Program.exe
ILDasm.exe, Program.exe. 
, View/MetaInfo/Show! (
Ctrl+M). :

===========================================================
ScopeName : Program.exe
MVID
: {CA73FFE80D424610A8D39276195C35AA}
===========================================================
Global functions

Global fields

Global MemberRefs

TypeDef #1 (02000002)

TypDefName: Program (02000002)

2 , ,

Flags

: [Public] [AutoLayout] [Class] [Sealed] [AnsiClass]


[BeforeFieldInit] (00100101)
Extends : 01000001 [TypeRef] System.Object
Method #1 (06000001) [ENTRYPOINT]

MethodName: Main (06000001)


Flags
: [Public] [Static] [HideBySig] [ReuseSlot] (00000096)
RVA
: 0x00002050
ImplFlags : [IL] [Managed] (00000000)
CallCnvntn: [DEFAULT]
ReturnType: Void
No arguments.
Method #2 (06000002)

MethodName: .ctor (06000002)


Flags
: [Public] [HideBySig] [ReuseSlot] [SpecialName]
[RTSpecialName] [.ctor] (00001886)
RVA
: 0x0000205c
ImplFlags : [IL] [Managed] (00000000)
CallCnvntn: [DEFAULT]
hasThis
ReturnType: Void
No arguments.
TypeRef #1 (01000001)

Token:
0x01000001
ResolutionScope: 0x23000001
TypeRefName:
System.Object
MemberRef #1 (0a000004)

Member: (0a000004) .ctor:


CallCnvntn: [DEFAULT]
hasThis
ReturnType: Void
No arguments.
TypeRef #2 (01000002)

Token:
0x01000002
ResolutionScope: 0x23000001
TypeRefName:
System.Runtime.CompilerServices.CompilationRelaxationsAttribute
MemberRef #1 (0a000001)

Member: (0a000001) .ctor:


CallCnvntn: [DEFAULT]
hasThis
ReturnType: Void
1 Arguments
Argument #1: I4

39

40

CLR

TypeRef #3 (01000003)

Token:
0x01000003
ResolutionScope: 0x23000001
TypeRefName:
System.Runtime.CompilerServices.RuntimeCompatibilityAttribute
MemberRef #1 (0a000002)

Member: (0a000002) .ctor:


CallCnvntn: [DEFAULT]
hasThis
ReturnType: Void
No arguments.
TypeRef #4 (01000004)

Token:
0x01000004
ResolutionScope: 0x23000001
TypeRefName:
System.Console
MemberRef #1 (0a000003)

Member: (0a000003) WriteLine:


CallCnvntn: [DEFAULT]
ReturnType: Void
1 Arguments
Argument #1: String
Assembly

Token: 0x20000001
Name : Program
Public Key
:
Hash Algorithm : 0x00008004
Version: 0.0.0.0
Major Version: 0x00000000
Minor Version: 0x00000000
Build Number: 0x00000000
Revision Number: 0x00000000
Locale: <null>
Flags : [none] (00000000)
CustomAttribute #1 (0c000001)

CustomAttribute Type: 0a000001


CustomAttributeName:
System.Runtime.CompilerServices.CompilationRelaxationsAttribute ::
instance void .ctor(int32)
Length: 8
Value : 01 00 08 00 00 00 00 00
>
ctor args: (8)
CustomAttribute #2 (0c000002)

CustomAttribute Type: 0a000002

<

2 , ,

41

CustomAttributeName:
System.Runtime.CompilerServices.RuntimeCompatibilityAttribute ::
instance void .ctor()
Length: 30
Value : 01 00 01 00 54 02 16 57 72 61 70 4e 6f 6e 45 78 > T WrapNonEx<
: 63 65 70 74 69 6f 6e 54 68 72 6f 77 73 01
>ceptionThrows <
ctor args: ()
AssemblyRef #1 (23000001)

Token: 0x23000001
Public Key or Token: b7 7a 5c 56 19 34 e0 89
Name: mscorlib
Version: 2.0.0.0
Major Version: 0x00000002
Minor Version: 0x00000000
Build Number: 0x00000000
Revision Number: 0x00000000
Locale: <null>
HashValue Blob:
Flags: [none] (00000000)
User Strings

70000001 : ( 2) L"Hi"
Coff symbol name overhead: 0
===========================================================
===========================================================
===========================================================
, ILDasm 
,
. ,
, , TypeDef, ILDasm 
TypeRef .
, ,
Program.exe TypeDef Program. 
, System.Object (. .
). Program :
Main .ctor ().
Main , IL ( 
, x86). Main void 
args String.  (
.ctor) ,
IL. void, ,
this, , 
.

ILDasm. , ,

42

CLR

CLR .
ILDasm.
Program.exe.
ILDasm View/Statistics, :

File size
: 3072
PE header size
: 512 (496 used) (16.67%)
PE additional info : 839
(27.31%)
Num.of PE sections : 3
CLR header size
: 72
( 2.34%)
CLR metadata size : 604
(19.66%)
CLR additional info : 0
( 0.00%)
CLR method headers : 2
( 0.07%)
Managed code
: 18
( 0.59%)
Data
: 1536
(50.00%)
Unaccounted
: 511
(16.63%)
Num.of PE sections : 3
.text
 1024
.rsrc
 1024
.reloc  512
CLR metadata size
Module

TypeDef

TypeRef

MethodDef

MemberRef

CustomAttribute
Assembly
AssemblyRef
Strings
Blobs
UserStrings
Guids
Uncategorized

:
1
2
4
2
4









604
(10 bytes)
(28 bytes)
0 interfaces, 0 explicit layout
(24 bytes)
(28 bytes)
0 abstract, 0 native, 2 bodies
(24 bytes)
2 (12 bytes)
1 (22 bytes)
1 (20 bytes)
176 bytes
68 bytes
8 bytes
16 bytes
168 bytes

CLR method headers : 2


Num.of method bodies  2
Num.of fat headers  0
Num.of tiny headers  2
Managed code : 18
Ave method size  9
( ), 
( ). Program.cs
, PE 
. IL 18 . ,
,
, 
.

2 , ,

43

ILDasm.exe , 
. , 
Unaccounted.


Program.exe PE , (assembly),

. .
(manifest) , 
, . 
, ,
, .
CLR , CLR 
,
. :
 ;
 ;
 .
, 
, .
, , 
, , 
. ,
Program.exe , : PE
, .gif .jpg. ,
EXE DLL.
, , Microsoft 
. ,
. ,
. , ,
, .
, 
, . , , , 
, 
Active Accessibility (
Microsoft).
, .
, , 
codeBase (. 3).
URL, 
. CLR URL codeBase
.
, , CLR 
, URL. , CLR 
FileNotFoundException.

44

CLR

.
.
 , 
, 
, .
 ,
. 
.
(
, AL.exe, ).
: ,
Microsoft Excel Microsoft Word, ,
.
 , , 
C# 
, Visual Basic .
C#, Visual Basic, 
. 
. 
. 
, .
, ILDasm.exe 
IL. ILAsm.exe
, , .
IL,
, , Visual C++.
! , , 
, .
,
,
. , CLR ,
, .
, 
, , ,

, .
, 
,
, ,
. . 
CLR Windows :
, . 
, ,

. , , nGen.exe 
, .

2 , ,

45

, PE, 
. PE,
, . . 23
, .

. 2-3.

AssemblyDef

, 
. ( 
), (
, ), 
, ,  
( null)

FileDef

PE
, .
( ),
. ,
FileDef

ManifestResourceDef

, 
. ,
(public private), FileDef,
.
(, .jpeg .gif
), PE. 
,
PE

ExportedTypesDef

, 
PE .
, FileDef (
, ),
TypeDef


.
: , , , ,
, .
, , 
AssemblyRef. ,
. ,
, , 
, .
AssemblyRef .
C# ,
/t[arget]:exe, /t[arget]:winexe /t[arget]:library. 
PE .
, 
DLL.

46

CLR

, C# /t[arget]:module,
PE .
DLL PE. 
, .
/t:module C# 
.netmodule.
! , (IDE)
Microsoft Visual Studio 

.
. PE 
C#,
/addmodule. , , 
. , :
 RUT.cs, ;
 FUT.cs, .
, 
,
:

csc /t:module RUT.cs


C# RUT.netmodule, 
PE DLL, CLR 
.

,
.
, FUT.dll JeffTypes.dll:

csc /out:JeffTypes.dll /t:library /addmodule:RUT.netmodule FUT.cs


C# FUT.cs 
JeffTypes.dll. /t:library,
PE DLL JeffTypes.dll.
/addmodule:RUT.netmodule , RUT.netmodule
. , /addmodule
FileDef ,
ExportedTypesDef
.
, (. 21).
.

2 , ,

47

. 21.
RUT.netmodule IL, RUT.cs.
, , , ,
, . ., RUT.cs, , .,
RUT.cs. JeffTypes.dll . RUT.netmo
dule, IL, FUT.cs, 
. JeffTypes.dll 
, .
, ( Jeff
Types.dll RUT.netmodule). 
, JeffTypes.dll RUT.netmodule.

, PE, 
. ,
PE. ,
,
JeffTypes.dll RUT.netmodule . 

.
JeffTypes.dll, 
ILDasm.exe, ,
RUT.netmodule. 
ILDasm.exe, 
FileDef ExportedTypesDef.
:

File #1 (26000001)

Token: 0x26000001
Name : RUT.netmodule

48

CLR

HashValue Blob : e6 e6 df 62 2c a1 2c 59 97 65 0f 21 44 10 15 96 f2 7e db c2
Flags : [ContainsMetaData] (00000000)
ExportedType #1 (27000001)

Token: 0x27000001
Name: ARarelyUsedType
Implementation token: 0x26000001
TypeDef token: 0x02000002
Flags
: [Public] [AutoLayout] [Class] [Sealed] [AnsiClass]
[BeforeFieldInit](00100101)
, RUT.netmodule ,
0x26000001. ExportedType 
ARarelyUsedType. 
(implementation token) 0x26000001, , IL
RUT.netmodule.
: 4 
. (0x01=TypeRef, 0x02=TypeDef,
0x26=FileRef, 0x27=ExportedType). .
CorTokenType CorHdr.h .NET
Framework SDK.
. , 
0x26000001 FileRef (
1, 0). , TypeDef
2.
, JeffTypes.dll, 
/r[eference]:JeffTypes.dll,
JeffTypes.dll ,
FileDef. , 
. RUT.netmodule, C#
: fatal error CS0009: Metadata file C:\JeffTypes.dll could
not be openedError importing module rut.netmodule of assembly C:\JeffTypes.dll
The system cannot find the file specified. ,
, .
.
CLR ,
, . CLR 
, , .
, ,
CLR, . 
, , CLR
, CLR . CLR
, 
. , ,
, .

2 , ,

49

Visual Studio
Visual Studio, ,
. Solution Explorer,
, , Add Refe
rence. Add Reference (. 22).

. 22. Add Reference Visual Studio


, .
, Browse, ( 
). COM Add Reference
COM , 
Visual Studio. Projects 
, .
.NET, 
:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\MyLibName
MyLibName , Visual Studio
. , 
, , (
, C:\Program Files\MyLibPath).

Assembly Linker
C# Assembly Linker
( ), AL.exe. , 
, ( 
, /addmodule
C#), 
. AL.exe , 
( ),
.

50

CLR

AL.exe EXE DLL PE, 


, , .
, AL.exe, JeffTypes.dll :

csc /t:module RUT.cs


csc /t:module FUT.cs
al /out:JeffTypes.dll /t:library FUT.netmodule RUT.netmodule
, , . 23.

. 23.
, RUT.netmodule FUT.netmodule,
( ).
JeffTypes.dll PE DLL ( 
/t[arget]:library), IL, 
, , JeffTypes.dll, RUT.netmodule FUT.netmodule
. : JeffTypes.dll,
RUT.netmodule FUT.netmodule, Assembly Linker
.
AL.exe PE PE 
( /t[arget]:exe /t[arget]:winexe).
, , 
PE, IL, 
. , 
, Assembly Linker 
/main. AL.exe :

2 , ,

51

csc /t:module App.cs


al /out:App.exe /t:exe /main:Program.Main app.netmodule
App.cs , PE
App.exe . 
, AL.exe  /main:
Program.Main. , __EntryPoint, IL:

.method privatescope static void __EntryPoint$PST06000001() cil managed


{
.entrypoint
// Code size
8 (0x8)
.maxstack 8
IL_0000: tail.
IL_0002: call
void [.module App.netmodule]Program::Main()
IL_0007: ret
} // end of method 'Global Functions'::__EntryPoint
, Main, Program,
App.netmodule. /main, 
AL.exe, ,  
, PE 
. ,
.


AL.exe, /embed[resource]
( , PE).
PE.
ManifestResourceDef , 
.
AL.exe /link[resource],
. Manifest
ResourceDef FileDef ,
. PE ,

.
AL.exe, CSC.exe , 
C#. /resource C#
PE Manifest
ResourceDef. /linkresource Manifest
ResourceDef FileDef .
: Win32.
, AL.exe CSC.exe res /win32res.
, Win32 ,
AL.exe CSC.exe ico /win32icon. Visual
Studio Application
. , (Windows Explorer)
.

52

CLR


AL.exe CSC.exe PE,
Win32 Version. 
, . 
GetVersionInfo System.Diagnostics.FileVersionInfo.
. 24 Version JeffTypes.dll.

. 24. Version JeffTypes.dll


Version
, 
. ,
, . 24:

using System.Reflection;
// CompanyName, LegalCopyright LegalTrademarks
[assembly:AssemblyCompany("Wintellect")]
[assembly:AssemblyCopyright("Copyright (c) Wintellect 2006")]
[assembly:AssemblyTrademark(
"JeffTypes is a registered trademark of Wintellect")]
// ProductName ProductVersion.
[assembly:AssemblyProduct("Wintellect (R) Jeffs Type Library")]
[assembly:AssemblyInformationalVersion("2.0.0.0")]
// FileVersion, FileDescription Comments.
[assembly:AssemblyFileVersion("1.0.0.0")]
[assembly:AssemblyTitle("JeffTypes.dll")]
[assembly:AssemblyDescription("This assembly contains Jeffs types")]
// AssemblyVersion.
[assembly: AssemblyVersion("3.0.0.0")]

2 , ,

53

// ( . " ")
[assembly:AssemblyCulture("")]
. 24 Version 
, . AL.exe, 
,
. . 24 
Version. 
C#; ,
.

. 2-4. Version AL.exe



Version

AL.exe

FILEVERSION

/fileversion

System.Reflection.AssemblyFileVersion
Attribute

PRODUCTVERSION

/productversion

System.Reflection.AssemblyInformational
VersionAttribute

FILEFLAGSMASK

VS_FFI_FILEFLAGSMASK
( WinVer.h 0x0000003F)

FILEFLAGS

FILEOS


VOS__WINDOWS32

FILETYPE

/target

VFT_APP, 
/target:exe /target:winexe. 
/target:library 
VFT_DLL

FILESUBTYPE

VFT2_UNKNOWN
( VFT_APP
VFT_DLL)

AssemblyVersion

/version

System.Reflection.AssemblyVersionAttribute

Comments

/description

System.Reflection.AssemblyDescriptionAttribute

CompanyName

/company

System.Reflection.AssemblyCompanyAttribute

FileDescription

/title

System.Reflection.AssemblyTitleAttribute

FileVersion

/version

System.Reflection.AssemblyVersionAttribute

InternalName

/out


( )

LegalCopyright
LegalTrademarks

/copyright
/trademark

System.Reflection.AssemblyCopyrightAttribute
System.Reflection.AssemblyTrademark Attribute

OriginalFilename

/out


( )

PrivateBuild

ProductName

/product

System.Reflection.AssemblyProductAttribute

ProductVersion

/productversion

System.Reflection.AssemblyInformational
VersionAttribute

SpecialBuild

54

CLR

! C# Visual Studio Assem


blyInfo.cs . ,
,
3. AssemblyInfo.cs
.


, .
: 4 , .

. 2-5.

719

. 25 2.5.719.2. 
, :
2.5. , 719, . 
,
. , 2, .
(, 
, 
), .
Microsoft,
. CLR 

, .
CLR , ,
, , 
(servicing
version) . CLR
(
) .
.
. , 
.
 AssemblyFileVersion Win32
, CLR .
, 
. 
. Microsoft (, CSC.exe
AL.exe) (
), 
. Windows
.

2 , ,

55

 AssemblyInformationalVersion 
Win32 , , 
; CLR . 
, . , 2.0 
. 1.0,
, 1.0.

. 
.
 AssemblyVersion , 
AssemblyDef. CLR 
, ( . 3). 
. 
, , 
; ,
, . 
, , 
AssemblyRef. , 
, .


,
(culture). , , 
, 
. . , 
( RFC1766).
. 26.

. 2-6. ,

de

de

AT

de

CH

en

en

GB

en

US

,
. ,
, 
(culture neutral).
, 
, Microsoft , 

. 
, .

56

CLR

, 
, , .
, ,
(satellite assemblies). 
, ,
.
, .
AL.exe. 

. AL.exe, 
/c[ulture]:text, text (, enUS, 
). 
,
, . , 
C:\MyApp,
C:\MyApp\enUS.

System.Resources.ResourceManager.
, 
. /culture
AL.exe System.Reflection.AssemblyCulture
Attribute, , , :

// Swiss German.
[assembly:AssemblyCulture("deCH")]
, .
, AssemblyRef
. 
,
, (. 22).


( )
,
. ,
.
.
, . ,
 , 
. 
 .
, , 
, CLR ,
. ,
, !

2 , ,

57

, 
, .cab (
).
MSI,
Windows Installer (MSIExec.exe). MSI
CLR .
MSI, EXE
DLL.

, 
(Desktop), (Start) 
. ,
,
, 
. , Windows .
, Visual Studio , 
, Publish 
. , Visual Studio 
MSI Web, FTP
. MSI ,
.NET Framework Microsoft SQL Server 2005 Express Edition. , 

, ClickOnce.
, , , 
(privately deployed assemblies),
(
). 
, 
, 
, CLR .
, , . 
.
// 
. 
, , ,
. , .
, ,
. CLR 
, . CLR 
COM, , 
, .
3 , 
.

58

CLR


( )

. ,

. 
, 3.
, 
.
, 
. , 

. CLR
.
XML
. ( 
, ) , 
: 
, .
3 ,
. , 
JeffTypes, .
:

AppDir ( )
App.exe
App.exe.config ( )
AuxFiles ( JeffTypes)
JeffTypes.dll
FUT.netmodule
RUT.netmodule
JeffTypes 
, CLR ,
System.IO.FileNotFoundException. 
, XML
. 
.config, App.exe.config.
:

<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemasmicrosoftcom:asm.v1">
<probing privatePath="AuxFiles" />
</assemblyBinding>
</runtime>
</configuration>

2 , ,

59

, CLR
, , AuxFiles.
privatePath , , 
, . , 
. ,
, 
.


CLR .
( 
, firstPrivatePath secondPrivatePath privatePath 
):

AppDir\AsmName.dll
AppDir\AsmName\AsmName.dll
AppDir\firstPrivatePath\AsmName.dll
AppDir\firstPrivatePath\AsmName\AsmName.dll
AppDir\secondPrivatePath\AsmName.dll
AppDir\secondPrivatePath\AsmName\AsmName.dll
...
,
JeffTypes JeffTypes, CLR 
, 
.
, CLR
, .exe
.dll. , 
FileNotFoundException.

: ,
, 
. , AsmName.dll 
enUS, :

C:\AppDir\enUS\AsmName.dll
C:\AppDir\enUS\AsmName\AsmName.dll
C:\AppDir\firstPrivatePath\enUS\AsmName.dll
C:\AppDir\firstPrivatePath\enUS\AsmName\AsmName.dll
C:\AppDir\secondPrivatePath\enUS\AsmName.dll
C:\AppDir\secondPrivatePath\enUS\AsmName\AsmName.dll
C:\AppDir\enUS\AsmName.exe
C:\AppDir\enUS\AsmName\AsmName.exe
C:\AppDir\firstPrivatePath\enUS\AsmName.exe
C:\AppDir\firstPrivatePath\enUS\AsmName\AsmName.exe
C:\AppDir\secondPrivatePath\enUS\AsmName.exe
C:\AppDir\secondPrivatePath\enUS\AsmName\AsmName.exe

60

CLR

C:\AppDir\en\AsmName.dll
C:\AppDir\en\AsmName\AsmName.dll
C:\AppDir\firstPrivatePath\en\AsmName.dll
C:\AppDir\firstPrivatePath\en\AsmName\AsmName.dll
C:\AppDir\secondPrivatePath\en\AsmName.dll
C:\AppDir\secondPrivatePath\en\AsmName\AsmName.dll
C:\AppDir\en\AsmName.exe
C:\AppDir\en\AsmName\AsmName.exe
C:\AppDir\firstPrivatePath\en\AsmName.exe
C:\AppDir\firstPrivatePath\en\AsmName\AsmName.exe
C:\AppDir\secondPrivatePath\en\AsmName.exe
C:\AppDir\secondPrivatePath\en\AsmName\AsmName.exe
, CLR .exe .dll. 
( CLR
), XML
,
.
XML
.
 (EXE) 
. ,
EXE, .config.
 ASP.NET Web Form
Web
Web.config. , 
Web.config . 
, Web, http://www.Wintellect.com/Trai
ning, Web.config,
Training.
 , ,
Microsoft Internet Explorer, HTML ,
rel Configuration, href 
URL . :
<LINK REL=Configuration HREF=http://www.Wintellect.com/Controls.config>. 
. .NET Framework,
http://msdn.microsoft.com/library/enus/cpguide/html/cpcondeployingcommonlan
guageruntimeapplicationusingie55.asp
, 
. .NET Framework
Machine.config. Machine.config CLR,
.
Machine.config :

%SystemRoot%\Microsoft.NET\Framework\<>\CONFIG

2 , ,

61

, %SystemRoot% , , Windows
( C:\Windows), <> , 
.NET Framework (, v2.0.50727).
Machine.config
.
Machine.config, ,
,
. ,
,
, .

2 , .
(private deployment),
, ,
.
, "
.
,
.
, Microsoft .NET Frame"
work, , "
Microsoft .NET Framework Class Library (FCL).
2, Windows "
" ,
. Windows, "
, , Microsoft. ,
, "
.
.NET Framework, , ,
.
, Microsoft "
: , "
. . "
. "
,
. "
, Windows.
.
, "
" 0 1 , ,
, ,

63

. "
,
. "
, .
, : ,
, ,
? : "
. , , , "
, "
. "
, ,
, ,
, .
.NET Framework, "
. : "
. ,
, (CLR). ,
, "
. , "
, , ,
.
Micro"
soft, ,
. "
CLR. "
CLR,
. , CLR 2.0
. "
"
.


.NET Framework : (weakly
named assemblies) (strongly named assemblies).
! "
.NET Framework. ? , "
.
, .
, "
, .
,
portable executable (PE) "
PE32(+), CLR", , ,

64

CLR

IL", 1 2.
, C# AL.exe.
,
,
. "
, , ,
. "
CLR "
,
.
, CLR.
.
.
.
2. "
" , CLR
. , .
, . "
. 3"1.

. 3-1.

"
. , CLR , "
, "
. , "
. "
, "
. CLR
, ,
. "
,
CLR.


,
, CLR "
, .
, ( ) ?
,
, , , "

65

, ( "
DLL Windows" DLL"
System32).
, , . CLR "
,
. .
, : ( ),
, . "
, "
,
(public key token). (
assembly display name) "
:

"MyTypes, Version=1.0.8123.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"


"MyTypes, Version=1.0.8123.0, Culture="enUS", PublicKeyToken=b77a5c561934e089"
"MyTypes, Version=2.0.1234.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
"MyTypes, Version=1.0.8123.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
MyTypes.exe MyTypes.dll (
, ).
" 1.0.8123.0; "
, , Culture "
neutral. MyTypes.dll ( MyTypes.exe)
1.0.8123.0 .
, ,
, .
Microsoft ( GUID,
URL URN) , "
. ,

,
. .
, , ,
, "
. , "
,
, .
System.Reflection.AssemblyName "
,
.
: CultureInfo, FullName, KeyPair, Name Version "
, GetPublicKey, GetPublicKey
Token, SetPublicKey SetPublicKeyToken.

66

CLR

2 "
. "

. CLR "
, "
.
, "
, privatePath
XML", CLR (
.dll .exe).
, "
. "
.
"
Strong Name, SN.exe, .NET Framework SDK Microsoft
Visual Studio. , "
, . : "
SN.exe . "
, :

SN k MyCompany.keys
SN.exe MyCompany.keys, "
.
, , .
SN.exe, .
SN.exe . p,
, (MyCompany.PublicKey):

SN p MyCompany.keys MyCompany.PublicKey
SN.exe tp , "
:

SN tp MyCompany.PublicKey
:

Microsoft (R) .NET Framework Strong Name Utility Version 2.0.50727.42


Copyright (c) Microsoft Corporation. All rights reserved.
Public key is
00240000048000009400000006020000002400005253413100040000010001003f9d621b702111
850be453b92bd6a58c020eb7b804f75d67ab302047fc786ffa3797b669215afb4d814a6f294010
b233bac0b8c8098ba809855da256d964c0d07f16463d918d651a4846a62317328cac893626a550
69f21a125bc03193261176dd629eace6c90d36858de3fcb781bfc8b817936a567cad608ae672b6
1fb80eb0
Public key token is 3db32f38c8b42c9a
, SN.exe
.

67

.
( ), "
. 64" .
SN.exe tp, "
.
, ,
.
/keyfile:<_>:

csc /keyfile:MyCompany.keys app.cs


,
(MyCompany.keys), "
. : ,
, .
Visual Studio .
Signing, Sign the assembly,
Choose a strong name key file <New> (. . 3"1).

. 31. Visual Studio


: "
FileDef "
, . , "
, , "
FileDef. "
, , AL.exe "
/algid ,
System.Reflection.AssemblyAlgorithmIdAttribute.
SHA"1, "
.
PE" "
( Authenticode Signature, "

68

CLR

PE) (. 3"2). "


SHA"1, .
,
RSA PE" (
PE" ) CLR" PE" "
, .

. 32.
PE" (
AssemblyDef ). , "
,
, .
, ,
Calculus, (
).
.
2, "
, ;
, .
C# /reference. "
AssemblyRef "
. AssemblyRef
, , "
( ), ,
.

69

! , ,
, "
.
Microsoft "
8 . AssemblyRef "
, , "
. "
,
.
, CLR
,
, "
.
AssemblyRef (
ILDasm.exe) JeffTypes.dll, 2:

AssemblyRef #1 (23000001)

Token: 0x23000001
Public Key or Token: b7 7a 5c 56 19 34 e0 89
Name: mscorlib
Version: 2.0.0.0
Major Version: 0x00000002
Minor Version: 0x00000000
Build Number: 0x00000000
Revision Number: 0x00000000
Locale: <null>
HashValue Blob:
Flags: [none] (00000000)
, JeffTypes.dll ,
:

"MSCorLib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"


, ILDasm.exe Locale,
Culture.
AssemblyDef JeffTypes.dll,
:

Assembly

Token: 0x20000001
Name : JeffTypes
Public Key
:
Hash Algorithm : 0x00008004
Version: 3.0.0.0
Major Version: 0x00000003
Minor Version: 0x00000000
Build Number: 0x00000000

70

CLR

Revision Number: 0x00000000


Locale: <null>
Flags : [none] (00000000)
:

"JeffTypes, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null"


, JeffTypes.dll,
2, , , "
.
SN.exe, /keyfile,
.
ILDasm.exe, AssemblyDef
Public Key, ,
. , AssemblyDef "
, .
. ,
.


, "
CLR .
"
, , CLR
, . , "
, (global
assembly cache, GAC), :

C:\Windows\Assembly
GAC
, .
GAC
, . "
GAC
.
"
GAC GACUtil.exe.
, :

Microsoft (R) .NET Global Assembly Cache Utility. Version 2.0.50727.42


Copyright (c) Microsoft Corporation.All rights reserved.
Usage: Gacutil <command> [ <options> ]
Commands:
/i <assembly_path> [ /r <...> ] [ /f ]
Installs an assembly to the global assembly cache.
/il <assembly_path_list_file> [ /r <...> ] [ /f ]
Installs one or more assemblies to the global assembly cache.

71

/u <assembly_display_name> [ /r <...> ]
Uninstalls an assembly from the global assembly cache.
/ul <assembly_display_name_list_file> [ /r <...> ]
Uninstalls one or more assemblies from the global assembly cache.
/l [ <assembly_name> ]
List the global assembly cache filtered by <assembly_name>
/lr [ <assembly_name> ]
List the global assembly cache with all traced references.
/cdl
Deletes the contents of the download cache
/ldl
Lists the contents of the download cache
/?
Displays a detailed help screen
Options:
/r <reference_scheme> <reference_id> <description>
Specifies a traced reference to install (/i, /il) or uninstall (/u, /ul).
/f
Forces reinstall of an assembly.
/nologo
Suppresses display of the logo banner
/silent
Suppresses display of all output
, GACUtil.exe /i, GAC,
/u, GAC. :
GAC. GACUtil.exe
, : Failure adding assembly
to the cache: Attempt to install an assembly without a strong name (
: ).
GAC
Windows Administrators () Power
Users ( ). GACUtil.exe "
, .
/i GACUtil.exe "
. GACUtil.exe
/r /i
/u . /r

72

CLR

Windows. "
, , ,
, .

cabinet (.cab") , , "
GAC GACUtil.exe,
, "
.
GACUtil.exe
NET Framework, . "
, GAC,
Windows Installer (MSI) 3 , ,
GAC "
. ( Windows Installer
, MSIExec.exe.)
!
GAC , "
Windows. GAC "
, ,
.
,
.
GAC? ,
Calculus, : Calcu"
lus.dll. , , ,
, "
" . GAC "
, C:\Windows\Assembly
.
GAC,
. , GAC
CLR , GAC. , , "
GAC .
.NET Framework "
(ShFusion.dll). " GAC "
, .
C:\Windows\Assembly , , "
GAC (. 3"3). , , "
, ( ), "
.

73

. 33. , GAC,

, "
Delete Properties. , "
GAC, .
. 3"4.
Last Modified , GAC.
Version, , . 3"5.

. 34. General

74

CLR

. 35. Version
, :
, , ,
GAC. "
GAC , GACUtil.exe.

Assembly Cache Viewer :
HKEY_LOCAL_MACHINE\Software\Microsoft\Fusion
DWORD DisableCacheViewer 1.
: C:\Windows\Assembly
Desktop.ini.

GAC
GAC, , "
. , CLR "
, , ,
, .
%SystemRoot%\Assembly, "
. GAC
:

C:\Windows\Assembly\GAC
C:\Windows\Assembly\GAC_MSIL
C:\Windows\Assembly\GAC_32
C:\Windows\Assembly\GAC_64
C:\Windows\Assembly\GAC , 1.0
1.1 CLR. (IL) "

75

x86" (,
Microsoft C++ Managed Extensions).
32" ,
x86 Windows , WoW64, 64""
Windows.
C:\Windows\Assembly\GAC_MSIL ,
2.0 CLR. IL" "
32" 64" , 32"
64" Windows. 32""
64" Windows, "
WoW64.
C:\Windows\Assembly\GAC_32 ,
2.0 CLR. IL" x86" ("
, Microsoft C++/CLI). "
32" ,
x86" Windows ,
WoW64, 64" Windows.
C:\Windows\Assembly\GAC_64 ,
2.0 CLR. IL" x64 IA64.
x64", "
x64". GAC IA64 (Intel Itanium) x64",
. 64" "
, 64"
Windows . 32""
Windows .
,
.
GAC_MSIL, "
, GAC. GAC_MSIL
( ,
):

Volume in drive C has no label.


Volume Serial Number is 2450178A
Directory of C:\WINDOWS\assembly\GAC_MSIL
09/22/2005
09/22/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005

07:38
07:38
10:25
10:25
10:25
10:29
10:25
10:25
10:25
10:25
10:29

AM
AM
AM
AM
AM
AM
AM
AM
AM
AM
AM

<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>

.
..
Accessibility
ADODB
AspNetMMCExt
CppCodeProvider
cscompmgd
IEExecRemote
IEHost
IIEHost
MFCMIFC80

76

08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
...
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005
08/25/2005

10:32
10:32
10:29
10:25
10:25
10:25
10:25
10:32
10:33
10:25

CLR

AM
AM
AM
AM
AM
AM
AM
AM
AM
AM

<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>

Microsoft.AnalysisServices
Microsoft.AnalysisServices.DeploymentEngine
Microsoft.Build.Conversion
Microsoft.Build.Engine
Microsoft.Build.Framework
Microsoft.Build.Tasks
Microsoft.Build.Utilities
Microsoft.DataWarehouse.Interfaces
Microsoft.ExceptionMessageBox
Microsoft.JScript

10:25 AM
<DIR>
System
10:25 AM
<DIR>
System.Configuration
10:25 AM
<DIR>
System.Configuration.Install
10:25 AM
<DIR>
System.Data.SqlXml
10:25 AM
<DIR>
System.Deployment
10:25 AM
<DIR>
System.Design
10:25 AM
<DIR>
System.DirectoryServices
10:25 AM
<DIR>
System.DirectoryServices.Protocols
10:25 AM
<DIR>
System.Drawing
10:25 AM
<DIR>
System.Drawing.Design
10:25 AM
<DIR>
System.Management
10:25 AM
<DIR>
System.Messaging
10:25 AM
<DIR>
System.Runtime.Remoting
10:25 AM
<DIR>
System.Runtime.Serialization.Formatters.Soap
10:25 AM
<DIR>
System.Security
10:25 AM
<DIR>
System.ServiceProcess
10:25 AM
<DIR>
System.Web.Mobile
10:25 AM
<DIR>
System.Web.RegularExpressions
10:25 AM
<DIR>
System.Web.Services
10:25 AM
<DIR>
System.Windows.Forms
10:25 AM
<DIR>
System.Xml
1 File(s)
0 bytes
110 Dir(s) 13,211,459,584 bytes free

, "
. System :

Volume in drive C has no label.


Volume Serial Number is 2450178A
Directory of C:\WINDOWS\assembly\GAC_MSIL\System
08/25/2005 10:25 AM
<DIR>
.
08/25/2005 10:25 AM
<DIR>
..
08/25/2005 10:25 AM
<DIR>
2.0.0.0__b77a5c561934e089
0 File(s)
0 bytes
3 Dir(s) 13,211,467,776 bytes free
System System.dll,
. System.dll:

77

"System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"


: (
)_ (__)_(__
). ,
. ("
, System.dll), System .
! , GAC "
. , GAC
1.0.0.0 2.0.0.0 Calculus.dll. "
1.0.0.0 Calculus.dll,
CLR 1.0.0.0,
GAC . "
CLR , "
, "
. "
.

,

, , "
.
, System.Object MSCorLib.dll, "
. ,
, Microsoft, "
.
2 , CSC.exe /reference
, .
, CSC.exe
. 2,
, CSC.exe "
( , ):
1) ;
2) , CLR. DLL"
CLR;
3) , /lib
CSC.exe;
4) , LIB.
, , System.Dra"
wing.dll Microsoft, /reference:System.Drawing.dll "
CSC.exe.
System.Drawing.dll CLR,
. , "
, .

78

CLR

, .NET Framework ,
Microsoft, .
CLR, GAC. CLR "
, GAC
.
CSC.exe GAC,
C:\WINDOWS\Assembly\GAC_
MSIL\System.Drawing\2.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll. CSC.exe
, "
System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=
b03f5f7f11d50a3a. ,
.
"
, x86 x64. , "
GAC x86 x64 .
, , "
CLR. . .NET Framework
x86, x64 IA64 CLR. "

, "
. "
GAC_32 GAC_64. "
, CLR , .



, "
.
GAC "
RSA, PE"
( ). "
, , "
. , "
"
FileDef.
, , "
GAC .
! "
; , "
, , "
, .
,
Microsoft Authenticode.

79

, ,
CLR GAC (, , "
). , "
, , "
. ,
, ,
. "
, AssemblyRef "
, AssemblyDef , "
. GAC, CLR "
, , "
, , MSI,
CLR MSI .
, Sys
tem.IO.FileNotFoundException.
GAC, ("
, codeBase "
), CLR . ,
.
, ,
. "
, CLR "
System.IO.FileLoadException.



SN.exe. , "
Microsoft API" CryptoAPI. "
"
. , ( Microsoft)
, "
. "
"
. , , , "
.
,
. "
, ,
.NET Framework (delayed signing), 
(partial signing).

, . AssemblyRef
, , "
, "
GAC. , "
,

80

CLR

.
,
, "
.
"
, . ( , "
, , SN.exe "
tp.) , "
, , .
C# /delaysign. Visual Studio
Signing Delay sign only
(. . 3"1). AL.exe /delay[sign].
, , AL.exe
AssemblyDef "
. ,
GAC, , ,
AssembyRef "
. PE" "
RSA. (
, .) ,
.

. GA ,
, "
. GAC,
, SN.exe
Vr. SN.exe CLR "
.
, Vr SN.exe

HKEY_LOCAL_ MACHINE\SOFTWARE\Microsoft\StrongName\Verification.
,
. , "
SN.exe, R
, . R SN.exe
,
RSA . "
. "
, SN.exe Vu Vx.

.
1. , "
, /keyfile
/delaysign:

csc /keyfile:MyCompany.PublicKey /delaysign MyAssembly.cs

81

2. ,
, GAC "
, . "
, .

SN.exe Vr MyAssembly.dll
3. , "
.
GAC, "
. 4.

SN.exe R MyAssembly.dll MyCompany.PrivateKey


4. "
, :

SN Vu MyAssembly.dll
"
, ". , "
, .
(Cryptographic Service Providers, CSP) "
, "
. , Microsoft CSP",
".
CSP",
CSC.exe, AL.exe SN.exe. (CSC.exe)
/keyfile /keycontainer, (AL.exe)
/keyname /keyfile, SN.exe
, ,
Rc R. SN.exe CSP.
! , "
" . , "
, "
. ,
. , "

, .
SN.exe R Rc, "
".



GAC . GAC
, "
. , GAC
"

82

CLR

( ). GAC
. GAC
,
GAC . , GAC
.
GAC,
. GAC,
"
. , "
. "
. , GAC
C:\Windows\System32 "
.
, .
GAC , "
,
. , , "
. "
"
. "
XML", codeBase
.
CLR , , "
. , "
. , "
,
.
codeBase
URL", "
Web. Web" CLR
"
( C:\Documents and
Settings\<UserName>\Local Settings\ApplicationData\Assembly, <UserName>
, ).
CLR
URL". , CLR
( ).
codeBase .
GAC ,
"
. , "
. , GAC,
, CLR ,
, "
.

83



2 :

public sealed class Program {


public static void Main() {
System.Console.WriteLine(Hi);
}
}
, ,
Program.exe. CLR.
CLR CLR" MethodDefToken,
Main, . CLR
MethodDef , "
IL" ,
JIT".
,
. IL" Main. , "
ILDasm.exe, View Show Bytes "
Main .

.method public hidebysig static voidMain() cil managed


// SIG: 00 00 01
{
.entrypoint
// Method begins at RVA 0x2050
// Code size
11 (0xb)
.maxstack 8
IL_0000: /* 72 | (70)000001
*/
ldstr
"Hi"
IL_0005: /* 28 | (0A)000003
*/
call
void [mscorlib]System.Console::WriteLine(string)
IL_000a: /* 2A |
*/
ret
} // end of method Program::Main
JIT" CLR
, ( "
). , System.Console.Write
Line: Call 0A000003. "
3 MemberRef ( 0A). "
, CLR ,
TypeRef ( System.Console). TypeRef CLR
, AssemblyRef. : MSCorLib, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089. CLR ,
, .
CLR "
:

84

CLR

, , "
( 
). , ;
, ,
, FileRef "
. , ,
. , ,
, CLR ,
;
, ,
, .
, ,
CLR , .
ModuleDef, ModuleRef FileDef "
.
AssemblyRef , .

.dll .exe, , "
, 2.

. 36.  ,
CLR, , , IL

85

( "
, . .), "
.
CLR , System.Console
. CLR PE", "
.
PE", .
, , , , CLR
.
CLR
JIT" Main. "
Main.
. 3"6 .
! ,
. , , "
.NET Framework, .
.NET Framework ( MSCorLib.dll)
CLR. , .NET Framework, "
CLR. "
(unification), Microsoft ,
.NET Framework
CLR. "
.
WriteLine System.
Console MSCorLib.dll, CLR,
, MSCorLib.dll
AssemblyRef .
: CLR , , "
. GAC
, , , "
. GAC CLR , "
32" x86 (, "
WoW64), 64" x64 64" IA64.
GAC .
C:\Windows\Assembly\GAC_MSIL.
, C:\Windows\Assembly\GAC
1.x.
, CLR ,
. "
. CLR
.

86

CLR


( )
( )
2
, CLR.
, , , "
CLR XML"
.
2 privatePath
probing, XML":

<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemasmicrosoftcom:asm.v1">
<probing privatePath="AuxFiles;bin\subdir" />
<dependentAssembly>
<assemblyIdentity name="JeffTypes"
publicKeyToken="32ab4ba45e0a69a1" culture="neutral"/>
<bindingRedirect
oldVersion="1.0.0.0" newVersion="2.0.0.0" />
<codeBase version="2.0.0.0"
href="http://www.Wintellect.com/JeffTypes.dll" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="FredTypes"
publicKeyToken="1f2e74e897abbcfe" culture="neutral"/>
<bindingRedirect
oldVersion="3.0.0.03.5.0.0" newVersion="4.0.0.0" />
<publisherPolicy apply="no" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
XML" CLR .
probing AuxFiles bin\subdir, "
,

87

. CLR GAC URL"


, codeBase.
dependentAssembly, assemblyIdentity binding
Redirect : JeffTypes
1.0.0.0 , "
, 32ab4ba45e0a69a1,
, 2.0.0.0.
codeBase JeffTypes
2.0.0.0 , ,
32ab4ba45e0a69a1,
, URL: http://www.Wintellect.
com/JeffTypes.dll. 2, codeBase "
.
, code"
Base. URL, codeBase, "
.
dependentAssembly, assemblyIdentity binding
Redirect FredTypes 3.0.0.0
3.5.0.0 ,
, 1f2e74e897abbcfe, "
, 4.0.0.0.
publisherPolicy , FredTypes,
( .
), CLR .
CLR , "
. , (
AssemblyRef ),
. CLR

, .
apply publisherPolicy yes ,
CLR GAC / "
, ; CLR
/. . "
CLR / Machine.config
.
CLR , "
, GAC. GAC
, codeBase , CLR ,
2. ,
, codeBase, CLR URL""
, .

, CLR
. , "
, ,

88

CLR

. CLR , "
XML" .
XML" Microsoft .NET
Framework Configuration, .NET Framework SDK.
, "
.NET Framework. , 
(Control Panel), (Administrative Tools),
Microsoft .NET Framework Configuration.
, , ,
,
Machine.config , CLR
"
.
, "
,
, , . , "
, , "
. .


, ,
, "
XML" . "
, ,
. ,
" CLR, ,
. , "
XML" , ,
. , "

. ,
.
, , ,
. "
, XML".
, . JeffTypes.config, "
JeffTypes.dll:

<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemasmicrosoftcom:asm.v1">
<dependentAssembly>
<assemblyIdentity name="JeffTypes"
publicKeyToken="32ab4ba45e0a69a1" culture=" neutral"/>
<bindingRedirect
oldVersion="1.0.0.0" newVersion=" 2.0.0.0" />

89

<codeBase version="2.0.0.0"
href="http://www.Wintellect.com/JeffTypes.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
, . "
, ,
. ,
probing publisherPolicy.
CLR
1.0.0.0 JeffTypes 2.0.0.0. , "
, ,
. AL.exe
:

AL.exe /out:policy.1.0.JeffTypes.dll
/version:1.0.0.0
/keyfile:MyCompany.keys
/linkresource:JeffTypes.config
AL.exe .
/out AL.exe PE" Policy.1.0.JeffTypes.dll,
, . "
. , Policy, CLR,
. , 1.0,
CLR, Jeff"
Types, 1.0. "
;

. , JeffTypes, , "
. , dll, "
, .
/version ,
. , ,
, . "
, CLR 1.0.0.0 JeffTypes
2.0.0.0, , "
1.0.0.0 JeffTypes 2.5.0.0. CLR
, ,
.
/keyfile AL.exe
, . "
, JeffTypes.
CLR , JeffTypes
.

90

CLR

/linkresource AL.exe XML" "


.
. "
JeffTypes. , "
XML" , AL.exe /embedre
source, , ,
CLR , XML
.
, ,
JeffTypes.dll .
GAC. JeffTypes
GAC, . "
, URL" codeBase.
!
"
.
.
. ,
, "
, . , CLR "
. "
, publisherPolicy:

<publisherPolicy apply="no"/>

<assemblyBinding>
, <dependantAssembly> .
, CLR ,
GAC , "
. , CLR "
, Machine.config.
! "
.
, "
. , "
, .
.
, ,
,
. , "
.

I I


(Common Language Runtime, CLR). , 
, , 
, ,
. ,
, , .

System.Object
CLR System.Object.
, :

// , Object
class Employee {
...
}

// , Object
class Employee : System.Object {
...
}

,
System.Object,
. System.Object 
. 41.

. 4-1. System.Object

Equals

true, .
. 5

GetHashCode

 .
, 
. , 
Object,
; 
. . 5

93

. 4-1. ()

ToString

(this.GetType().Full
Name). , 
String, .
,
, Boolean Int32, 
. ,
: , 
. , ToString
CultureInfo, .
ToString . 11

GetType

, Type,
, GetType.
Type , 
.
. 22. GetType ,
,
.

, , System.Object,
(. . 42).

. 4-2. System.Object

MemberwiseClone



this.

Finalize

, 
, ,
. ,
, .
. 20

CLR , new.
Employee :

Employee e = new Employee("ConstructorParam1");


new .
1. ,
System.Object (
). 
,  (type object pointer)
(SyncBlockIndex) CLR 
. ,
.
2. , 
.
3.  SyncBlockIndex.
4. , 
new ( ConstructorParam1). 

94

II

.

. 
. , 
System.Object, 
. , ILDasm.exe MSCorLib.dll
 System.Object.
, new ( )
. 
e Employee.
, new delete, 
, . CLR
(. 20), , 
.


CLR (type safety). 
CLR. 
GetType. , 
. , Employee 
GetType, SpaceShuttle.

. CLR 
.  
. , C# 
,
. 
C# 
. 
:

// System.Object.
internal class Employee {
...
}
public sealed class Program {
public static void Main() {
// , new Employee,
// Object Employee.
Object o = new Employee();
// , Employee Object.
// ( Visual Basic)
// .
Employee e = (Employee) o;
}
}

95

,
. ? CLR 
,
, . , 
, InvalidCastException:

internal class Employee {


...
}
internal class Manager : Employee {
...
}
public sealed class Program {
public static void Main() {
// Manager PromoteEmployee.
// Manager Object,
// PromoteEmployee .
Manager m = new Manager();
PromoteEmployee(m);
// DateTime PromoteEmployee.
// DateTime Employee,
// PromoteEmployee System.InvalidCastException.
DateTime newYears = new DateTime(2007, 1, 1);
PromoteEmployee(newYears);
}
public static void PromoteEmployee(Object o) {
// ,
// o, .
// CLR ,
// o ( ),
// , Employee
// , Employee.
Employee e = (Employee) o;
...
}
}
Main Manager PromoteEmployee.
, Manager Object,
PromoteEmployee. PromoteEmployee CLR ,
o Employee , Employee.
Manager Employee, CLR ,
PromoteEmployee .
PromoteEmployee , Main
DateTime, PromoteEmployee. DateTime 
Object, , PromoteEmployee,
. PromoteEmployee CLR , o

96

II

DateTime, Employee, ,
Employee. CLR 
System.InvalidCastException.
, 
. :
,
. 
. 
CLR .
, PromoteEmp
loyee Object, Employee. Object,
, C# CLR.

C#
is as
C# . , , is 
, 
Boolean: true false. is 
. :

Object o = new Object();


Boolean b1 = (o is Object); // b1 true.
Boolean b2 = (o is Employee); // b2 false.
null, is false,
, .
is :

if (o is Employee) {
Employee e = (Employee) o;
// e if.
}
CLR :
is o Employee, if
, o Employee. CLR
, 
, CLR , 
(o),
(Employee).
, C# ,
as:

Employee e = o as Employee;
if (e != null) {
// e if.
}
CLR o Employee, , as
. o Employee 

97

, as null. : as CLR 
, if e null
, .
as ,
. , 
null. null
, NullReferenceException. 
, :

System.Object o = new Object(); // Object.


Employee e = o as Employee;
// o Employee.
// : , e null.
e.ToString();

// e NullReferenceException.

, , . ,
:

internal class B {
}

// .

internal class D : B { // .
}
. 43 C# , 
CLR.
, OK,
CTE (compiletime error), 
RTE (runtime error).

. 4-3.

OK

Object o1 = new Object();

Object o2 = new B();

Object o3 = new D();

Object o4 = o3;

B b1 = new B();

B b2 = new D();

D d1 = new D();

B b3 = new Object();

D d3 = b2;

D d4 = (D) d1;

D d5 = (D) b2;

D d6 = (D) b1;

B b5 = (B) o1;
B b6 = (D) b2;

RTE

D d2 = new Object();
B b4 = d1;

CTE

98

II



, . ,
System.Text , System.IO
.
System.IO.FileStream System.Text.StringBuilder:

public sealed class Program {


public static void Main() {
System.IO.FileStream fs = new System.IO.FileStream(...);
System.Text.StringBuilder sb = new System.Text.StringBuilder();
}
}
,
FileStream StringBuilder . , 
, 
. , C# using, Visual Basic
Imports. :

using System.IO;
// "System.IO".
using System.Text; // "System.Text".
public sealed class Program {
public static void Main() {
FileStream fs = new FileStream(...);
StringBuilder sb = new StringBuilder();
}
}
, 

, . , 
FileStream System.IO.FileStream, StringBuilder System.Text.StringBuilder.
using C# Imports Visual Basic 
; . using
C# .
! CLR .
 CLR (
) , 
, ,
.
, 
: 
, , 
, , . .
,
System.IO. ,

99

. 
, System.Text. 
using, , File
Stream StringBuilder System.
IO.FileStream System.Collections.StringBuilder. , ,
.
/reference (. 2
3), .
. , 

. ,
, . C# 
MSCorLib.dll, .
FCL, Object,
Int32, String .
, 
, ( ) 
. Microsoft 
. . CLR 
. , ,
Microsoft Wintellect, ,
Widget. 
, , , .
Widget Microsoft Microsoft.Widget, Widget
Wintellect Wintellect.Widget. Widget 
, C# error CS0104: Widget is an ambiguous
reference ( CS0104: Widget ):

using Microsoft; // "Microsoft."


using Wintellect; // "Wintellect."
public sealed class Program {
public static void Main() {
Widget w = new Widget();// .
}
}
, ,
Widget :

using Microsoft; // "Microsoft."


using Wintellect; // "Wintellect."
public sealed class Program {
public static void Main() {
Wintellect.Widget w = new Wintellect.Widget(); // .
}
}

100

II

C# using,
. ,
, 
. 
:

using Microsoft; // "Microsoft."


using Wintellect; // "Wintellect."
// WintellectWidget Wintellect.Widget.
using WintellectWidget = Wintellect.Widget;
public sealed class Program {
public static void Main() {
WintellectWidget w = new WintellectWidget(); // .
}
}
, 
. , Australian Boomerang Company (ABC) Alaskan Boat
Corporation (ABC) BuyProduct
. , 
ABC, BuyProduct. , 
, , ,

, . C# 
(extern aliases),
.
( ) .
. C#.
, , 
, ,
.
,
, . .NET Framework
SDK Microsoft Microsoft ( 
, Microsoft.CSharp, Microsoft.VisualBasic Microsoft.Win32).
, ( C#):

namespace CompanyName {
public sealed class A {
}
namespace X {
public sealed class B { ... }
}

// TypeDef: CompanyName.A

// TypeDef: CompanyName.X.B

}
, 
; 
CLR.

101

,
namespace . C# namespace 

.


(, )
. , ,
, . 
, System.IO.FileStream MSCorLib.dll, System.IO.File
SystemWatcher System.dll. System.dll
.NET Framework.
.
, MSCorLib.dll System.Int32 System.Text.String
Builder.
.NET Framework SDK , 

. . 41 Syntax ,
ResXFileRef System.Resources, 
System.Windows.Forms.dll. 
, ResXFileRef, 
using System.Resources; /r:System.Windows.
Forms.dll .

. 41.
.NET Framework SDK

102

II



, , 
, . , ,
, . 
. , ,
, CLR, ,
, CLR.
. 42 Microsoft Windows 
CLR. .
1 .

. . 42 .
( 
).  , 
 ( 
). , , M1.

. 42. M1
, , (prologue
code), . 
(epilogue code), , 
,
. M1
name (. 43).

. 43. M1

103

M1 M2, 
name. name
(. 44). M2 
 s. (, 
,
.) , 
( . 44).

. 44. M2 M1

M2 
length tally (. 45).
M2. M2 , 
, 
M2 , . 43. 
M1, M2,
, M1.

. 45.
M2
M1 ,
(
, name),

104

II

M1 , . 42. 
, ,
M1, 
, .
CLR. ,
:

internal class Employee {


public
Int32
public virtual String
public static Employee
}

GetYearsEmployed() { ... }
GenProgressReport() { ... }
Lookup(String name) { ... }

internal sealed class Manager : Employee {


public override String GenProgressReport() { ... }
}
Windows , CLR, 
, ( 1 ).
 , M3 (. 46). M3
, , CLR; 
, .

. 46. CLR , ,
, M3
IL 3 JIT
, M3 Employee, Int32, Manager
String ( Joe). CLR
AppDomain , . , 
, CLR
, .
Employee Manager . 47. M3

105

 , , Int32 String
( , ),
.

. 47. M3 Employee Manager


.
, :
 . Employee Manager
. , 
. .
, 
, . 1.
Employee (GetYearsEmployed, GenProgressReport
Lookup), . Manager
( GenProgressReport), 
.
CLR
 M3,
M3. M3
(. . 48). , CLR
null 0
() .
, M3 Manager.
Manager, Manager (. 49).
Manager , 
. ,
, Manager,
,
Manager ( Employee Object). 
CLR 

106

II

 ,  (
 Manager). , CLR
(SyncBlockIndex)
null 0 () , , 
, . 
new Manager, 
e ( ).

. 48.
M3

. 49. Manager

107

M3 Lookup Emplo
yee. CLR , 
, .
 CLR 
, JIT ( ) 
. ,
Lookup Employee , 
Joe. , , Joe
, Lookup Manager, 
Joe . 
e. . 410.

. 410. Lookup Employee


Manager Joe
, e Manager.
, , 
,
.
M3 Get
YearsEmployed Employee. CLR 
, , . 
e Employee. (
Employee, CLR 
Object.) CLR
 ,
JIT ( ) 
. , GetYearsEmployed 5,
Joe . 
year (. 411).

108

II

. 411. GetYearsEmployeed
Employee 5
M3 GenProgress
Report Employee. CLR 
. , CLR
, ,
. , e Joe Manager. 
, CLR  ;
. CLR 
, JIT (
) . , Get
YearsEmployed 5, Joe .
GenProgressReport Manager,
e Manager. . 412.

. 412. GenProgressReport
Employee Manager

109

, Lookup Employee , Joe Employee,


Manager, Lookup Employee,  
Employee, , 
GenProgressReport Employee, Manager.
, , IL 
JIT, ,
,
. ,  (
). , CLR 
, .
CLR
, , 
. , 
CLR.
, Employee Manager 
 . , 
, , . , CLR 
. : 
?. , CLR 
 System.Type ( MSCorLib.dll). 
Employee Manager , 
 ,
 System.Type (. 413).

. 413. Manager Employee


System.Type
,  System.Type 
 , , 
. ,  System.Type
. ,
CLR. , GetType System.

110

II

Object ,  
. , GetType  
, 
( ).

,
Microsoft .NET Framework. , 
. .NET Frame
work, , ,
, 
. , 

.


, 
. , 
:

System.Int32 a = new System.Int32();


, 
. , ( C#) 
, :

int a = 0;
, 
IL System.Int32. ,
, (primitive types)
.NET Framework Class Library
(FCL). , C# int System.Int32. , 
IL:

int a = 0;
//
System.Int32 a = 0;
//
int a = new int();
//
System.Int32 a = new System.Int32();//

.
.
.
.

112

II

. 51 FCL
C#. , Com
mon Language Specification (CLS), 
. , CLS,
.

. 5-1. C# FCL

C#

FCL

CLS

sbyte

System.SByte

8

byte

System.Byte

8

short

System.Int16

16

ushort

System.UInt16

16

int

System.Int32

32

uint

System.UInt32

32

long

System.Int64

64

ulong

System.UInt64

64

char

System.Char

16 Unicode (char


8
, 
C++)

float

System.Single

32 float IEEE

double

System.Double

64 float IEEE

bool

System.Boolean

(True False)

decimal

System.Decimal

128 
,

,
.
, 96

, 8 
10,
96 (
0 28).

object

System.Object

string

System.String

, , C# 
, using ( 
4):

using
using
using
using
using
using
...

sbyte
byte
short
ushort
int
uint

=
=
=
=
=
=

System.SByte;
System.Byte;
System.Int16;
System.UInt16;
System.Int32;
System.UInt32;

113


C#: 
, .
FCL . ,
,
FCL. .
, , : string
String. C# , string 
FCL System.String.
C# long System.Int64, Int16
Int32. , ++ (C++/CLI) long
Int32.  ,
, .
long, ,
.
FCL , .
, BinaryReader ReadBoolean, ReadInt32 ReadSingle
. ., System.Convert ToBoolean, ToInt32 ToSingle . .
, , float, 
, , :

BinaryReader br = new BinaryReader(...);


float val = br.ReadSingle();
// , .
Single val = br.ReadSingle();
// .
FCL.
, 
:

Int32 i = 5; // 32 .
Int64 l = i; // 64 .
, , 4, 
, .  System.Int32 System.Int64
. :
, . , .
, C#
. , 
IL
, , . 
, , 
.
,
, :

Int32 i
Int64 l
Single s
Byte b
Int16 v

=
=
=
=
=

5;
i;
i;
(Byte) i;
(Int16) s;

//
//
//
//
//

Int32 Int32.
Int32 Int64.
Int32 Single.
Int32 Byte.
Single Int16.

114

II

C# , ,
; Int32 Int64.
C# 
. 
. , Int32 Byte
, Int32
; Single Int16, 
Single , Int16.

. , 6,8 Single Int32 
, Int32 6, 
7. , C# . 

C#, (Conversions).
,
: . 
, , 
:

Console.WriteLine(123.ToString() + 456.ToString()); // "123456"


, , , , 
, .

Boolean found = false; // found 0.


Int32 x = 100 + 20 + 3;// x 123.
String s = "a " + "bc";// s "a bc".
, , , 
( +, , *, /, %, &, ^, |, ==, !=, >, <, >=, <=, <<, >>,
~, !, ++,  . .):

Int32 x = 100;
Int32 y = x + 23;
Boolean lessThanFifty = (y < 50);

// .
// .
// " " .



, 
:

Byte b = 100;
b = (Byte) (b + 200); // b 44 ( 2C).

, , , . ,
(, ), 
, .
. C C++
;

115

. Visual Basic ,
, .
! CLR
32 64 . b 200
32 ( 64, 
32 ) , . 
200 b ( 32) 32
. 32 ,
b, Byte.
C# , 
Byte.
CLR IL, 
. , add, 
, add.ovf, 
System.OverflowException. , CLR IL
(sub/sub.ovf), (mul/mul.ovf)
(conv/conv.ovf).
C# , 
; . , 
, , 
IL . 
,
.

, /checked+.
, , ,
IL 
. , CLR 
, . , CLR
OverflowException.
.

. 
, . C# 
checked unchecked.
(, ):

UInt32 invalid = unchecked((UInt32) 1);

// OK.

checked (, 
):

Byte b = 100;
b = checked((Byte) (b + 200));

// OverflowException.

b 200 32 ;
300. 300 Byte OverflowException.
Byte checked, .

116

II

b = (Byte) checked(b + 200);

// b 44; OverflowException.

checked unchecked, C# ,
:

checked {
// .
Byte b = 100;
b = (Byte) (b + 200); // .
}
// .
, +=, 
:

checked {
Byte b = 100;
b += 200;
}

// .
// .
// .

! 
, checked,
( ) checked
IL , ,
. :

checked {
// , SomeMethod 400 Byte.
SomeMethod(400);
// OverflowException SomeMethod
// .
}
checked unchecked, .
checked , 
, ,
, .
unchecked , 
, .
, checked unchecked, 
, ,
(, ),
.
/checked+. 
,
, checked unchecked. 
, . 
/checked, , 
.

117

! System.Decimal .
( C# Visual Basic) CLR Decimal
. CLR IL 
Decimal. .NET Framework ,
Decimal  Add, Subtract, Multiply,
Divide , +, , *, / . .
Decimal
Decimal, . Deci
mal CLR. ,
IL Decimal,
checked unchecked, 
. Decimal
OverflowException.


CLR : (reference types) 
(value types). FCL ,
.
, C# new , 
. 
, :
;
, , 
, ;
(
);
.
,
. , , 
Int32 ! ,
, , CLR 
.
( ). 
; 
. 
, (derefe
rence) . , 
,
(collections),
.
.NET Framework ,
, . (class),
. , System.Object, System.Exception, System.IO.FileStream
System.Random . 

118

II

(structure) (enumeration).
, System.Int32, System.Boolean, System.Decimal, System.TimeSpan
System.DayOfWeek, System.IO.FileAttributes System.Drawing.FontStyle
.
, 
System.ValueType,
System.Object.
System.ValueType. 
System.Enum, System.ValueType.
CLR  .
. 12.

, 
. , CLR 
,  
. , ,
Boolean, Char, Int32, Uint64, Single, Double, Decimal . .
! ( , 
C/C++) 
. C/C++ 
, , : 
. : , 
, , ,
, , .
. 51 :

// ( 'class').
class SomeRef { public Int32 x; }
// ( 'struct')
struct SomeVal { public Int32 x; }
static void ValueTypeDemo() {
SomeRef r1 = new SomeRef(); // .
SomeVal v1 = new SomeVal(); // .
r1.x = 5;
// .
v1.x = 5;
// .
Console.WriteLine(r1.x);
// "5".
Console.WriteLine(v1.x);
// "5".
// . 51
// .
SomeRef r2 = r1;
SomeVal v2 = v1;
r1.x = 8;
v1.x = 9;
Console.WriteLine(r1.x);

//
//
//
//
//

().
.
r1.x r2.x.
v1.x, v2.x.
"8".

119

Console.WriteLine(r2.x);
// "8".
Console.WriteLine(v1.x);
// "9".
Console.WriteLine(v2.x);
// "5".
// . 51
// .
}
SomeVal struct,
class. C# , struct, , 
class, .
. ,
: 
.

. 51.
:

SomeVal v1 = new SomeVal();

// .

, SomeVal .
, C# , SomeVal , 
SomeVal . C#
.
:

SomeVal v1;

// .

IL, SomeVal 
. , , 
new, C# . :

// , C# ,
// v1 .
SomeVal v1 = new SomeVal();
Int32 a = v1.x;

120

II

// , C# ,
// v1 .
SomeVal v1;
Int32 a = v1.x; // error CS0170: Use of possibly unassigned field 'x'
// ( CS0170: 'x', ).
, ,
. .
, .
. , , 
,
, , (immutable).
.
.
,
,
, . :
, , 
, , 
.
,
:
( 16 );
( 16 )

.
, 
. , ,
. ,
.
: (unboxed)
(boxed) (. ).
.
System.ValueType.
, System.Object. System.ValueType 
Equals, true,
. , System.ValueType GetHashCode,
 ,
. 
, ,
Equals GetHash
Code. Equals GetHashCode .

,
.
( ).

121

. 
, null,
. 
Null
ReferenceException. 
, 
0.
, NullRefe
renceException . CLR
, null, (nullable types).
18.

, . 
,
.
, 
, ,
, , 
. , 
,
.
, , 
, ,
. ,
( Finalize), 
.
, 
Finalize,
. ( C#,
C++/CLI Visual Basic) 
Finalize. , CLR
Finalize,
.

CLR
CLR 
. , CLR
, ,
.
, ,
, CLR .
CLR ,
System.Runtime.InteropServices.StructLayout
Attribute. CLR, 

122

II

LayoutKind.Auto, 
LayoutKind.Sequential, Layout
Kind.Explicit , .
StructLayoutAttribute,
.
() Microsoft C# Lay
outKind.Auto, () LayoutKind.Sequential. 
, , 
, ,
, .
, , 
,
:

using System;
using System.Runtime.InteropServices;
// CLR
// .
[StructLayout(LayoutKind.Auto)]
internal struct SomeValType {
Byte b;
Int16 x;
}
StructLayoutAttribute
, LayoutKind.Explicit. 
System.Runtime.InteropServices.FieldOffsetAttribute
Int32, 
( ) ,
. ,
C/C++ (union), 
. :

using System;
using System.Runtime.InteropServices;
// .
[StructLayout(LayoutKind.Explicit)]
internal struct SomeValType {
[FieldOffset(0)] Byte b; // b x
[FieldOffset(0)] Int16 x; // .
}
, ,
. ,
, 
, 
.  

, .

123


: 
, 
. . 
, Point ArrayList (
System.Collections). :

// .
struct Point {
public Int32 x, y;
}
public sealed class Program {
public static void Main() {
ArrayList a = new ArrayList();
Point p;
// Point ( ).
for (Int32 i = 0; i < 10; i++) {
p.x = p.y = i; // .
a.Add(p);
//
// ArrayList.
}
...
}
}
Point. 
Point ArrayList. , ArrayList:
Point, Point  ? Add
ArrayList .
Add :

public virtual Int32 Add(Object value);


, Add Object, (
) . p,
Point. , 
Point .

(boxing). .
1. . 
,
,  SyncBlockIndex.
2. , .
3. . ;
.
, C#, IL
, , 
, ,
.

124

II

C# , ,
, ,
. p Point
Point. 
Point ( )
Add. Point .
p Point
, ArrayList . : 
.
, CLR (, C# Visual Basic), 
, 
. ( C++ Managed Extensions) ,
, .
, FCL 
, 
. , System.Collections.ArrayList 
System.Collections.Generic.List<T>.
.
, API ,
. 

, 
/. 
, 
, , , 
. 
,
.
16.
, . , 
ArrayList:

Point p = (Point) a[0];


( ), 0
ArrayList, p Point. 
, Point, 
p , . CLR
. Point
Point. (unboxing).
, .
.
, ,
( ), . ,
. 
( ).

125

, 
.
, /
( , ),
, ,
.
.
1. , , null,
NullReferenceException.
2. , 
, InvalidCastException.1
, ,
:

public static void Main() {


Int32 x = 5;
Object o = x;
// x; o .
Int16 y = (Int16) o; // InvalidCastException.
}
, Int32, 
o, Int16. , ,
( , Int32).
:

public static void Main() {


Int32 x = 5;
Object o = x;
Int16 y = (Int16)(Int32) o;
}

// x; o .
// , .

, .
C# ,
:

public static void Main() {


Point p;
p.x = p.y = 1;
Object o = p;
// p; o .
p = (Point) o; // o .
}
C# IL o
( ) IL
p, .

CLR , 
null (. 18).

126

II

public static void Main() {


Point p;
p.x = p.y = 1;
Object o = p;
// p; o .
// x Point ( 2).
p = (Point) o;
// o
// .
p.x = 2;
// .
o = p;
// p; o .
}
x Point 1 2.
, , ( )
( ). , ,
.
, C++/CLI, 
, . 
(
 SyncBlockIndex). , ,
(
). , 
, C++/CLI,
x Point Point.
, !
! 
, , , 
. , 
, ,
. 
, , ILDasm.exe, 
IL box.
, :

public static void Main() {


Int32 v = 5;
// .
Object o = v;
// o Int32, 5.
v = 123;
// 123.
Console.WriteLine(v + ", " + (Int32) o); // "123, 5"
}
?
! , , IL Main.
, .

127

.method public hidebysig static voidMain() cil managed


{
.entrypoint
// 45 (0x2e).
.maxstack 3
.locals init (int32 V_0,
object V_1)
// 5 v.
IL_0000: ldc.i4.5
IL_0001: stloc.0
// v o.
IL_0002: ldloc.0
IL_0003: box
[mscorlib]System.Int32
IL_0008: stloc.1
// 123 v.
IL_0009: ldc.i4.s 123
IL_000b: stloc.0
// v Concat.
IL_000c: ldloc.0
IL_000d: box
[mscorlib]System.Int32
// Concat.
IL_0012: ldstr
", "
// o: Int32 .
IL_0017: ldloc.1
IL_0018: unbox.any [mscorlib]System.Int32
// Int32 Concat.
IL_001d: box
[mscorlib]System.Int32
// Concat.
IL_0022: call

string [mscorlib]System.String::Concat(object,
object,
object)

// , Concat, WriteLine.
IL_0027: call
void [mscorlib]System.Console::WriteLine(string)
// Main .
IL_002c: ret
} // App::Main
v Int32, 
5. o Object,
v. ,
, C# IL v 
v o. 123 

128

II

v, Int32, 
5.
WriteLine, String,
. 
Int32 (v), String ( )
Int32 (o), 
Int32.  ,
String.
String, C# , 
Concat String.
, . 
,
Concat:

public static String Concat(Object arg0, Object arg1, Object arg2);


, arg0, v. v 
, arg0 Object, v , 
arg0. arg1 , String.
, , arg2, o ( Object)
Int32. ( ), 
Int32 Int32.
Int32 ,
arg2 Concat.
Concat ToString 
.
Concat String WriteLine, 
.
IL , WriteLine 
:

Console.WriteLine(v + ", " + o);

// "123, 5"

, 
(Int32) o. ,
o Object,
Concat. , : 
. , 
IL:

.method public hidebysig static voidMain() cil managed


{
.entrypoint
// 35 (0x23).
.maxstack 3
.locals init (int32 V_0,
object V_1)
// 5 v.
IL_0000: ldc.i4.5
IL_0001: stloc.0

129

// v o.
IL_0002: ldloc.0
IL_0003: box
[mscorlib]System.Int32
IL_0008: stloc.1
// 123 v.
IL_0009: ldc.i4.s 123
IL_000b: stloc.0
// v Concat.
IL_000c: ldloc.0
IL_000d: box
[mscorlib]System.Int32
// Concat.
IL_0012: ldstr
", "
// Int32 Concat.
IL_0017: ldloc.1
// Concat.
IL_0018: call
string [mscorlib]System.String::Concat(object,
object,
object)
// , Concat, WriteLine.
IL_001d: call
void [mscorlib]System.Console::WriteLine(string)
// Main , .
IL_0022: ret
} // App::Main
IL Main ,
(Int32) 10 , .
/, , 
. , ,
,
. ,
,
, (, ), 
.
, WriteLine:

Console.WriteLine(v.ToString() + ", " + o);

// "123, 5".

v ToString, 
String.
Concat .
, :

public static void Main() {


Int32 v = 5;
// .
Object o = v;
// o v.

130

II

v = 123;
// 123.
Console.WriteLine(v); // "123".
v = (Int32) o;
// o v.
Console.WriteLine(v); // "5".
}
? .
, System.Console WriteLine, 
Int32:

public static void WriteLine(Int32 value);


WriteLine v,
Int32, . ,  WriteLine
Int32, . ,
, : .
FCL, , 
. , System.Console
WriteLine:

public
public
public
public
public
public
public
public
public
public
public
public

static
static
static
static
static
static
static
static
static
static
static
static

void
void
void
void
void
void
void
void
void
void
void
void

WriteLine(Boolean);
WriteLine(Char);
WriteLine(Char[]);
WriteLine(Int32);
WriteLine(UInt32);
WriteLine(Int64);
WriteLine(UInt64);
WriteLine(Single);
WriteLine(Double);
WriteLine(Decimal);
WriteLine(Object);
WriteLine(String);

Write System.Console,
Write System.IO.BinaryWriter, Write WriteLine System.
IO.TextWriter, AddValue System.Runtime.Serialization.SerializationInfo,
Append Insert System.Text.StringBuilder . . 
, 
.
, FCL 
. , 
, FCL,
. , 
, 
, Object. Object
, . 
, (,
, ).
, ,
(. 16).

131

, : , 
 , 
, . 
:

using System;
public sealed class Program {
public static void Main() {
Int32 v = 5; // .
#if INEFFICIENT
// v
// , , .
Console.WriteLine("{0}, {1}, {2}", v, v, v);
#else
// ,
// .
Object o = v; // v ( ).
// .
Console.WriteLine("{0}, {1}, {2}", o, o, o);
#endif
}
}
INEFFICIENT, 
, v
! ,
5.
INEFFICIENT, v
. Console.WriteLine
.
.
,
. : ,
. ,
, .
, .
, , , 
, :
;
, : 
 SyncBlockIndex.
SyncBlockIndex, 
,
System.Threading.Monitor ( lock C#).
,

132

II

( Equals, GetHashCode ToString). , CLR


, System.ValueType 
, this 
. ,
.
, CLR .
, (, GetType
MemberwiseClone) , 
System.Object, , this 
.
, 
, ,
. ( . 14.)
:

using System;
internal struct Point : IComparable {
private Int32 m_x, m_y;
// , .
public Point(Int32 x, Int32 y) {
m_x = x;
m_y = y;
}
// ToString, System.ValueType.
public override String ToString() {
// Point .
return String.Format("({0}, {1})", m_x, m_y);
}
// CompareTo.
public Int32 CompareTo(Point other) {
// ,
// (0, 0).
return Math.Sign(Math.Sqrt(m_x * m_x + m_y * m_y)
 Math.Sqrt(other.m_x * other.m_x + other.m_y * other.m_y));
}
// CompareTo IComparable.
public Int32 CompareTo(Object o) {
if (GetType() != o.GetType()) {
throw new ArgumentException("o is not a Point");
}
// CompareTo.
return CompareTo((Point) o);
}
}

133

public static class Program {


public static void Main() {
// Point.
Point p1 = new Point(10, 10);
Point p2 = new Point(20, 20);
// p1 ToString ( ).
Console.WriteLine(p1.ToString());// "(10, 10)"
// p GetType ( ).
Console.WriteLine(p1.GetType());// "Point"
// p1 CompareTo.
// p2 , CompareTo(Point).
Console.WriteLine(p1.CompareTo(p2));// "1"
// p1 , c.
IComparable c = p1;
Console.WriteLine(c.GetType());// "Point"
// p1 CompareTo.
// CompareTo Point,
// CompareTo(Object),
// Point.
// c , Point.
Console.WriteLine(p1.CompareTo(c));// "0"
// c , Point.
// p2 , CompareTo(Object).
Console.WriteLine(c.CompareTo(p2));// "1"
// c , p2.
p2 = (Point) c;
// , p2.
Console.WriteLine(p2.ToString());// "(10, 10)"
}
}
,
/.
ToString ToString p1 .
, p1 , ToString , 
, System.ValueType. ,
, , p1
,  Point. C#
, ToString Point, , 
() ToString. ,
, Point ,
 
.

134

II

GetType GetType p1 
, Point GetType, System.Object.
GetType  Point,
p1.
CompareTo CompareTo p1
, Point CompareTo
. : CompareTo p2
Point, CompareTo,
Point. , p2
CompareTo , .
IComparable p1
(), p1 , 
. 
p1, c.
GetType , c
Point .
CompareTo CompareTo p1 
, Point CompareTo
. , CompareTo
IComparable, 
CompareTo, Object. ,
,
. , Point , ,
c CompareTo, 
.
CompareTo CompareTo c
Point . c
IComparable, CompareTo ,
Object. ,
, .
p2 CompareTo.
Point c Point,
, c, , 
p2, Point, .
, ,
. , 
.NET Framework, 

.



, , .
: , :

135

using System;
// Point  .
internal struct Point {
private Int32 m_x, m_y;
public Point(Int32 x, Int32 y) {
m_x = x;
m_y = y;
}
public void Change(Int32 x, Int32 y) {
m_x = x; m_y = y;
}
public override String ToString() {
return String.Format("({0}, {1})", m_x, m_y);
}
}
public sealed class Program {
public static void Main() {
Point p = new Point(1, 1);
Console.WriteLine(p);
p.Change(2, 2);
Console.WriteLine(p);
Object o = p;
Console.WriteLine(o);
((Point) o).Change(3, 3);
Console.WriteLine(o);
}
}
: Main p Point
m_x m_y 1. p WriteLine,
ToString Point, , ,
(1, 1). p Change, 
m_x m_y p 2. WriteLine
, , (2, 2).
p o
Point. WriteLine (2, 2),
. , , Change 
Point. Object ( o)
Change, o Point. 
o , Point
Point . m_x m_y 

136

II

3, Change
Point. WriteLine (2, 2).
.
, C++/CLI,
, C#. C# , 
. :

using System;
// , Change.
internal interface IChangeBoxedPoint {
void Change(Int32 x, Int32 y);
}
// Point  .
internal struct Point : IChangeBoxedPoint {
private Int32 m_x, m_y;
public Point(Int32 x, Int32 y) {
m_x = x;
m_y = y;
}
public void Change(Int32 x, Int32 y) {
m_x = x; m_y = y;
}
public override String ToString() {
return String.Format("({0}, {1})", m_x, m_y);
}
}
public sealed class Program {
public static void Main() {
Point p = new Point(1, 1);
Console.WriteLine(p);
p.Change(2, 2);
Console.WriteLine(p);
Object o = p;
Console.WriteLine(o);
((Point) o).Change(3, 3);
Console.WriteLine(o);
// p , .
((IChangeBoxedPoint) p).Change(4, 4);
Console.WriteLine(p);

137

// .
((IChangeBoxedPoint) o).Change(5, 5);
Console.WriteLine(o);
}
}
. 
, Change IChangeBoxedPoint 
Point . Main
WriteLine ( ). 
Main .
p Point
IChangeBoxedPoint. p. Change 
, m_x m_y 4,
Change
. WriteLine
(2, 2), .
Point, o, 
IChangeBoxedPoint. , o 
. Change, m_x m_y 
Point. Change 
Point! WriteLine (5, 5).
,
. C# 
.
! ,
,  . 
.

, .
,
, 
. , 

, .
. 
(, ), 
, . , 

; . ,
, . 
. 
,  
, .
Point class, struct , .

138

II


. ,
,
, .
, ,
, .
System.Object Equals, true
. Equals Object:

public class Object {


public virtual Boolean Equals(Object obj) {
// ,
// .
if (this == obj) return true;
// , .
return false;
}
}
, :
, this obj, , ,
true, false. ,
Equals , . , 
, Equals , 
, false. , ,
Equals Object 
, .
, , 
: Equals .
Equals.
1. obj null, false, , ,
this, null Equals.
2. obj this , false.
, , String
FileStream.
3. obj this.
, false.
4. Equals , .
Equals false, false, 
true.
Microsoft Equals Object .

public class Object {


public virtual Boolean Equals(Object obj) {
// null.
if (obj == null) return false;

139

// .
if (this.GetType() != obj.GetType()) return false;
// , true ,
// .
// System.Object ,
// , .
return true;
}
}
, Microsoft Equals , 
Equals , . Equals,
Equals
, Object. 
, , Equals Object,
.
Object ReferenceEquals
:

public class Object {


public static Boolean ReferenceEquals(Object objA, Object objB) {
return (objA == objB);
}
}
ReferenceEquals (
, ).
== C# ( 
Object), 
, 
.
, .NET Framework
. , System.ValueType ( 
) Equals Object
( ). 
.
1. obj null, false.
2. obj this , false.
3. obj
this. , false.
4. true. Equals ValueType
Object.
. 3 Equals ValueType
(. 22). CLR , 
Equals 
,
. , ,
Equals .

140

II

Equals, 
, , :
: x.Equals(x) true;
: x.Equals(y) y.Equals(x)
;
: x.Equals(y) true y.Equals(z) true,
x.Equals(z) true;
: ,
.
Equals 
.
Equals
:
Equals System.IEquatable<T>

Equals. Equals , ,
Object, Equals.
== and !=
Equals.
,
, CompareTo System.
Icomparable CompareTo System.ICom
parable<T>. , Equals ,
CompareTo System.IComparable<T> true, CompareTo
0. CompareTo 
(<, <=, >, >=)
, CompareTo.

-
FCL ,  
. System.Object 
GetHashCode, 
(Int32) .
Equals, 
GetHashCode. 
, Microsoft C# . ,
, , : warning
CS0659: Program overrides Object.Equals(Object o) but does not override Object.Get
HashCode() (Program Object.Equals(Object o), 
Object.GetHashCode()).

public sealed class Program {


public override Boolean Equals(Object obj) { ... }
}

141

, Equals Get
HashCode, , System.Collections.Hashtable System.Collec
tions.Generic.Dictionary , 
. , Equals, GetHash
Code , 
, ,  .
, Hashtable
Dictionary,  .  , 
. Hashtable
( Dictionary) , . 
, 
. , ,
Hashtable/Dictionary , Hashtable/Dictionary
. ,
, , 
 .
GetHashCode .

, .
, Point:

internal sealed class Point {


private Int32 m_x, m_y;
public override Int32 GetHashCode() {
return m_x ^ m_y; // m_x m_y.
}
...
}
 , 
:
, ,
;
GetHashCode
; 
GetHashCode Object ValueType,

;
;
, , ;

;
;
; 
String, ,
.

142

II

GetHashCode System.Object 
. , 
AppDomain; ,
. ,
, 
.
( App
Domain) , GetHashCode
Object. ,
GetHashCode Object; , GetHashCode
Object , 
.
FCL , 
. System.
Runtime.CompilerServices
GetHashCode RuntimeHelpers, 
Object. 
, GetHashCode 
. 
, , Microsoft ,
GetUniqueObjectID.
GetHashCode System.ValueType
( ) 
(XOR).
,
GetHashCode,
.
! 
, GetHashCode,
. 
. ,
 .
, .
Web , .
(String) GetHashCode, 
. Web 
, GetHashCode, 
 . 
. , CLR
GetHashCode String .
Web!

I I I

2 ,
. , 
. , 
, . 7 10 
.


.
( 7) , 
. 
. 
, . .
( 7) .
.
() . 
,
.
( 8) , 
.
( 8) , 
.
( 8) , , 
( )
( ).
.
( 8) ,
.
CLS, 
.
( 8) ,
/ 

145

. CLS 
, .
( 9) ,
( )
,
. . 
.
( 10). ,
/. (
) , 
/.
, .
, ()
 .
, 
.
.
, 
.
, , 
, .

IL .

CLR . 
,
, 
.
CLR 
, , , ,
. ,
Microsoft .NET Framework;
, .
C# 
. ( ),
,
. , 
.

using System;
public sealed class SomeType {

// 1

// .
private class SomeNestedType { }

// 2

// , .
private const Int32 SomeConstant = 1;

// 3

146

III

private readonly Int32 SomeReadOnlyField = 2;


private static Int32 SomeReadWriteField = 3;

// 4
// 5

// .
static SomeType() { }

// 6

// .
public SomeType() { }
public SomeType(Int32 x) { }

// 7
// 8

// .
private String InstanceMethod() { return null; }
public static void Main() {}

// 9
// 10

// .
public Int32 SomeProp {
get { return 0; }
set { }
}

// 11
// 12
// 13

// .
public Int32 this[String s] {
get { return 0; }
set { }
}

// 14
// 15
// 16

// .
public event EventHandler SomeEvent;

// 17

}
ILDasm.exe
(. . 61).

. 61. ILDasm.exe ,

147

, .
(, , 17) 
( ) . 
, , 
,
, .


, , 
(public) (internal).
. ,
. C# .
.

using System;
// ; .
public class ThisIsAPublicType { ... }
// ; .
internal class ThisIsAnInternalType { ... }
// , .
class ThisIsAlsoAnInternalType { ... }


: ,
, , .
, ,
, 
, ;
.
,
(public).
, ;
, ,
. ,
, , 
. ,
(internal),
. CLR C# 
(friend assemblies).
,
, InternalsVisibleTo,
System.Runtime.ComplierServices.
, (

148

III

, 
). ,
, 
. ,
Wintellect Microsoft:

using System;
using System.Runtime.ComplierServices; // InternalsVisibleTo.
//
// ( ).
[assembly:InternalsVisibleTo("Wintellect, PublicKey=12345678...90abcdef")]
[assembly:InternalsVisibleTo("Microsoft, PublicKey=b77a5c56...1934e089")]
internal sealed class SomeInternalType { ... }
internal sealed class AnotherInternalType { ... }

. , Wintellect
1234567890abcdef SomeInternalType 
:

using System;
internal sealed class Foo {
private static Object SomeMethod() {
// Wintellect
// , .
SomeInternalType sit = new SomeInternalType();
return sit;
}
}

, 

. , (
InternalsVisibleTo) C# 
/out:<>. ,
, .
, C#
, ;
, .

.
, C# /t:module ( 
), , 
/moduleassemblyname:<>
C#. ,
,
.

149

! 
, , , . 
, 

. , 
,
, LinkDemand,
StrongNameIdentityPermission.


( ) 
. , 
. CLR ,
.
, Assembly CLR , ,
C# internal.
. 61 ,
(Private) (Public).

. 6-1.
CLR

C#

Private ()

private

Family ()

protected


( )

Family and Assembly


(
)

( 
)


( )

Assembly () internal

Family or Assembly
(
)

protected
internal

,
( )

Public ()

public

, , 
. , , 
, ,
.

. 
, . , 
JIT
IL . , ,
, JIT
FieldAccessException MethodAccessException .

150

III

IL
, 
. , 
, ( );
,
(protected) (private),
.
, C# ( 
) . CLR ,
. C#

, .
C#
, , C# 
, . 
Declared Accessibility C#.
, , CLR 
. C# C#.
, C#
, 
. , ,
.
C#, CLR. CLR ,
. ,
, 
. , 
.
CLR 
, .


, ,
Console, Math, Environment ThreadPool.
. ,
. , Math , 
. C# static.
, ( ),
CLR ,
.
.
System.Object
, 
, .

151

, 
.
(, ,
). .
,
, , 
, .
, .
, ;
.

using System;
public static class AStaticClass {
public static void AStaticMethod() { }
public static String AStaticProperty {
get { return s_AStaticField; }
set { s_AStaticField = value; }
}
private static String s_AStaticField;
public static event EventHandler AStaticEvent;
}
. 62 ILDasm.exe 
(DLL), .
, static C#
(abstract) (sealed). ,
(.ctor).

. 62. , ILDasm.exe,

152

III

,
,
C# , CLR .
,
CLR C#.
partial C#, , 
.
, .
, 
. 
,  
, . partial
,
.
Microsoft Visual Studio
Windows Forms Web Forms,
. .
Visual Studio 
Visual Studio
.
. ,
. , 

. Visual Studio 2005, Windows
Form, Web Form, User Control , Visual Studio
: , , 
. 
.
partial , 
. ,
.exe .dll (
.netmodule). ,
C#;
.

,
 ()
. 7080 

. , 
, 
.
, 

, ,  (, 

153

, ), . . 

. , 

. , 
.
.
(Component Software Programming)
. .
( .NET) .
, , 
.
( 
.NET 
).
(
).
. C# 
XML 
/doc .
. CLR
(Code Access Security).
( )
. (servicing) 
, . 
, 
.
.
,
.
.
, ,
.
.NET : (major)
(minor) , (build) (revision).
, 1.2.3.4 1, 
2, 3 4.
, 
.
, 2.7.0.0.
, , 
, 2.7.1.34.
(2.7.0.0).
, ,
,
/ (, 3.0.0.0).

154

III

. ,
CLR , , 
1.2.3.4 , CLR
1.2.3.4 ( ). 
Microsoft CLR,
. , 
1.2.3.4, , 1.2.5.0, .
, .

CLR (
C#), , 
.
, ,
(),
(). ,
. 
,
.
C# / , 
, 
CLR. . 62 ,
.

. 6-2. C#

C#

//

abstract

 ()



virtual

()

()

override

()

()

sealed


()
. 

,

new

, , , ,
, ,


,
CLR.

155

, CLR
, 
, , , 
.
, (
) (). ,
, (void).
,
. 
, 
. ( 
IL) ,
,
. , C#
. 8.
Employee .

internal class Employee {


// .
public
Int32
GetYearsEmployed() { ... }
// (, , ).
public virtual String GenProgressReport() { ... }
// .
public staticEmployee Lookup(String name) { ... }
}

. , , 
, .
, ,
, , IL
. CLR :
call , 
.
, , .
,
, call ,
null. , , 
. ,
. call 
.
callvirt 
. ,
.
, , .
callvirt CLR 

156

III

, ,
. JIT 
null, CLR 
NullReferenceException.  
callvirt call. null
.
, C#.

using System;
public sealed class Program {
public static void Main() {
Console.WriteLine(); // .
Object o = new Object();
o.GetHashCode();
// .
o.GetType();
// .
}
}
IL .

.method public hidebysig static void Main() cil managed {


.entrypoint
// Code size 26 (0x1a)
.maxstack 1
.locals init (object V_0)
IL_0000: call
void System.Console::WriteLine()
IL_0005: newobj instance void System.Object::.ctor()
IL_000a: stloc.0
IL_000b: ldloc.0
IL_000c: callvirt instance int32 System.Object::GetHashCode()
IL_0011: pop
IL_0012: ldloc.0
IL_0013: callvirt instance class System.Type System.Object::GetType()
IL_0018: pop
IL_0019: ret
} // end of method Program::Main
WriteLine , C#
call. GetHashCode 
callvirt. , GetType
callvirt. , GetType .
, JIT CLR ,
GetType , .
, : C# 
call? C# JIT
, null .
, .
C# NullReferenceException, 
.

157

using System;
public sealed class Program {
public Int32 GetFive() { return 5; }
public static void Main() {
Program p = null;
Int32 x = p.GetFive(); // C# NullReferenceException.
}
}
, . p null,
GetFive CLR
p, Program. GetFive this null,
GetFive , . C#
call callvirt, Null
ReferenceException.
! , 
. , 
call 
callvirt.
,
.
C#, , C#
callvirt. ,
.
callvirt 
call. , 
.

internal class SomeClass {


// ToString Object.
public override String ToString() {
// call
// ToString Object.
// call callvirt,
// .
return base.ToString();
}
}
base.ToString C#
call, ToString . 
, , ToString ,
, .
call , 
, . 
, 
. , ,

158

III

null, NullReferenceException 
. , CLR
,
, .
, 
.

call callvirt, 
this, ,
.

. , 
. , JIT (inline) 
, . ,
, .
, 
. ,
, . ,
,
. :

public class Set {


private Int32 m_length = 0;
// .
public Int32 Find(Object value) {
return Find(value, 0, m_length);
}
// .
public Int32 Find(Object value, Int32 startIndex) {
return Find(value, 0, m_length);
}
//
// .
public virtual Int32 Find(Object value, Int32 startIndex, Int32 endIndex) {
// , ...
}
// .
}



.NET Framework , 
, .
. 

159

( ,
),
. , 
.
, ,
. , 
.
, 
.
, 
. ,
( C#) , , 
sealed.
, , , 
.
.
,
, . 
, 
. , 
, 
, 
.
, 
, CLR 
, , . , 
, JIT
, .
,
.
, JIT
ToString .

using System;
public sealed class Point {
private Int32 m_x, m_y;
public Point(Int32 x, Int32 y) { m_x = x; m_y = y; }
public override String ToString() {
return String.Format("({0}, {1})", m_x, m_y);
}
public static void Main() {
Point p = new Point(3, 4);
// C# callvirt,
// JIT>
// ToString,

160

III

// p Point, .
Console.WriteLine(p.ToString());
}
}

. ,
, 
, . ,

. 
, 
,
.
, 
. ,
.
, 
. ,
CLR
(closed).
,
. ,
.
, . ,
closed 
, 
. , CLR
.
, (, ),
closed.
( , System.
Object). , 
, . .

public class SimulatedClosedClass : Object {


public sealed override Boolean Equals(Object obj) {
return base.Equals(obj);
}
public sealed override Int32 GetHashCode() {
return base.GetHashCode();
}
public sealed override String ToString() {
return base.ToString();
}
// , C# Finalize.
// ...
// .
}

161

, CLR .
, :
, 
. , C# 
. 
, . ,
C#. , 
,
, 
.
. C#
. , , C#
.
. 
(internal) ,
, 
.
, 
. , C# . ,
, , 
, 
, . ,
 , 

.
:
. ,
, 
. ,
. 
. 
, 
(
),
.



, 
. 3 ( 
,
,
).
. , 
.
.

162

III

Phone:

namespace CompanyA {
public class Phone {
public void Dial() {
Console.WriteLine("Phone.Dial");
// .
}
}
}
, , BetterPhone,
Phone :

namespace CompanyB {
public class BetterPhone : CompanyA.Phone {
public void Dial() {
Console.WriteLine("BetterPhone.Dial");
EstablishConnection();
base.Dial();
}
protected virtual void EstablishConnection() {
Console.WriteLine("BetterPhone.EstablishConnection");
// .
}
}
}

C# warning CS0108: The keyword new is required
on BetterPhone.Dial() because it hides inherited member Phone.Dial(). ,
Dial, BetterPhone,
Phone. Dial , 
, .

. , 
: new
Dial BetterPhone.
BetterPhone:

namespace CompanyB {
public class BetterPhone : CompanyA.Phone {
// Dial Phone.
public new void Dial() {
Console.WriteLine("BetterPhone.Dial");
EstablishConnection();
base.Dial();
}

163

protected virtual void EstablishConnection() {


Console.WriteLine("BetterPhone.EstablishConnection");
// .
}
}
}
BetterPhone,
:

public sealed class Program {


public static void Main() {
CompanyB.BetterPhone phone = new CompanyB.BetterPhone();
phone.Dial();
}
}
:

BetterPhone.Dial
BetterPhone.EstablishConnection
Phone.Dial
,
, . Dial
, BetterPhone. 
EstablishConnection, Dial Phone.
, Phone,
. , 
Dial. 
Phone:

namespace CompanyA {
public class Phone {
public void Dial() {
Console.WriteLine("Phone.Dial");
EstablishConnection();
// .
}
protected virtual void EstablishConnection() {
Console.WriteLine("Phone.EstablishConnection");
// .
}
}
}
BetterPhone
( Phone), : warning CS0114:
BetterPhone.EstablishConnection() hides inherited member Phone.EstablishConnec
tion(). To make the current member override that implementation, add the override
keyword. Otherwise, add the new keyword [ CS0114: BetterPhone.
EstablishConnection() Phone.EstablishConnection().

164

III

, override,
new].
, Phone, BetterPhone
EstablishConnection, 
. BetterPhone 
, , , 
Phone.
, EstablishConnection
, , 
Dial EstablishConnection, BetterPhone,
Phone.
, 
Dial new EstablishConnection:

namespace CompanyB {
public class BetterPhone : CompanyA.Phone {
// 'new' , ,
// Dial .
public new void Dial() {
Console.WriteLine("BetterPhone.Dial");
EstablishConnection();
base.Dial();
}
// 'new', ,
// EstablishConnection .
protected new virtual void EstablishConnection() {
Console.WriteLine("BetterPhone.EstablishConnection");
// .
}
}
}
new ,
CLR, BetterPhone Dial Establish
Connection , .
CLR , Phone BetterPhone
.
( Main) :

BetterPhone.Dial
BetterPhone.EstablishConnection
Phone.Dial
Phone.EstablishConnection
, , Main Dial, , 
BetterPhone. Dial EstablishConnection,
BetterPhone. EstablishConnection BetterPhone
, Dial Phone, Establish
Connection . EstablishConnection BetterPhone

165

new, 
EstablishConnection, Phone.
Dial Phone EstablishConnection, 
Phone, .
new BetterPhone
Dial EstablishConnection.
,
,
. 
,
. , 
, 
, Dial EstablishConnection,
, 
.
: ,
Phone, , Dial EstablishConnection
Phone , .
Dial BetterPhone. , 
, EstablishConnection
BetterPhone Phone,
new.
, Establish
Connection BetterPhone. ,
, ,
BetterPhone EstablishConnection virtual override.
BetterPhone:

namespace CompanyB {
public class BetterPhone : CompanyA.Phone {
// Dial ( ).
// new , virtual
// override, ,
// EstablishConnection .
protected override void EstablishConnection() {
Console.WriteLine("BetterPhone.EstablishConnection");
// .
}
}
}
( Main) :

Phone.Dial
BetterPhone.EstablishConnection

166

III

, , Main Dial, ,
Phone BetterPhone. ,
Dial, Phone, Establish
Connection, BetterPhone, 
EstablishConnection, Phone.

, , . 
, .

, .

.
. , 
, . C#
:
Boolean, Char, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double,
Decimal String.
: ,
. , 
, .
.
, 
, , 
IL.
, 
. , .
, 
, , 
, (
MaxInt16 32767). , .
DLL:

using System;
public sealed class SomeLibraryType {
// : C# static,
// , .
public const Int32 MaxEntriesInList = 50;
}

168

III

using System;
public sealed class Program {
public static void Main() {
Console.WriteLine("Max entries supported in list: "
+ SomeLibraryType.MaxEntriesInList);
}
}
, Max
EntriesInList. , , MaxEntriesIn
List 50, 50 Int32
IL (. 71). , 
DLL ,
.

. 71. ILDasm.exe IL


,
,
. MaxEntries
InList 1000 DLL,
. ,
. ,
, ,
( ).
.

(field) ,
. . 71 ,
.
, (CLR) 
(), ().
,

169

AppDomain (. 21), JIT


, .
.

. 7-1.
CLR

C#

Static

static

Instance

(default)

InitOnly

readonly

Volatile

volatile

, ,

, CLR .
volatile: 
, Single, Boolean, Byte, SByte, Int16, UInt16,
Int32, UInt32, Char, ,
: Byte, SByte, Int16,
UInt16, Int32 UInt32

, 
.
, . ,
, 
(
).
CLR (read/write) (readonly) .
. ,
. 
 (
).
, , ,
. , 
.

, .
DLL:

using System;
public sealed class SomeLibraryType {
// static , .
public static readonly Int32 MaxEntriesInList = 50;
}
, ,
, , 
, . Main 
CLR DLL ( 
) MaxEntriesInList , 
. , 50.

170

III

, 50 1000 
. 
1000. 
, (
). : ,

CLR .
, ,
:

public sealed class SomeType {


// .
// .
public static readonly Random s_random = new Random();
// .
private static Int32 s_numberOfWrites = 0;
// .
public readonly String Pathname = "Untitled";
// .
private System.IO.FileStream m_fs;
public SomeType(String pathname) {
// .
// ,
// .
this.Pathname = pathname;
}
public String DoSomething() {
// .
s_numberOfWrites = s_numberOfWrites + 1;
// .
return Pathname;
}
}
(inline). C#
,
. 8, C# ,
,
. , C#
, 
,
. 8.

171

!
, , ,
. :

public sealed class AType {


// InvalidChars .
public static readonly Char[] InvalidChars = new Char[] { 'A', 'B', 'C'};
}
public sealed class AnotherType {
public static void M() {
// ,
// InvalidChars.
AType.InvalidChars[0] = 'X';
AType.InvalidChars[1] = 'Y';
AType.InvalidChars[2] = 'Z';
// ,
// , InvalidChars, .
AType.InvalidChars = new Char[] { 'X', 'Y', 'Z' };
}
}

: ,
,

,
, , . , ,
 ( ),
(
). , ,
, , 
.


( )
, 
. , ,
 .ctor ( constructor). 

( 
SyncBlockIndex),
, .

. , 
, 0 null.
, . 
, , 
. , 
: virtual, new, override, sealed
abstract. , 
( C#) (
),
.

: , ,

173

, :

public class SomeType {


}
:

public class SomeType {


public SomeType() : base() { }
}

protected, public.
,
, .
(sealed abstract)
.
,
. 

 . 
, C#,
, , , . 
System.Object
. 
, System.Object 
.

. , MemberwiseClone Object
, , 
, . , 
.
!  
, . :
,
, ,

.
.
C# ,
:

internal sealed class SomeType {


private Int32 m_x = 5;
}
SomeType m_x 5.
: ? IL 
( .ctor), (. 81).

174

III

. 81. IL  SomeType


, SomeType ,
m_x 5 . , 
C# ,
. 
, . , 
. . :

internal sealed class


private Int32 m_x
private String m_s
private Double m_d
private Byte m_b;
//
public
public
public

SomeType {
= 5;
= "Hi there";
= 3.14159;

.
SomeType()
{ ... }
SomeType(Int32 x) { ... }
SomeType(String s) { ...; m_d = 10; }

}
IL  , 
, m_x, m_s
m_d. , 
. , IL,
String, , m_x, m_s m_d, , 
m_d 10. : m_b 
0, , .
, 
, m_x, m_s m_d:
. 
, 
, , ; 
, 
, .
. 
C# 
this:

internal sealed class SomeType {


// , .
private Int32 m_x;

: , ,

175

private String m_s;


private Double m_d;
private Byte m_b;
// , .
// .
public SomeType() {
m_x = 5;
m_s = "Hi there";
m_d = 3.14159;
m_b = 0xff;
}
// ,
// m_x.
public SomeType(Int32 x) : this() {
m_x = x;
}
// ,
// m_s.
public SomeType(String s) : this() {
m_s = s;
}
// ,
// m_x m_s.
public SomeType(Int32 x, String s) : this() {
m_x = x;
m_s = s;
}
}


( )
(struct) , 
(class). CLR 
, . , , 
. (
C#) , 
. :

internal struct
public Int32
}
internal sealed
public Point
}

Point {
m_x, m_y;
class Rectangle {
m_topLeft, m_bottomRight;

176

III

Rectangle, new, 
. ,
C#. , Rectangle,
Point. 
CLR 
, . , ,
.
CLR
, ,
, , Rectangle:

internal struct Point {


public Int32 m_x, m_y;
public Point(Int32 x, Int32 y) {
m_x = x;
m_y = y;
}
}
internal sealed class Rectangle {
public Point m_topLeft, m_bottomRight;
public Rectangle() {
// C# new, ,
// .
m_topLeft = new Point(1, 2);
m_bottomRight = new Point(100, 200);
}
}
,
. , Rectangle
m_topLeft m_bottomRight Point new, m_x
m_y Point 0.
Point , ,
, . :

internal struct Point {


public Int32 m_x, m_y;
public Point() {
m_x = m_y = 5;
}
}
internal sealed class Rectangle {
public Point m_topLeft, m_bottomRight;
public Rectangle() {
}
}

: , ,

177

: 0 5
m_x m_y, Point (m_topLeft m_bottomRight )?
(: .)
( ++)
, C# Rectangle , 
Point , 
, Rectangle. , 
, C# 
. 
,
. 
, ,
.
, m_x m_y Point
Rectangle 
, Point.
, , . ,
C# . 
.
C# : error
CS0568: Structs cannot contain explicit parameterless constructors ( CS0568:
).
C# 
, ,
. ,
, 
. 
.
, 
0 null,
. , 
, , 0
null! , 
, , .
,
 , .
C# , , 
, , ,

. 
. , 
,
.
C#
, CLR. , 

178

III

, , (,
IL) .
C#
, 
: error CS0573: SomeValType.m_x: cannot have instance field initializers in
structs( CS0573: SomeValType.m_x: 
).

internal struct SomeValType {


// .
private Int32 m_x = 5;
}
, 
 , ,
, .
, 
:

internal struct SomeValType {


private Int32 m_x, m_y;
// C# .
public SomeValType(Int32 x) {
m_x = x;
// : m_y .
}
}
C# 
: error CS0171: Field SomeValType.y must be fully assigned before control leaves
the constructor ( CS0171: SomeValType.y 
). 
, m_y ( 0) .


, CLR (
, 
). (
C# ), . , 

,
. .
. , 
. 
C#:

internal sealed class SomeRefType {


static SomeRefType() {
// SomeRefType.

: , ,

179

}
}
internal struct SomeValType {
// C#
// , .
static SomeValType() {
// SomeValType.
}
}
: , 
, , , 
. , (C# 
). , 
(  ), C# 
: error CS0515: SomeValType.SomeValType(): access mo
difiers are not allowed on static constructors ( CS0515: SomeValType.Some
ValType():
). , 
, , CLR 
.
! ,
, CLR 
. :

internal struct SomeValType {


static SomeValType() {
Console.WriteLine("This never gets displayed");
}
public Int32 m_x;
}
public sealed class Program {
public static void Main() {
SomeValType[] a = new SomeValType[10];
a[0].m_x = 123;
Console.WriteLine(a[0].m_x); // 123.
}
}
.
JIT , .
 , JIT ,
AppDomain. , JIT
IL . , JIT
, ,
. ( . 
.)

180

III

, JIT , , 
. 
, , 
. CLR ,
AppDomain. 
. 
,
, , .
. 
, , 
. , 
. , 
CLR , , 
.
CLR , 
AppDomain, 
, 
Singleton, 
.
,
, . , 
ClassA, , ClassB, 
, ClassA. CLR 
, , 
, ClassA
ClassB.
. , 
CLR, , 
.
, ,
CLR .
System.TypeInitializationException.
,
, .
, C# , 
:

internal sealed class SomeType {


private static Int32 s_x = 5;
}
C# 
, 
. , class struct,
, .

: , ,

181


SomeType. , ,
:

internal sealed class SomeType {


private static Int32 s_x;
static SomeType() { s_x = 5; }
}
ILDasm.exe , 
. IL (. 82).
, , 
.cctor ( ).

. 82. IL  SomeType


IL , .cctor 
. , 
s_x 5.
. 
, 
.
, Java, ,
, 
. , , ,
. CLR 
, 
RunClassConstructor, 
System.Runtime.CompilerServices.RuntimeHelpers.
, , 
, .
RunClassConstructor
CLR , , ,
.
:

internal sealed class SomeType {


private static Int32 s_x = 5;

182

III

static SomeType() {
s_x = 10;
}
}
C#  , 
s_x 5, 10.
, IL C# 
, , ,
 .
! : 
? , ,
AppDomain. AppDomain
, , , ,
. 
,
Finalize, 
. , CLR Finalize. 
: AppDomain
,
DomainUnload System.AppDomain.



, JIT , IL
, CLR 
. ,
, .
JIT , 
.
, , IL. .
JIT ,

. (precise) , CLR
, .
JIT , , 
.
(beforefieldinit), CLR

; 
.
, 
CLR , CLR
. , CLR

: , ,

183


AppDomain , 
JIT NGen.exe.

CLR
, BeforeFieldInit 
, . ,
C# . 

using System;
using System.Diagnostics;
///////////////////////////////////////////////////////////////////////////////
// ,
// C# BeforeFieldInit.
internal sealed class BeforeFieldInit {
public static Int32 s_x = 123;
}
// ,
// C# BeforeFieldInit.
internal sealed class Precise {
public static Int32 s_x;
static Precise() { s_x = 123; }
}
///////////////////////////////////////////////////////////////////////////////
public sealed class Program {
public static void Main() {
const Int32 iterations = 1000 * 1000 * 1000;
PerfTest1(iterations);
PerfTest2(iterations);
}
// JIT-
// BeforeFieldInit Precise ,
// ,
// .
private static void PerfTest1(Int32 iterations) {
Stopwatch sw = Stopwatch.StartNew();
for (Int32 x = 0; x < iterations; x++) {
// JIT- BeforeFieldInit,
// .
BeforeFieldInit.s_x = 1;
}
Console.WriteLine("PerfTest1: {0} BeforeFieldInit", sw.Elapsed);

184

III

sw = Stopwatch.StartNew();
for (Int32 x = 0; x < iterations; x++) {
// JIT- Precise,
// ,
// .
Precise.s_x = 1;
}
Console.WriteLine("PerfTest1: {0} Precise", sw.Elapsed);
}
// JIT- ,
// BeforeFieldInit Precise ,
//
// , - .
private static void PerfTest2(Int32 iterations) {
Stopwatch sw = Stopwatch.StartNew();
for (Int32 x = 0; x < iterations; x++) {
BeforeFieldInit.s_x = 1;
}
Console.WriteLine("PerfTest2: {0} BeforeFieldInit", sw.Elapsed);
sw = Stopwatch.StartNew();
for (Int32 x = 0; x < iterations; x++) {
Precise.s_x = 1;
}
Console.WriteLine("PerfTest2: {0} Precise", sw.Elapsed);
}
}
////////////////////////////// ////////////////////////////////////
:

PerfTest1:
PerfTest1:
PerfTest2:
PerfTest2:

00:00:02.1997770
00:00:07.6188948
00:00:02.0843565
00:00:02.0843732

BeforeFieldInit
Precise
BeforeFieldInit
Precise

, 
( BeforeFieldInit), C# 
BeforeFieldInit.
( Precise) C#
.
: ,
, 
,
.
, 
. PerfTest1 2,2 ,
7,62 ,
. PerfTest2 , JIT

: , ,

185

, , IL
.

BeforeFieldInit , 
, .

.


, 
. , (, System.String) 
(==) (!=). CLR 
, .
, ,
, .
, C# +, 
c , . + 
, C# ,
. C# !=, Visual
Basic <>. , ^ C# (XOR),
Visual Basic .
CLR , 
, 
. ,
.
, , , 

. CLR 
.

, ,
. CLR , 
. C#
( ) , 
,
. ,
C# 
.
, C#:

public sealed class Complex {


public static Complex operator+(Complex c1, Complex c2) { ... }
}
op_Addition
specialname, ,
. ( C#)

186

III

+, . 
, op_Addi
tion specialname, .
, , 
, .
. 81 82 ,
C# ,
, . 
.

. 8-1. C# CLS-

C#

CLS-

op_UnaryPlus

Plus

op_UnaryNegation

Negate

op_LogicalNot

Not

op_OnesComplement

OnesComplement

++

op_Increment

Increment

op_Decrement

Decrement

op_True

IsTrue { get; }

op_False

IsFalse { get; }

. 8-2. C# CLS-

C#

CLS-

op_Addition

Add

op_Subtraction

Subtract

op_Multiply

Multiply

op_Division

Divide

op_Modulus

Mod

&

op_BitwiseAnd

BitwiseAnd

op_BitwiseOr

BitwiseOr

op_ExclusiveOr

Xor

<<

op_LeftShift

LeftShift

>>

op_RightShift

RightShift

==

op_Equality

Equals

!=

op_Inequality

Compare

<

op_LessThan

Compare

>

op_GreaterThan

Compare

<=

op_LessThanOrEqual

Compare

>=

op_GreaterThanOrEqual

Compare

: , ,

187

CLR , 
, C# . ,
. . ECMA (www.ecma
international.org/publications/standards/Ecma335.htm) 
CLI, 10.3.1 ( ) 10.3.2 ( ).
.NET
Framework (FCL) Int32, Int64, UInt32 . . ,
. , CLR 
IL,
. , 
, 
. , 
, 
IL. : ,
,  FCL,
.


, 
.
, ,
, ,
+ ( ),
. , 
, op_ (, op_Addi
tion) .
, + 
, op_Addition.
, C# op_Addition, 
+, . +, C#
op_Addition specialname, ,
op_Addition . op_Addition
, , specialname
C# . , 
op_Addition, + 
.

Microsoft,

, , ,
, . 
, , 
specialname,
, , 

188

III

. , 
, 
,
op_. , Microsoft
, ,
Microsoft .
Microsoft 

. 
. , op_Addition
op_AdditionAssignment 
Add.
. 81 82.
, Complex :

public sealed class Complex {


public static Complex operator+(Complex c1, Complex c2) { ... }
public static Complex Add(Complex c1, Complex c2) { return(c1 + c2); }
}
, , ,
, Add. 
Microsoft, 
, . ,
,
, JIT
. 
JIT 
.

, 

Microsoft, System.Decimal FCL.



. , Byte Int32.
,
, .
, ,
, CLR ( ).
CLR , ,
( ). 
. , FCL
Rational, Int32
Single. , .

: , ,

189

, Rational
,
. ,
ToXxx, ( 
ToString). ,
, Xxx. 
Rational:

public sealed class Rational {


// Rational Int32.
public Rational(Int32 num) { ... }
// Rational Single.
public Rational(Single num) { ... }
// Rational Int32.
public Int32 ToInt32() { ... }
// Rational Single.
public Single ToSingle() { ... }
}
, , ,
Int32 Single Rational .
, 
,
.

. (, C#) 
, 
.
. CLR , 
. , C# ( 
) ,
,
. ,
C# 
. Rational
:

public sealed class Rational {


// Rational Int32.
public Rational(Int32 num) { ... }
// Rational Single.
public Rational(Single num) { ... }
// Rational Int32.
public Int32 ToInt32() { ... }

190

III

// Rational Single.
public Single ToSingle() { ... }
// Rational Int32 .
public static implicit operator Rational(Int32 num) {
return new Rational(num);
}
// Rational Single .
public static implicit operator Rational(Single num) {
return new Rational(num);
}
// Int32, Rational.
public static explicit operator Int32(Rational r) {
return r.ToInt32();
}
// Single, Rational
public static explicit operator Single(Rational r) {
return r.ToSingle();
}
}
, 


. implicit C#, 
, 
. explicit 
, 
.
implicit explicit (
operator) ,
. operator , 
, .
Rational ,
( C#):

public sealed class Program {


public static void Main() {
Rational r1 = 5;
// Int32 Rational.
Rational r2 = 2.5F;
// Single Rational.
Int32 x = (Int32) r1; // Rational Int32.
Single s = (Single) r2; // Rational Single.
}
}

: , ,

191

. 
C# (
) IL, 
, Rational. 
? ,
Rational . , 
. 
, Rational,
:

public
public
public
public

static
static
static
static

Rational
Rational
Int32
Single

op_Implicit(Int32 num)
op_Implicit(Single num)
op_Explicit(Rational r)
op_Explicit(Rational r)

, ,
, op_Implicit op_Explicit.
,
, 
Int32 Rational. 
(, Rational Int32),
. 

OverflowException InvalidOperationException.
op_Explicit 
Rational. 
: Int32 Single . , 
. CLR

, .
. , 
, , C++, C#, Visual Basic Java 
, 
. (, IL) 
, . , IL
,
,
. C# 
, ,
.
C# . 
,
, ,
, , .
,
IL .

192

III

,
. , 
.
, , .

, Sys
tem.Decimal . Decimal 
, Decimal .
ToXxx
Decimal . ,
.


CLR , 
. ( )
( ) . ,
. 
, . 
, ,
, , .
! ( ) 
, , , 
,
.
CLR , . C#
out ref. 
, 
. ,
.
CLR out ref ,
IL. C# 
, ,
, .
out, 
, .
, 
. ref, 
, 
, .
out ref
.
:

public sealed class Program {


public static void Main() {

: , ,

193

Int32 x;
// x.
GetVal(out x);
// x .
Console.WriteLine(x); // 10.
}
private static void GetVal(out Int32 v) {
v = 10; // V.
}
}
x Main,
GetVal. v
Int32. GetVal Int32, v,
10. GetVal , x 10, 
. out ,
.
, out
ref:

public sealed class Program {


public static void Main() {
Int32 x = 5;
// x.
AddVal(ref x);
// x .
Console.WriteLine(x); // "15".
}
private static void AddVal(ref Int32 v) {
v += 10; // v.
}
}
x Main 5.
x AddVal, v
Int32 Main. AddVal 
Int32, v. ,
AddVal v . AddVal
,
. AddVal 10. AddVal
, x Main 15, 
.
, IL CLR out
ref : .
,
. , ref, 
, error CS0165:
Use of unassigned local variable x ( CS0165:
x, .):

public sealed class Program {


public static void Main() {
Int32 x;
// x .

194

III

// :
// error CS0165: Use of unassigned local variable x.
AddVal(ref x);
Console.WriteLine(x);
}
private static void AddVal(ref Int32 v) {
v += 10; // v.
}
}
! , 
C# out ref, 
, out ref, ,
. ,
(
). C# ,
, , 
, , 
.
, CLR  
, out ref. ,
C# :

public sealed class Point {


static void Add(Point p) { ... }
static void Add(ref Point p) { ... }
}
,
(out ref), JIT
,
. Point
:

static void Add(out Point p) { ... }


Add Point, 
C# error CS0663: Add cannot define overloaded
methods that differ only on ref and out ( CS0663: Add
, ref out).
out ref 
, . out ref
. 
,
.
, 
.
out ref ,
. :

: , ,

195

using System;
using System.IO;
public sealed class Program {
public static void Main() {
FileStream fs; // fs.
// .
StartProcessingFiles(out fs);
// , .
for (; fs != null; ContinueProcessingFiles(ref fs)) {
// .
fs.Read(...);
}
}
private static void StartProcessingFiles(out FileStream fs) {
fs = new FileStream(...); // fs .
}
private static void ContinueProcessingFiles(ref FileStream fs) {
fs.Close(); // .
// null, .
if (noMoreFilesToProcess) fs = null;
else fs = new FileStream (...);
}
}
, ,
, out ref,
. ,
ContinueProcessingFiles ,
. , 
ref. :

class App {
static public void Main() {
FileStream fs = null; // ().
// .
ProcessFiles(ref fs);
// , .
for (; fs != null; ProcessFiles(ref fs)) {
// .
fs.Read(...);
}
}

196

III

void ProcessingFiles(ref FileStream fs) {


// , .
if (fs != null) fs.Close(); // .
// null, .
if (noMoreFilesToProcess) fs = null;
else fs = new FileStream (...);
}
}
, ref
, :

using System;
using System.IO;
public sealed class Program {
public static void Main() {
FileStream fs = null; // null ( ).
// .
ProcessFiles(ref fs);
// , .
for (; fs != null; ProcessFiles(ref fs)) {
// .
fs.Read(...);
}
}
private static void ProcessFiles(ref FileStream fs) {
// , .
if (fs != null) fs.Close(); // .
// null, .
if (noMoreFilesToProcess) fs = null;
else fs = new FileStream (...);
}
}
, ref
, :

public static void Swap(ref Object a, ref Object b) {


Object t = b;
b = a;
a = t;
}
, ,
String:

: , ,

197

public static void SomeMethod() {


String s1 = "Jeffrey";
String s2 = "Richter";
Swap(ref s1, ref s2);
Console.WriteLine(s1); // "Richter".
Console.WriteLine(s2); // "Jeffrey".
}
: ,
, . , Swap
Object, String. String, 
:

public static void SomeMethod() {


String s1 = "Jeffrey";
String s2 = "Richter";
// , ,
// .
Object o1 = s1, o2 = s2;
Swap(ref o1, ref o2);
// .
s1 = (String) o1;
s2 = (String) o2;
Console.WriteLine(s1); // "Richter".
Console.WriteLine(s2); // "Jeffrey".
}
SomeMethod
.
. (, 
, ) :

internal sealed class SomeType {


public Int32 m_val;
}
public sealed class Program {
public static void Main() {
SomeType st;
// : error CS1503: Argument '1':
// cannot convert from 'ref SomeType' to 'ref object' ( CS1503:
// "1"
// 'ref SomeType' 'ref object').
GetAnObject(out st);
Console.WriteLine(st.m_val);
}

198

III

private static void GetAnObject(out Object o) {


o = new String('X', 100);
}
}
, Main GetAnObject
SomeType. , GetAnObject Object,
GetAnObject o .
st GetAnObject 
Main String,
SomeType, Console.WriteLine 
. , C# , st 
SomeType, GetAnObject
Object.
, , 
. Swap:

public
T t
b =
a =
}

static void Swap<T>(ref T a, ref T b) {


= b;
a;
t;

Swap ( )
:

public static void SomeMethod() {


String s1 = "Jeffrey";
String s2 = "Richter";
Swap(ref s1, ref s2);
Console.WriteLine(s1); // "Richter".
Console.WriteLine(s2); // "Jeffrey".
}

System.Threading.Interlocked
CompareExchange Exchange.


, 
. , System.String , 
, ,
,
.
, , :

static Int32 Add(params Int32[] values) {


// : ,
// .

: , ,

199

Int32 sum = 0;
for (Int32 x = 0; x < values.Length; x++)
sum += values[x];
return sum;
}
, params, 
.
, ,
Int32, ,
, .
, :

public static void Main() {


// "15".
Console.WriteLine(Add(new Int32[] { 1, 2, 3, 4, 5 } ));
}
,
Add. ,
. , , , 
Add :

public static void Main() {


// "15".
Console.WriteLine(Add(1, 2, 3, 4, 5));
}
, ,
params.
System.ParamArrayAttribute.
, C#
, ParamArray.
, , ,
, ParamArray ,
. , ,
, ,
.
Add, Int32
.
Add, Int32, Add, 
 Int32 ParamArray.
, 
Int32 Add. : ,
Add , 
, Add, 
.
params
(ParamArrayAttribute).
. null 

200

III

, 0 . Add 
, , 0 ( ):

public static void Main() {


// "0".
Console.WriteLine(Add());
}
,
Int32. 
, ? :
, Int32[] 
Object[]. , Type
:

public sealed class Program {


public static void Main() {
DisplayTypes(new Object(), new Random(), "Jeff", 5);
}
private static void DisplayTypes(params Object[] objects) {
foreach (Object o in objects)
Console.WriteLine(o.GetType());
}
}
, :

System.Object
System.Random
System.String
System.Int32
! , 
, . 
, 
,
.
, 
, params.
Concat System.String,
:

public sealed class String : Object, ... {


public static string Concat(object arg0);
public static string Concat(object arg0, object arg1);
public static string Concat(object arg0, object arg1, object arg2);
public static string Concat(params object[] args);
public static string Concat(string str0, string str1);
public static string Concat(string str0, string str1, string str2);
public static string Concat(string str0, string str1, string str2, string str3);

: , ,

201

public static string Concat(params string[] values);


}
, Concat 
, params .
Concat
, , , 
.
params ,
; , 
.



, . ,
, , 
, , IEnumerable<T>,
, List<T>, ,
ICollection<T> IList<T>:

// : .
public void ManipulateItems<T>(IEnumerable<T> collection) { ... }
// : .
public void ManipulateItems<T>(List<T> collection) { ... }
, , , ,
, List<T>, String . . , 
IEnumerable<T>. List<T>,
String. , 
, .
, , , (
), IList<T>.
List<T>. IList<T>
, 
IList<T>.
, , 
. ,
, . , ,
, a stream, :

// : .
public void ProcessBytes(Stream someStream) { ... }
// : .
public void ProcessBytes(FileStream fileStream) { ... }
: FileStream,
NetworkStream, MemoryStream . . FileStream,
.

202

III

,
, ( 
). , , 
FileStream, Stream:

// :
// .
public FileStream OpenFile() { ... }
// :
// .
public Stream OpenFile() { ... }
,
FileStream, Stream.
,
Stream. , 
.

, . ,
OpenFile 
 FileStream ( ,
FileStream). , , List<String>,
, ,
String[]. , 
, 
. , :

// :
// .
public IList<String> GetStringCollection() { ... }
// :
// .
public List<String> GetStringCollection() { ... }
, GetStringCollection 
List<String>, 
IList<String>.
String[], , 
. , 
IEnumerable<String> ICollec
tion<String>.

- -
, C++,
, 
 , . CLR 
, .

: , ,

203

, ,
( C#).
, , C++ 
const ,
.
,

.
C++ , , 
 .
, ,
. , ,
String , .
Microsoft CLR
 . CLR 
,
, . 
, 
. , 
. , ,
. , , 
, , 
.
, CLR 
.

.
, . CLR 
: , , 
. , C# 
, Visual Basic .


,
. ,
. , , :

public sealed class Employee {


public String Name; // .
public Int32 Age; // .
}
, 
:

Employee e = new Employee();


e.Name = "Jeffrey Richter"; // .
e.Age = 41;
// .
Console.WriteLine(e.Name);

// "Jeffrey Richter".


. , 
, . 
. 
,
, , 

. , Employee:

e.Age = 5; // , 5 ?

205

. ,
,  ,
 ,
. , ,
, 
, .
,
, , , , 
,
, . 
, , 
(accessor). ,
, .
:

public sealed class Employee {


private String m_Name; // .
private Int32 m_Age;
// .
public String GetName() {
return(m_Name);
}
public void SetName(String value) {
m_Name = value;
}
public Int32 GetAge() {
return(m_Age);
}
public void SetAge(Int32 value) {
if (value < 0)
throw new ArgumentOutOfRangeException("value",
value.ToString(),
"The value must be greater than or equal to 0");
m_Age = value;
}
}
, 
, 
,
.
, : ,

, , 
.

206

III

e.SetName("Jeffrey Richter");
String EmployeeName = e.GetName();
e.SetAge(41);
e.SetAge(5);
ArgumentOutOfRangeException.
Int32 EmployeeAge = e.GetAge();

//
//
//
//

.
.
.
.

// .

. CLR 
, 
. .
, 
:

public sealed class Employee {


private String m_Name;
private Int32 m_Age;
public String Name {
get { return(m_Name); }
set { m_Name = value; }

// value
// .

}
public Int32 Age {
get { return(m_Age); }
set {
if (value < 0)
// value
// .
throw new ArgumentOutOfRangeException("value",
value.ToString(),
"The value must be greater than or equal to 0");
m_Age = value;
}
}
}
, , ,
, 
:

e.Name = "Jeffrey Richter";


String EmployeeName = e.Name;
e.Age = 41;
e.Age = 5;
ArgumentOutOfRangeException
Int32 EmployeeAge = e.Age;

//
//
//
//

"" .
"" .
"" .

// "" .

,
. CLR , , 
. , (.
6) (. 14).

207

( void). 
( ,
). , : get
set. , set, , ,
get, , .
get set , 
. (backing
field). get set .
, System.Threading.Thread Priority,
, Thread , 
. , , 
, : , 
, , , . .

:
 get ,
get;
 set ,
set;
.
Employee. 
Name Age. 
get set, Employee 
. , :

public sealed class Employee {


private String m_Name;
private Int32 m_Age;
public String get_Name(){
return m_Name;
}
public void set_Name(String value) {
m_Name = value; // value .
}
public Int32 get_Age() {
return m_Age;
}
public void set_Age(Int32 value) {
if (value < 0) { // value .
throw new ArgumentOutOfRangeException("value",
value.ToString(),
"The value must be greater than or equal to 0");
}
m_Age = value;
}
}

208

III

, 
get_ set_ , .
C# . , 
, 
. 
, . 
, .
, , 
, 
. ,
get set. ,

. ,
System.Reflection.PropertyInfo. CLR
, .


, ,
Microsoft .NET Framework .
, , . 
. ,
, ,
, . :
, 
, . ,
get set;
, 
;
out
ref, :

using System;
public sealed class SomeType {
private static String Name {
get { return null; }
set {}
}
static void MethodWithOutParam(out String n) { n = null; }
public static void Main() {
//
// :
// error CS0206: A property or indexer may not
// be passed as an out or ref parameter.
MethodWithOutParam(out Name);
}
}

209

, 
. ,
, 

. ,
(, System.MarshalByRefObject), 
, 
. , , MarshalByRefObject, 
;

, . System.DateTime
Now, .
.
, Microsoft , Now
;
, 
. ,
,
;

, , 
;
,
. , ,
,
.
, ,
. 
, : ,
.
, 
, 
. .NET Framework , 
,
GetXxx SetXxx.
,
,
, !


, , get
. (parameterless
properties). ,
. , 
, (parameterful

210

III

properties), get .
. ,
: C# 
, Visual Basic .
C# .
C# () 
. , ,
C# []. BitArray,
,
, :

using System;
public sealed class BitArray {
// , .
private Byte[] m_byteArray;
private Int32 m_numBits;
// ,
// 0.
public BitArray(Int32 numBits) {
// .
if (numBits <= 0)
throw new ArgumentOutOfRangeException("numBits",
numBits.ToString(),
"numBits must be > 0");
// .
m_numBits = numBits;
// .
m_byteArray = new Byte[(numBits + 7) / 8];
}
// ( ).
public Boolean this[Int32 bitPos] {
//  get .
get {
// .
if ((bitPos < 0) || (bitPos >= m_numBits))
throw new ArgumentOutOfRangeException("bitPos");
// .
return (m_byteArray[bitPos / 8] & (1 << (bitPos % 8))) != 0;
}
//  set .
set {
if ((bitPos < 0) || (bitPos >= m_numBits))

211

throw new ArgumentOutOfRangeException("bitPos",


bitPos.ToString());
if (value) {
// .
m_byteArray[bitPos / 8] = (Byte)
(m_byteArray[bitPos / 8] | (1 << (bitPos % 8)));
} else {
// .
m_byteArray[bitPos / 8] = (Byte)
(m_byteArray[bitPos / 8] & ~(1 << (bitPos % 8)));
}
}
}
}
BitArray :

// BitArray, 14 .
BitArray ba = new BitArray(14);
// , set.
for (Int32 x = 0; x < 14; x++) {
ba[x] = (x % 2 == 0);
}
// , get.
for (Int32 x = 0; x < 14; x++) {
Console.WriteLine("Bit " + x + " is " + (ba[x] ? "On" : "Off"));
}
BitArray Int32 bitPos.
, 
. ( )
.

. , System.Collections.Hashtable ,
.

, .
set , set 
( C# value),
, .
CLR .
, . 
, 
. C# this[...]
, , C#
. C# , 
 ,
CLR .

212

III

CLR ,
:
 set , 
set;
 get , 
get;

;
: CLR .
BitArray, , ,
:

public sealed class BitArray {


//  get .
public Boolean get_Item(Int32 bitPos) { /* ... */ }
//  set .
public void
set_Item(Int32 bitPos, Boolean value) { /* ... */ }
}
, Item
get_ set_. C# 
, C# 
, Item.
get_Item set_Item.
.NET Framework Reference, Item,
, . , System.Collections.
Generic.List  Item, 
List.
C#, Item, 
. , 
, ,
, , (get set).
C# , 
System.Runtime.CompilerServices.IndexerNameAttribute. :

using System;
using System.Runtime.CompilerServices;
public sealed class BitArray {
[IndexerName("Bit")]
public Boolean this[Int32 bitPos] {
// .
}
}
get_Item set_Item get_Bit
set_Bit. C# IndexerName

213

, ;
.1
Visual Basic,
, C#:

'

BitArray.
Dim ba as New BitArray(10)

'
'

Visual Basic (),


[].
Console.WriteLine(ba(2))
' True False.

'

Visual Basic .
Console.WriteLine(ba.Bit(2)) ' , .

C# ,
.
IndexerName 
, . C#
, ,
, , . 
C#
error CS0111: Class SomeType already defines a member called
this with the same parameter types ( CS0111: SomeType 
this ).

using System;
using System.Runtime.CompilerServices;
public sealed class SomeType {
//  get_Item.
public Int32 this[Boolean b] {
get { return 0; }
}
//  get_Jeff.
[IndexerName("Jeff")]
public String this[Boolean b] {
get { return null; }
}
}
, C# 
[], 
, .
, Sys
tem.String, String Chars, Item. 
1

IndexerNameAttribute ECMA 
CLI C#.

214

III

. ,
, [] 
, Chars .


, C# , 
.
, , , 
?
C#?
: 
, 
System.Reflection.DefaultMemberAttribute. , DefaultMember
Attribute , . #
, ,
DefaultMember
Attribute DefaultMemberAttribute. 
, 
, .
, C#, ,
IndexerName, DefaultMember,
, Item.
IndexerName, DefaultMember
, IndexerName. 
: C# , ,
.
, 
,
DefaultMember. ,
C#.
, , 
C# . 
. 
,
. CLR , 

System.Reflection.PropertyInfo.


 get set JIT
, 

. (inline) (,

215

, ) 
. ,
, . 
, 
, , , 
.
: JIT ,
. , 
, .
.



get set. get 
set:

public class SomeType {


public String Name {
get { return null; }
protected set {}
}
}
, Name public, ,
get .
, set protected
SomeType , SomeType.

C# ,
,
. ,
set ( ).

-
, C# CLR 
, 
 . C# . 
,
. , , 
.
, / ,
, , . 
 , ,
.

1 0

, , .
, ( ) 
. , Button
() Click (). ,
Button,
. , 
. , ,
:
,
;

, ;
, .
,
.
, .
CLR (delegate).
(callback method), 
. ,
, . 
, 15.
CLR,
, . ,
. ,
.
, MailManager,
. MailManager 
NewMail. (, Fax Pager)
. MailManager
, ,
.
.

MailManager Fax Pager. . 101 , 
.

10

217

.101. ,
.
MailManager, NewMail. 
Fax Pager NewMail
( ) MailManager, MailManager ,
. 
MailManager ,
NewMail,
.

,

, , 
. .
 MailManager ( http://wintellect.com)
MailManager, Fax Pager. 
, Fax Pager .

1: ,
,

, ,
 .

, ,
. , , 

218

III

, ,
System.EventArgs, EventArgs. 
NewMailEventArgs , 
(m_from), (m_to) (m_subject).

// 1: , ,
// .
internal class NewMailEventArgs : EventArgs {
private readonly String m_from, m_to, m_subject;
public NewMailEventArgs(String from, String to, String subject) {
m_from = from; m_to = to; m_subject = subject;
}
public String From
{ get { return m_from; } }
public String To
{ get { return m_to;
} }
public String Subject { get { return m_subject; } }
}
EventArgs .NET
Framework Class Library (FCL) :

[ComVisible(true)]
[Serializable]
public class EventArgs {
public static readonly EventArgs Empty = new EventArgs();
public EventArgs() { }
}
, .
, .
. , 
Button ,
. , 
, Event
Args, EventArgs.Empty.

2: -
C#  event. 
( , 
), ,
( ), ( ). 
 NewMail:

internal class MailManager {


// 2: 
public event EventHandler<NewMailEventArgs> NewMail;
...
}

10

219

NewMail ,  EventHandler<NewMailEventArgs>,
, 
,  Event
Handler<NewMailEventArgs>. System.EventHandler
:

public delegate void EventHandler<TEventArgs>


(Object sender, TEventArgs e) where TEventArgs: EventArgs;
:

void MethodName(Object sender, NewMailEventArgs e);


, ,
sender Object. , MailManager
, NewMailEventArgs,

:

void MethodName(MailManager sender, NewMailEventArgs e);


, sender
Object, . , MailManager 
SmtpMailManager?
sender
SmtpMailManager, MailManager, ,
SmtpMailManager NewMail. , 
SmtpMailManager ,
sender SmtpMailManager.
, ,
, sender Object.
, sender Object
. , 
, NewMailEventArgs.
, PopMailManager ,
MailManager.
: ,
EventArgs 
e. 
, 
. (, Microsoft Visual
Studio) , e.
, ,
void. , 

. void
. 
, FCL , Resolve
EventHandler, Microsoft
Assembly.

220

III

3: ,


, .
, MailMsgEventArgs, 
. 
, , 
, 
.
MailManager:

internal class MailManager {


...
// 3: ,
// .
// , .
protected virtual void OnNewMail(NewMailEventArgs e) {
//
// .
EventHandler<NewMailEventArgs> temp = NewMail;
// ,
// , .
if (temp != null) temp(this, e);
}
...
}
, OnNewMail
temp, . temp
null 
.
. , temp
NewMail, , , NewMail
null, , ,
NewMail, null. 
CLR NullReferenceException. 
temp 
NullReferenceException.
, MailManager, On
NewMail, 
. ,
. 
OnNewMail ,
. 
.

10

221

4: ,

,
. MailManager Simulate
NewMail MailManager.

internal class MailManager {


// 4: ,
// .
public void SimulateNewMail(String from, String to, String subject) {
// ,
// .
NewMailEventArgs e = new NewMailEventArgs(from, to, subject);
// , .
// ,
// .
OnNewMail(e);
}
}
SimulateNewMail
NewMailEventArgs, .
OnNewMail, MailManager,
MailManager .
, 
. ( , , MailManager,
.)


,
, . MailManager
, :

public event EventHandler<NewMailEventArgs> NewMail;



:

// 1. , null.
private EventHandler<NewMailEventArgs> NewMail = null;
// 2. add_Xxx ( Xxx ).
// .
[MethodImpl(MethodImplOptions.Synchronized)]
public void add_NewMail(EventHandler<NewMailEventArgs> value) {
NewMail = (EventHandler<NewMailEventArgs>)
Delegate.Combine(NewMail, value);
}

222

III

// 3. remove_Xxx ( Xxx ).
//
[MethodImpl(MethodImplOptions.Synchronized)]
public void remove_NewMail(EventHandler<NewMailEventArgs> value) {
NewMail = (EventHandler<NewMailEventArgs>)
Delegate.Remove(NewMail, value);
}
. 
, 
. null, ,
, .
, EventHand
ler<NewMailEventArgs>,
EventHandler<NewMailEventArgs>. 
,
. , 
.
: , NewMail, , 
, .
, .
, ,
, .
C# , 
. 
C# , add_
(NewMail). C#
, Combine System.Delegate.
Combine 
, .
C#
, .
C# ,
remove_ (NewMail). Remove
System.Delegate.
, .
, add remove Method
ImplAttribute ( System.Runtime.CompilerServices).
, ,
: , , 
, 
.
add remove , 

. , add remove, 
, . ,
, , 
,

10

223

.  
; 
add remove 
.
,

. ,
 add remove. ,

. ,
, , System.Reflec
tion.EventInfo. CLR 
.

,
, . , , 
, .
Fax:

internal sealed class Fax {


// MailManager.
public Fax(MailManager mm) {
// EventHandler<NewMailEventArgs>,
// FaxMsg.
// NewMail MailManager.
mm.NewMail += FaxMsg;
}
// MailManager
// Fax .
private void FaxMsg(Object sender, NewMailEventArgs e) {
// 'sender' MailManager,
//  .
// 'e' ,
// MailManager.
// .
//
// .
Console.WriteLine("Faxing mail message:");
Console.WriteLine(" From={0}, To={1}, Subject={2}",
e.From, e.To, e.Subject);
}
// Fax
// NewMail.
public void Unregister(MailManager mm) {

224

III

// NewMail
// MailManager.
mm.NewMail = FaxMsg;
}
}
MailMana
ger . Fax, 
MailManager . Fax
+= C#
NewMail MailManager:

mm.NewMail += FaxMsg;
, C# 
+= , :

mm.add_NewMail(new EventHandler<NewMailEventArgs>(this.FaxMsg));
, C# , EventHandler<New
MailEventArgs> , NewMail Fax. 
C# add_NewMail MailManager, 
. , ,
IL , ILDasm.exe.
, , 
,  add.
, 
. add, ,
.
MailManager, FaxMsg
Fax. MailManager
, sender. ,
, Fax 
MailManager. 
NewMailEventArgs. 
, , NewMailEventArgs, 
.
NewMailEventArgs FaxMsg
,
. Fax , 
.
,
. , Fax 
NewMail, 
. 
, .
Dispose IDisposable,
(
IDisposable . 20).

10

225

, , 
Unregister Fax.
Fax. , += 
=. , 
=, C# remove :

mm.remove_NewMail(new EventHandler<NewMailEventArgs>(FaxMsg));
+=, , 
, ,
 remove, 
 ,
. , 
. , ,
.
, C# , 
+= =.
add remove , C# 
CS0571: cannot explicitly call operator or accessor (CS0571:
).


, C# 
[MethodImpl(MethodImplOptions.Synchronized)] add remove 
. , add remove
. 

. , , 
CLR.
MethodImpl ()
CLR , 
. , ,
, add remove , 
, , 

. ,
. 
, , 
. ,
, , , 
.
,
. , .
[MethodImpl(MethodImplOptions.Synchronized)] 
CLR  , 
. , , 
, add remove 

226

III

,
,
. , .
:
,
, .
, CLR ,
. 
AppDomain, , 
. , C# 

add remove. ,
C#.
C# CLR () 
() , ,
C# . ,

. C# [MethodImpl(MethodImpl
Options.Synchronized)] add remove,
. , 
,
, .
, ( )
,
 ( ). , 
, ,
.


add remove, , .
, , 
C# Microsoft.  C#
Microsoft ,
.
, ,

. , . 
, , 
add remove,
, .
.
, C#, ,
 add remove.
MailManager 
:

10

227

internal class MailManager {


//
// .
private readonly Object m_eventLock = new Object();
// , .
private EventHandler<NewMailEventArgs> m_NewMail;
// .
public event EventHandler<NewMailEventArgs> NewMail {
// add.
add {
//
// ( ) .
lock (m_eventLock) { m_NewMail += value; }
}
// remove.
remove {
//
// ( ) .
lock (m_eventLock) { m_NewMail = value; }
}
}
// ,
// .
// , .
protected virtual void OnNewMail(NewMailEventArgs e) {
// .
EventHandler<NewMailEventArgs> temp = m_NewMail;
// ,
// .
if (temp != null) temp(this, e);
}
// ,
// .
public void SimulateNewMail(String from, String to, String subject) {
// , ,
// , .
NewMailEventArgs e = new NewMailEventArgs(from, to, subject);
// , .
// , ,
// ,

228

III

// .
OnNewMail(e);
}
}
MailManager m_NewMail,
, . 
C# . 
, 
add remove, .
EventHandler<NewMail
EventArgs>. , . 
event , 
. add remove 
. : value
EventHandler<NewMailEventArgs>. 
. , 
 get set, 
 add remove.
, , 
, C#,
[MethodImpl(MethodImplOptions.Synchronized)],
lock C#
m_eventLock Object. ,
. m_eventLock
, , MailManager, 
; MailManager.
, 
. , m_NewMail 
.
m_eventLock . ,
,
. , ,

 , 
. 
5.
, ,
add remove, 
. 
+= =,
, .
OnNewMail.
. , 
(NewMail) , m_NewMail.

10

229


,
 add remove .
, . ,

.
System.Windows.Forms.Control 70 . Control
, add
remove , Control 
70 !
, 
, Control,
. , System.Web.UI.Control 
, , , 
.
add remove ,
, 
. , , 
.
: ( ) 
, , 
. . 

. ,
. , 
.
, .
, ,
, 
. , ,
.
, ,
; , , 
.
, 
TypeWithLotsOfEvents, http://wintellect.com. 
, ,
, 
.

230

III

EventSet,
 
. FCL System.ComponentModel.EventHandlerList,
, EventSet. System.
Windows.Forms.Control System.Web.UI.Control
EventHandlerList .
, , FCL EventHandler
List. EventHandlerList EventSet , Event
HandlerList . ,
EventHandlerList , 
. , 
EventHandlerList.
EventSet .

I V

1 1

, 
Microsoft .NET Framework. System.Char
. Sys
tem.String, . (
, .)
System.Text.StringBuilder. 
,
. System.
Security.SecureString, 
, .

.NET Framework 16 Unicode,


. 
System.Char ( ). System.Char
, : MinValue, 
\0, MaxValue, \uffff.
Char GetUnicodeCategory,
System.Globalization.Unicode
Category, : , 
, , ,
. . ( Unicode).
Char ,
: IsDigit, IsLetter, IsWhiteSpace, IsUpper, IsLower, IsPunctuation, IsLetterOrDigit,
IsControl, IsNumber, IsSeparator, IsSurrogate IsLowSurrogate, IsHighSurrogate IsSymbol.
GetUnicodeCategory true
false. : ,
String String.
, ToLowerInvariant ToUpperInvariant 

. 

11

233

(culture), ( 
, CurrentCulture System.Threa
ding.Thread), ToLower ToUpper.
, CultureInfo.
ToLower ToUpper,
. ,
U+0069 ( i) 
U+0130 ( I ),
U+0049 ( I).
, Char
. Equals true, 
Char 16 Unicode.
CompareTo ( IComparable/IComparable<Char>) 
. ToString
, , Parse TryParse 
String
UTF16.
, GetNumericValue .
:

using System;
public static class Program {
public static void Main() {
Double d;
// '\u0033' " 3".
d = Char.GetNumericValue('\u0033'); // '3' .
Console.WriteLine(d.ToString());
// "3".
// '\u00bc' " ('1/4')".
d = Char.GetNumericValue('\u00bc');
Console.WriteLine(d.ToString());
// "0.25".
// 'A' " A".
d = Char.GetNumericValue('A');
Console.WriteLine(d.ToString());
// "1".
}
}

Char .
, 
IL  . 
Char , Int32, .
, (, C#) ,
: (. 5).
Convert System.Convert 
, Char .
, 

234

IV

Over
flowException.
IConvertible Char
.NET Framework Class Library (FCL)
IConvertible, , ToUInt16 ToChar.
, 
: Char 
. IConvertible System.In
validCastException, (,
Char Boolean) . ( 
Char FCL) IConvertible 
(. 14), , 

IConvertible. IConvertible GetTypeCode
, IFormatProvider. 
, 
.
null, .
:

using System;
public static class Program {
public static void Main() {
Char c;
Int32 n;
// "  " C#.
c = (Char) 65;
Console.WriteLine(c);
// "A".
n = (Int32) c;
Console.WriteLine(n);

// "65".

c = unchecked((Char) (65536 + 65));


Console.WriteLine(c);

// "A".

// "  " Convert.


c = Convert.ToChar(65);
Console.WriteLine(c);
// "A".
n = Convert.ToInt32(c);
Console.WriteLine(n);

// "65".

// Convert.
try {
c = Convert.ToChar(70000);
// 16

11

235

Console.WriteLine(c);
// .
}
catch (OverflowException) {
Console.WriteLine("Cant convert 70000 to a Char.");
}

// "  " IConvertible.


c = ((IConvertible) 65).ToChar(null);
Console.WriteLine(c);
// "A".
n = ((IConvertible) c).ToInt32(null);
Console.WriteLine(n);

// "65".

}
}

System.String
, , System.String, 
.
Object, , 
. String
(IComparable/IComparable<String>, ICloneable, IConvertible,
IEnumerable/IEnumerable<Char> IEquatable<String>).


( C#) String , 
. 
, 
.
C# new String :

using System;
public static class Program {
public static void Main() {
String s = new String("Hi there."); // <
Console.WriteLine(s);
}
}
:

using System;
public static class Program {
public static void Main() {
String s = "Hi there.";
Console.WriteLine(s);
}
}

236

IV

, ILDasm.exe:

.method public hidebysig static void Main() cil managed


{
.entrypoint
// Code size
13 (0xd)
.maxstack 1
.locals init (string V_0)
IL_0000: ldstr
"Hi there."
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call
void [mscorlib]System.Console::WriteLine(string)
IL_000c: ret
} // end of method Program::Main
IL newobj.
. IL ldstr (
), String , 
. , String CLR 
.
, String Char*
SByte*. C# new 
, String Char* SByte*.
String , 
Char .
, , 
.
C# 
. , , 
, , C# , 
C/C++:

// String .
String s = "Hi\r\nthere.";
! 
, ,
. System.Environment 
NewLine, Windows 
, . NewLine
,
. , CLI
UNIX NewLine ,
\n. ,
:

String s = "Hi" + Environment.NewLine + "there.";


+
C#:

11

237

// .
String s = "Hi" + " " + "there.";
,
, 
Hi there.. +
.
+ , 
. System.Text.StringBuilder
( ).
, , C# , 
.
(verbatim strings)
. :

// .
String file = "C:\\Windows\\System32\\Notepad.exe";
// .
String file = @"C:\Windows\System32\Notepad.exe";
. @
,
(\) , 
, .
, , ,
String.


, String, , 
; ,
. 
. , ,
:

if (s.ToUpperInvariant().Substring(10, 21).EndsWith("EXE")) {
...
}
ToUpperInvariant ; s 
. SubString , ToUpperInvariant,
, EndsWith. 
, ToUpperInvariant Sub
String, .
, String 
,
.
, StringBuilder.

238

IV


. , CLR String
, ,
. ,
, 
(string interning), .
String CLR.
, CLR 
.
: String . ,
, String,
, String CLR. ,
CLR String, 
.


, .
, .
, , ( , 
).

,
String:

Boolean Equals(String value, StringComparison comparisonType)


static Boolean Equals(String a, String b,
StringComparison comparisonType)
static Int32 Compare(String strA, String strB,
StringComparison comparisonType)
static Int32 Compare(string strA, string strB,
Boolean ignoreCase, CultureInfo culture)
static Int32 Compare(String strA, Int32 indexA,
String strB, Int32 indexB, Int32 length, StringComparison comparisonType)
static Int32 Compare(String strA, Int32 indexA, String strB,
Int32 indexB, Int32 length, Boolean ignoreCase, CultureInfo culture)
Boolean StartsWith(String value, StringComparison comparisonType)
Boolean StartsWith(String value,
Boolean ignoreCase, CultureInfo culture)
Boolean EndsWith(String value, StringComparison comparisonType)
Boolean EndsWith(String value, Boolean ignoreCase, CultureInfo culture)
,
, , 
 , 
.

11

239

comparisonType ( )
, StringComparison,
:

public enum StringComparison {


CurrentCulture = 0,
CurrentCultureIgnoreCase = 1,
InvariantCulture = 2,
InvariantCultureIgnoreCase = 3,
Ordinal = 4,
OrdinalIgnoreCase = 5
}
, 
, URL, 
, , , XML, XML . . 
StringComparison. Ordinal
StringComparison.OrdinalIgnoreCase. ,
.
,
(
), StringComparison.CurrentCulture String
Comparison.CurrentCultureIgnoreCase.
! StringComparison.
InvariantCulture StringComparison.InvariantCultureIgnoreCase.

,
, StringComparison.Ordinal StringCompari
son.OrdinalIgnoreCase. , 
, 
.

! 
,
String ToUpperInvariant ToLowerInvariant.
ToUpperInvariant,
ToLowerInvariant  , Microsoft
. , FCL 

.

, .
StartsWith,
EndsWith Compare Boolean CultureInfo.

240

IV

! String
Equals, StartsWith, EndsWith Compare , 
. Microsoft ( 
). , String 
CompareTo ( IComparable), Com
pareOrdinal == != .
, ,
, , 
. ,
CompareTo ,
Equals . ,
, .
. 
( RFC 1766) .NET Frame
work System.Globalization.CultureInfo. , enUS 
() , enAU
, deDE . CLR
,
CultureInfo.
CurrentUICulture , 
. Windows Forms Web
Forms, , 
, .
CultureInfo,
.
Win32 GetUserDefaultUILanguage 
CultureInfo, Windows.
MUI (Multilingual User Interface) Windows 
Regional and Language Options (
) .
CurrentCulture , Current
UICulture, , 
. CultureInfo
. 
Win32 GetUserDefaultLCID
CultureInfo. Regional Options (
) Regional and Language Options (
) .
CurrentUICulture CurrentCulture
CultureInfo,
. . , ,
, ,

. CurrentUICulture 
CultureInfo, enUS.

11

241

CultureInfo System.Globali
zation.CompareInfo,
Unicode. 
.NET Framework, .NET
Framework ( ) .

:

using System;
using System.Globalization;
public static class Program {
public static void Main() {
String s1 = "Strasse";
String s2 = "Strae";
Boolean eq;
// CompareOrdinal .
eq = String.Compare(s1, s2, StringComparison.Ordinal) == 0;
Console.WriteLine("Ordinal comparison: '{0}' {2} '{1}'", s1, s2,
eq ? "==" : "!=");
// (de) (DE).
CultureInfo ci = new CultureInfo("deDE");
// Compare .
eq = String.Compare(s1, s2, true, ci) == 0;
Console.WriteLine("Cultural comparison: '{0}' {2} '{1}'", s1, s2,
eq ? "==" : "!=");
}
}
:

Ordinal comparison: 'Strasse' != 'Strae'


Cultural comparison: 'Strasse' == 'Strae'
Compare , 
(character expansions),
, 
. 
ss. AE.
Compare 
0, .

.
. 
CultureInfo CompareInfo. ,
CultureInfo 

242

IV

,
CompareInfo.
Compare String 
. 
, CurrentCulture . ,
Compare, CompareInfo 
Compare CompareInfo,
(, 
). , , 
Compare CompareInfo.
Compare CompareInfo
CompareOptions, IgnoreCase,
IgnoreKanaType, IgnoreNonSpace, IgnoreSymbols, IgnoreWidth, None, Ordinal StringSort.
, 
.
. .NET Framework.

:

using
using
using
using
using

System;
System.Text;
System.Windows.Forms;
System.Globalization;
System.Threading;

public sealed class Program {


public static void Main() {
String output = String.Empty;
String[] symbol = new String[] { "<", "=", ">" };
Int32 x;
CultureInfo ci;
// ,
// .
String s1 = "cot";
String s2 = "c te";
// .
ci = new CultureInfo("frFR");
x = Math.Sign(ci.CompareInfo.Compare(s1, s2));
output += String.Format("{0} Compare: {1} {3} {2}",
ci.Name, s1, s2, symbol[x + 1]);
output += Environment.NewLine;
// .
ci = new CultureInfo("jaJP");
x = Math.Sign(ci.CompareInfo.Compare(s1, s2));
output += String.Format("{0} Compare: {1} {3} {2}",

11

243

ci.Name, s1, s2, symbol[x + 1]);


output += Environment.NewLine;
// .
ci = Thread.CurrentThread.CurrentCulture;
x = Math.Sign(ci.CompareInfo.Compare(s1, s2));
output += String.Format("{0} Compare: {1} {3} {2}",
ci.Name, s1, s2, symbol[x + 1]);
output += Environment.NewLine + Environment.NewLine;
//
//
//
//


CompareInfo.Compare .
"shinkansen" (
) : .

s1 = "
s2 = "

"; // ("\u3057\u3093\u304b\u3093\u305b\u3093")
"; // ("\u30b7\u30f3\u30ab\u30f3\u30bb\u30f3")

// .
ci = new CultureInfo("jaJP");
x = Math.Sign(String.Compare(s1, s2, true, ci));
output += String.Format("Simple {0} Compare: {1} {3} {2}",
ci.Name, s1, s2, symbol[x + 1]);
output += Environment.NewLine;
// , .
CompareInfo compareInfo = CompareInfo.GetCompareInfo("jaJP");
x = Math.Sign(compareInfo.Compare(s1, s2, CompareOptions.IgnoreKanaType));
output += String.Format("Advanced {0} Compare: {1} {3} {2}",
ci.Name, s1, s2, symbol[x + 1]);
MessageBox.Show(output, "Comparing Strings For Sorting");
}
}
,
. 111.

. 111.

244

IV



, Windows 
( 230 ). 
Regional And Language Options (
), Languages (),
Install Files For East Asian Languages (
) OK (. 112)
 (Input Method
Editor, IME).

. 112. 
Regional And Language Options (
)
, ANSI;
UTF8,
Microsoft Visual Studio, Microsoft C#.
Compare, CompareInfo IndexOf, IsLastIndexOf,
IsPrefix IsSuffix. 
,
CompareOptions,
Compare, IndexOf, LastIndexOf, StartsWith EndsWith String.
, FCL System.StringComparer,
. ,
.


, .
. 
(ordinal comparison) CLR , 

11

245

. ,
, , 
. CLR
, .
,
, .
, , 
.


, 
CLR (string interning).
CLR , 
, .
( ). String , 
:

public static String Intern(String str);


public static String IsInterned(String str);
, Intern, String . ,
String.
, ,
. String,
, . :
,
, String. String,
, , 
.
Intern, IsInterned String 
. , IsInterned 
. null, 
.
CLR 
, . Microsoft ,

, .
System.Runtime.CompilerServices.CompilationRelaxationsAttribute,
System.Runtime.CompilerServices.CompilationRelaxa
tions.NoStringInterning, ECMA CLR
, . : 
C# 
/.
/, CLR 
, . , 
,
, Intern String.
:

246

IV

String s1 = "Hello";
String s2 = "Hello";
Console.WriteLine(Object.ReferenceEquals(s1, s2));

// 'False'.

s1 = String.Intern(s1);
s2 = String.Intern(s2);
Console.WriteLine(Object.ReferenceEquals(s1, s2));

// 'True'.

ReferenceEquals s1 
Hello , s2  Hello.
, 'False'. , CLR
2.0, True. , CLR 
/, C#, CLR 
Hello AppDomain. ,
s1 s2 . , ,
,
/ , Hello
. , CLR 2.0 /
, NGen.exe.
ReferenceEquals Hello 
, s1 Hello. 
Intern s2 Hello, 
s1. ReferenceEquals
True ,
/.
,
.
NumTimesWordAppearsEquals : 
word , 
. , ,
:

private static Int32 NumTimesWordAppearsEquals(String word, String[] wordlist) {


Int32 count = 0;
for (Int32 wordnum = 0; wordnum < wordlist.Length; wordnum++) {
if (word.Equals(wordlist[wordnum], StringComparison.Ordinal))
count++;
}
return count;
}
, Equals String,
, .
. , wordlist
, String, 
. ,
.
, 
:

11

247

private static Int32 NumTimesWordAppearsIntern(String word, String[] wordlist) {


// , wordlist
// .
word = String.Intern(word);
Int32 count = 0;
for (Int32 wordnum = 0; wordnum < wordlist.Length; wordnum++) {
if (Object.ReferenceEquals(word, wordlist[wordnum]))
count++;
}
return count;
}
, wordlist
. , ,
, wordlist 
String . ,
, , ,
.
NumTimesWordAppearsIntern , NumTimesWord
AppearsEquals, ,
NumTimesWordAppearsIntern  ,
wordlist (
). NumTimesWordAppearsIntern
, 
, wordlist. 
, ,
. ,
C# , .



.
,
.
, (
C#)
.
.
. C/C++ 
. Microsoft C/C++
(string pooling). , .
, .


,
 .
String,

248

IV

Length, Chars ( C#), GetEnumerator, ToCharArray, Con


tains, IndexOf, LastIndexOf, IndexOfAny LastIndexOfAny.
System.Char 16
Unicode, Unicode
. , Unicode
. , U+0625 (
) U+0650 ( ) 
, .
, Unicode 
, 16 .
(high surrogate), (low surrogate). 
U+D800 U+DBFF, U+DC00
U+DFFF. Unicode 
.

. Unicode
System.Globalization.StringInfo. 
, 
. , , 
LengthInTextElements StringInfo.
SubstringByTextElements StringInfo,
.
, StringInfo GetTextElementEnumerator,
System.Globalization.TextElementEnumerator, ,
, Unicode. 
, ParseCombiningCharacters
StringInfo, Int32,
. 
.
StringInfo
:

using
using
using
using

System;
System.Text;
System.Globalization;
System.Windows.Forms;

public sealed class Program {


public static void Main() {
// .
String s = "a\u0304\u0308bc\u0327";
SubstringByTextElements(s);
EnumTextElements(s);
EnumTextElementIndexes(s);
}
private static void SubstringByTextElements(String s) {
String output = String.Empty;

11

249

StringInfo si = new StringInfo(s);


for (Int32 element = 0; element < si.LengthInTextElements; element++) {
output += String.Format(
"Text element {0} is '{1}'{2}",
element, si.SubstringByTextElements(element, 1),
Environment.NewLine);
}
MessageBox.Show(output, "Result of SubstringByTextElements");
}
private static void EnumTextElements(String s) {
String output = String.Empty;
TextElementEnumerator charEnum =
StringInfo.GetTextElementEnumerator(s);
while (charEnum.MoveNext()) {
output += String.Format(
"Character at index {0} is '{1}'{2}",
charEnum.ElementIndex, charEnum.GetTextElement(),
Environment.NewLine);
}
MessageBox.Show(output, "Result of GetTextElementEnumerator");
}
private static void EnumTextElementIndexes(String s) {
String output = String.Empty;
Int32[] textElemIndex = StringInfo.ParseCombiningCharacters(s);
for (Int32 i = 0; i < textElemIndex.Length; i++) {
output += String.Format(
"Character {0} starts at index {1}{2}",
i, textElemIndex[i], Environment.NewLine);
}
MessageBox.Show(output, "Result of ParseCombiningCharacters");
}
}

(. 113, 114 115).

. 113. SubstringByTextElements

250

IV

. 114. GetTextElementEnumerator

. 115. ParseCombiningCharacters
,
. 113 114, : (Win
dows Display Properties) (Appearance)
(Advanced) Lucida Sans Unicode
,
.
.


String 
(. 111).

. 11-1.

Clone

(this).
, String .
Icloneable String

Copy

.
,
.

. , ,
(),

CopyTo

SubString

ToString

(this)

11

251

, String
, Insert, Remove, PadLeft, Replace, Split, Join, ToLower,
ToUpper, Trim, Concat, Format . : 
; , ( 
).


String ,
String FCL Sys
tem.Text.StringBuilder. 
String. ,
String, StringBuilder, ,
, .
StringBuilder Char.
StringBuilder, 
, . , 
, StringBuilder 
, ,
. 
.
StringBuilder,
StringBuilder String, ToString StringBuilder.
,
StringBuilder. , 
.
String, ToString, . 
, , , 
StringBuilder, , , 
ToString, , 
, ToString.

StringBuilder
String StringBuilder CLR
. , ( C#) StringBuilder
. StringBuilder ,
:

StringBuilder sb = new StringBuilder();


StringBuilder .
,
StringBuilder.
(Maximum capacity) Int32, 
, .
Int32.MaxValue ( 2 ). ,
, .
StringBuilder .

252

IV

(Capacity) Int32, 
StringBuilder. 16. , 
StringBuilder,
StringBuilder.
StringBuilder , 
. , StringBuilder
, , 
, . 
. 
, , 
.
(Character array) Char,
. ( ) 
.
Length StringBuilder. Length 
StringBuilder. StringBuilder
, String . , 
Length 0.

StringBuilder
StringBuilder String . ,
StringBuilder , 
, . StringBuilder 
:
,
;
, ToString
StringBuilder.
StringBuilder 
. 
StringBuilder, . 
, ,
StringBuilder, .
. 112 StringBuilder.

. 11-2. StringBuilder

MaxCapacity

Capacity

/ 
. 
, , ,
MaxCapacity,
ArgumentOutOfRangeException

11

253

. 11-2. ()

EnsureCapacity

,
, ,
.
String
Builder, .
, , 
,

Length

.

.
0
StringBuilder

ToString


String, 
StringBuilder.
String ,
. 
StringBuilder
(
). ToString 
startIndex length
String, 
StringBuilder

Chars

.
C#  (
), 
, ( 
[])

Append Insert

/
, 
.

,

AppendFormat


, .


. 

StringBuilder

Replace

Remove

Equals

true, String
Builder 
,

CopyTo

StringBuilder
Char

254

IV

: StringBuilder 
StringBuilder. 
:

StringBuilder sb = new StringBuilder();


String s = sb.AppendFormat("{0} {1}", "Jeffrey", "Richter").
Replace(' ', '').Remove(4, 3).ToString();
Console.WriteLine(s); // "JeffRichter"
StringBuilder String. 
, String ToLower, ToUpper, EndsWiths, PadLeft, Trim . .,
StringBuilder. StringBuilder 
Replace,
( ). 
String StringBuilder. , 
, ,
:

// StringBuilder .
StringBuilder sb = new StringBuilder();
// , StringBuilder.
sb.AppendFormat("{0} {1}" "Jeffrey", "Richter").Replace(" ", "");
// StringBuilder String,
// .
String s = sb.ToString().ToUpper();
// StringBuilder ( Char).
sb.Length = 0;
// String StringBuilder
// .
sb.Append(s).Insert(8, "Marc");
// StringBuilder String.
s = sb.ToString();
// String .
Console.WriteLine(s); // "JEFFREYMarcRICHTER"
, StringBuilder 
, String. , Microsoft
StringBuilder,
.


, ,
, ( Byte, Int32, Single . .)
DateTime. .NET Framework 

11

255

, , 
.
, FCL , 
. .

ToString.
System.Object, . ToString
, ,
.
, , 
, , 
.
ToString System.Object
. ,
. ,
, FileStream Hashtable?
, 
, ToString. ,
FCL (Byte, Int32, UInt64, Double . .), ToString,
.


ToString . ,
. , , , 
,
. ,
, .

. 
,
.
ToString,
.

, System.IFormattable:

public interface IFormattable {


String ToString(String format, IFormatProvider formatProvider);
}
FCL (Byte, SByte, Int16/UInt16, Int32/UInt32, Int64/UInt64,
Single, Double, Decimal DateTime) . ,
, GUID. ,
IFormattable,
, 
.
ToString IFormattable . , format,
, . , formatProvi

256

IV

der, , System.IFormatProvider.
ToString .
.
, ToString IFormattable, 
. 
, System.FormatException.
FCL . , Date
Time : d , D 
, g , M /, s
, T , u
ISO 8601, U , Y
/ . . : G
, F , D X 
. . 12.
, : C ,
D , E (), F
, G , N , P ,
R (roundtrip) X 
. ,
.
, ToString 
, ,
. .
. .NET Framework SDK, .
null, 
ToString G. ,
, . ,
, , , 
; . , ToString
.
, .
,
. ToString 
ToString IFormattable null formatProvider.
( 
, , ), .
ToString , GUID, , 
GUID.
, .
ToString format
Provider. null, ToString ,
, System.Threading.Thread.CurrentThread.Cur
rentCulture. System.Globalization.CultureInfo.
, ToString NumberFormat 
DateTimeFormat .
System.Globalization.NumberFormatInfo System.Globaliza
tion.DateTimeFormatInfo . NumberFormatInfo

11

257

, CurrencyDecimalSeparator, CurrencySymbol, NegativeSign, Num


berGroupSeparator PercentSymbol. DateTimeFormatInfo 
, Calendar, DateSeparator, DayNames, LongDatePattern, Short
TimePattern TimeSeparator. ToString 
.
ToString IFormattable null 
, IFormatProvider:

public interface IFormatProvider {


Object GetFormat(Type formatType);
}
IFormatProvider :
, , 
, , 
, .
System.Globalization.CultureInfo FCL
, IFormatProvider.
, , , CultureInfo
ToString formatProvider. 
Decimal :

Decimal price = 123.54M;


String s = price.ToString("C", new CultureInfo("viVN"));
MessageBox.Show(s);
, (. 116).

. 116. ,

ToString Decimal, , formatProvider 
null, GetFormat :

NumberFormatInfo nfi = (NumberFormatInfo)


formatProvider.GetFormat(typeof(NumberFormatInfo));
ToString (CultureInfo) 
. ( Decimal) 
. ( DateTime) 
GetFormat :

DateTimeFormatInfo dtfi = (DateTimeFormatInfo)


formatProvider.GetFormat(typeof(DateTimeFormatInfo));
, GetFormat ,
, ,
. .NET Framework GetFormat 

258

IV

( );
.
, ,
,
InvariantCulture System.Globalization.CultureInfo 
formatProvider ToString:

Decimal price = 123.54M;


String s = price.ToString("C", CultureInfo.InvariantCulture);
MessageBox.Show(s);

(. 117). : . 
(U+00A4).

. 117. ,


. ,
.
FCL IFormatProvider : 
CultureInfo, NumberFormatInfo DateTimeFormatInfo.
GetFormat NumberFormatInfo, ,
NumberFormatInfo. , this, null. 
GetFormat DateTimeFormatInfo this, 
DateTimeFormatInfo, null . 
.

, ,
. ToString, 
null formatProvider. 
ToString
ToString. , Decimal ToString:

// ToString(null, null).
// : , .
public override String ToString();
// ToString.
// ToString IFormattable.
// : , .
public String ToString(String format, IFormatProvider formatProvider);
// ToString(format, null).
// : , , .
public String ToString(String format);

11

259

// ToString(null, formatProvider).
// ToString IConvertible.
// : , .
public String ToString(IFormatProvider formatProvider);


. 
.
, :

String s = String.Format("On {0}, {1} is {2} years old.",


new DateTime(2006, 4, 22, 14, 35, 5), "Aidan", 3);
Console.WriteLine(s);

enUS, :

On 4/22/2006 2:35:05 PM, Aidan is 3 years old.


Format String , 

. Format
{0} (
), {1} (Aidan) {2} ,
(3).
Format ToString, 
. 
, . ,
,
.
,
. , 
0 2:

String s = String.Format("On {0:D}, {1} is {2:E} years old.",


new DateTime(2006, 4, 22, 14, 35, 5), "Aidan", 3);
Console.WriteLine(s);
en
US, :

On Saturday, April 22, 2006, Aidan is 3.000000E+000 years old.


, Format , 
0 IFormattable
ToString, D null. Format
ToString IFormattable 2,
E null. IFormattable, Format 
ToString ,
.

260

IV

String
Format. , IFormatProvider,

, . 
, Format ToString , 
IFormatProvider.
String StringBuilder,
AppendFormat StringBuilder. ,
Format String, , 
StringBuilder. AppendFormat
, IFormatProvider.
System.Console Write WriteLine,
. Console 
Write WriteLine, IFormatProvider.

, Format String, IFormat
Provider, Write WriteLine
Console. , , ,

, , .


, .NET Framework 
. . ,
AppendFormat StringBuilder , 
. ,
ToString AppendFormat , 
, .
Format String.
. ,
HTML,
, Int32 .
, Int32 String,
: <B> </B>. :

using System;
using System.Text;
using System.Threading;
public static class Program {
public static void Main() {
StringBuilder sb = new StringBuilder();
sb.AppendFormat(new BoldInt32s(), "{0} {1} {2:M}", "Jeff", 123, DateTime.Now);
Console.WriteLine(sb);
}
}

11

261

internal sealed class BoldInt32s : IFormatProvider, ICustomFormatter {


public Object GetFormat(Type formatType) {
if (formatType == typeof(ICustomFormatter)) return this;
return Thread.CurrentThread.CurrentCulture.GetFormat(formatType);
}
public String Format(String format, Object arg, IFormatProvider formatProvider) {
String s;
IFormattable formattable = arg as IFormattable;
if (formattable == null) s = arg.ToString();
else s = formattable.ToString(format, formatProvider);
if (arg.GetType() == typeof(Int32))
return "<B>" + s + "</B>";
return s;
}
}
en
US ( ):

Jeff <B>123</B> January 23


Main StringBuilder, 
. AppendFormat 
BoldInt32s. , 
IFormatProvider, ICustom
Formatter:

public interface ICustomFormatter {


String Format(String format, Object arg,
IFormatProvider formatProvider);
}
Format , Append
Format StringBuilder . 

. AppendFormat, ,
. AppendFormat:

public StringBuilder AppendFormat(IFormatProvider formatProvider,


String format, params Object[] args) {
// IFormatProvider , ,
// ICustomFormatter.
ICustomFormatter cf = null;
if (formatProvider != null)
cf = (ICustomFormatter)
formatProvider.GetFormat(typeof(ICustomFormatter));

262

IV

// ( )
// StringBuilder.
Boolean MoreReplaceableArgumentsToAppend = true;
while (MoreReplaceableArgumentsToAppend) {
// argFormat ,
// format.
String argFormat = /* ... */;
// argObj
//  args.
Object argObj = /* ... */;
// argStr ,
// .
String argStr = null;
// ,
// .
if (cf != null)
argStr = cf.Format(argFormat, argObj, formatProvider);
//
// , .
if (argStr == null) {
// ,
// .
IFormattable formattable = argObj as IFormattable;
if (formattable != null) {
// ;
// .
argStr = formattable.ToString(argFormat, formatProvider);
} else {
// ;
// .
if (argObj != null) argStr = argObj.ToString();
else argStr = String.Empty;
}
}
// argStr (  ).
/* ... */
// , , .
MoreReplaceableArgumentsToAppend = /* ... */;
}
return this;
}
Main AppendFormat, GetFormat
, ICustomFormatter. GetFormat, 
BoldInt32s, , ICustomFormatter, 
, .

11

263

GetFormat  , GetFormat
CultureInfo, .
AppendFormat 
Format ICustomFormatter. Format,
BoldInt32s. Format , 

IFormattable. , ToString
( Object);
ToString, .
, , ,
Int32, , , HTML <B> </B> 
. Int32, 
.



. : ,
.
, .
Microsoft ,
.
, , ,
Parse. String, ;
 Parse . FCL Parse
, DateTime, TimeSpan
( SQL).
, .
(Byte, SByte, Int16/UInt16, Int32/UInt32, Int64/UInt64, Single, Double Decimal) 
Parse. Parse, 
Int32. ( Parse .)

public static Int32 Parse(String s, NumberStyles style,


IFormatProvider provider);
, . s
String , 
Int32. style System.Globali
zation.NumberStyles ,
Parse . provider IFormatProvider
, , Parse 
, .
Parse System.FormatException,
:

Int32 x = Int32.Parse(" 123", NumberStyles.None, null);


, Parse style:

Int32 x = Int32.Parse(" 123", NumberStyles.AllowLeadingWhite, null);

264

IV

,
NumberStyles, . .NET Framework SDK.
:

Int32 x = Int32.Parse("1A", NumberStyles.HexNumber, null);


Console.WriteLine(x); // "26".
Parse .
Parse . ,
Int32 Parse:

// NumberStyles.Integer
// .
public static Int32 Parse(String s);
// .
public static Int32 Parse(String s, NumberStyles style);
// NumberStyles.Integer .
public static Int32 Parse(String s, IFormatProvider provider)
// , .
public static int Parse(String s, NumberStyles style,
IFormatProvider provider);
DateTime Parse:

public static DateTime Parse(String s,


IFormatProvider provider, DateTimeStyles styles);
Parse 
, Parse DateTime ,
System.Globalization.DateTimeStyles,
NumberStyles. , 
DateTimeStyles, . .NET Framework SDK.
DateTime Parse:

// ,
// DateTimeStyles.None .
public static DateTime Parse(String s);
// DateTimeStyles.None .
public static DateTime Parse(String s, IFormatProvider provider);
// .
public static DateTime Parse(String s,
IFormatProvider provider, DateTimeStyles styles);
.
, Parse DateTime ,
. DateTime ParseExact,
, , 
, , .

11

265

. , DateTimeFormatInfo, 
.NET Framework SDK.
Microsoft 
: Parse 
( , ), 
. , 
, Parse
Microsoft TryParse ,
DateTime, TimeSpan IPAddress.
TryParse Int32:

public static Boolean TryParse(String s, NumberStyles style,


IFormatProvider provider, out Int32 result);
, true false, ,
Int32. true, ,
,
. TryXxx
19.

:

Win32 ,
Unicode MultiByte Character Set (MBCS). 
, , 
. CLR 16 Unicode,
16 Unicode.
.

. , 
16 ,
. (encode) 16
,
(decode) 16 .

, , Unicode. , 
, Windows 95, 
Unicode, ShiftJIS ( 932).
ShiftJIS CLR ,
Windows.
,
System.IO.BinaryWriter System.IO.StreamWriter.

System.IO.BinaryReader System.IO.StreamReader.
UTF8. (UTF

266

IV

Unicode Transformation Format.) ,


.
, FCL , 
. UTF16 UTF8.
UTF16 16 2 .
, 
. UTF16 Unicode (Unicode encoding).
, , UTF16,
(big endian) (little endian) .
UTF8 , ,
, . 0x0080,
, 1 .
0x0080 0x07FF, 
, 2 . , 0x0800
, , 3 
. , ,  (surrogate character pairs) 
4 . UTF8 ,
UTF16,
0x0800 .
UTF16 UTF8, FCL 
.
UTF32 4 . 
, 
, . , UTF
32 , 
4 . , UTF32 
,
. .
, UTF32
.
UTF7 , 7
. ,
, . Unicode Consortium 
UTF7.
ASCII 16 ASCII; 16
0x0080 .
0x007F ,
. , ASCII
( 0x00 0x7F),
( ). 
ASCII, .
, FCL 16
. ASCII,
, . 
UTF16 UTF8 , 
,  .

11

267

,
, System.Text.Encoding.
Encoding , 
, Encoding.

UTF8:

using System;
using System.Text;
public static class Program {
public static void Main() {
// .
String s = "Hi there.";
// , Encoding, ""
// UTF8.
Encoding encodingUTF8 = Encoding.UTF8;
// .
Byte[] encodedBytes = encodingUTF8.GetBytes(s);
// .
Console.WriteLine("Encoded bytes: " +
BitConverter.ToString(encodedBytes));
// .
String decodedString = encodingUTF8.GetString(encodedBytes);
// .
Console.WriteLine("Decoded string: " + decodedString);
}
}
:

Encoded bytes: 48692074686572652E


Decoded string: Hi there.
UTF8, Encoding : Unicode,
BigEndianUnicode, UTF32, UTF7, ASCII Default. , 

, Regional and
Language Options ( ). (. Win32
GetACP.) Default ,
, 

.
Encoding Get
Encoding, ( ).
GetEncoding , /, 

268

IV

. , GetEncoding 
ShiftJIS 932.
, Encoding (
GetEncoding) .
;
.
, .
GetEncoding Encoding, 
System.Text.Unicode
Encoding, System.Text.UTF8Encoding, System.Text.UTF32Encoding, System.Text.UTF7Encoding
System.Text.ASCIIEncoding. ,
, 
.
UnicodeEncoding, UTF8Encoding, UTF32Encoding UTF7Encoding
, 
(byte order mark, BOM).
, 
;

.
, BinaryWriter StreamWriter
. ASCIIEncoding 
, .
ASCIIEncoding (, ) 
ASCII Encoding.
ASCIIEncoding , 
.
, Encoding, GetBytes, 
. (
.) GetChars 
GetString. ( .) 
GetBytes GetString.
, , Encoding, GetByteCount, 
, , , 
. ,
. Get
CharCount, ,
. , 
.
GetByteCount GetCharCount ,
/.
, GetMaxByteCount GetMaxCharCount
,
, .
, Encoding, 
, .
. .NET Framework SDK.

11

269

, ,
:

using System;
using System.Text;
public static class Program {
public static void Main() {
foreach (EncodingInfo ei in Encoding.GetEncodings()) {
Encoding e = ei.GetEncoding();
Console.WriteLine("{1}{0}" +
"\tCodePage={2}, WindowsCodePage={3}{0}" +
"\tWebName={4}, HeaderName={5}, BodyName={6}{0}" +
"\tIsBrowserDisplay={7}, IsBrowserSave={8}{0}" +
"\tIsMailNewsDisplay={9}, IsMailNewsSave={10}{0}",
Environment.NewLine,
e.EncodingName, e.CodePage, e.WindowsCodePage,
e.WebName, e.HeaderName, e.BodyName,
e.IsBrowserDisplay, e.IsBrowserSave,
e.IsMailNewsDisplay, e.IsMailNewsSave);
}
}
}
( ):

IBM EBCDIC (USCanada)


CodePage=37, WindowsCodePage=1252
WebName=IBM037, HeaderName=IBM037, BodyName=IBM037
IsBrowserDisplay=False, IsBrowserSave=False
IsMailNewsDisplay=False, IsMailNewsSave=False
OEM United States
CodePage=437, WindowsCodePage=1252
WebName=IBM437, HeaderName=IBM437, BodyName=IBM437
IsBrowserDisplay=False, IsBrowserSave=False
IsMailNewsDisplay=False, IsMailNewsSave=False
IBM EBCDIC (International)
CodePage=500, WindowsCodePage=1252
WebName=IBM500, HeaderName=IBM500, BodyName=IBM500
IsBrowserDisplay=False, IsBrowserSave=False
IsMailNewsDisplay=False, IsMailNewsSave=False
Arabic (ASMO 708)
CodePage=708, WindowsCodePage=1256
WebName=ASMO708, HeaderName=ASMO708, BodyName=ASMO708
IsBrowserDisplay=True, IsBrowserSave=True
IsMailNewsDisplay=False, IsMailNewsSave=False

270

IV

Unicode
CodePage=1200, WindowsCodePage=1200
WebName=utf16, HeaderName=utf16, BodyName=utf16
IsBrowserDisplay=False, IsBrowserSave=True
IsMailNewsDisplay=False, IsMailNewsSave=False
Unicode (BigEndian)
CodePage=1201, WindowsCodePage=1200
WebName=unicodeFFFE, HeaderName=unicodeFFFE, BodyName=unicodeFFFE
IsBrowserDisplay=False, IsBrowserSave=False
IsMailNewsDisplay=False, IsMailNewsSave=False
Western European (DOS)
CodePage=850, WindowsCodePage=1252
WebName=ibm850, HeaderName=ibm850, BodyName=ibm850
IsBrowserDisplay=False, IsBrowserSave=False
IsMailNewsDisplay=False, IsMailNewsSave=False
Unicode (UTF8)
CodePage=65001, WindowsCodePage=1200
WebName=utf8, HeaderName=utf8, BodyName=utf8
IsBrowserDisplay=True, IsBrowserSave=True
IsMailNewsDisplay=True, IsMailNewsSave=True
, , 
Encoding, . 113.

. 11-3. , Encoding

GetPreamble

, ,
. BOM
(byte order mark) (preamble). 
, BOM 
, 
. , Encoding,
0 , .
UTF8Encoding , ,
3 : 0xEF, 0xBB, 0xBF. UnicodeEncoding
, ,
: 0xFE, 0xFF (big endian)
0xFF, 0xFE (little endian)

Convert

.
GetChars
GetBytes
.

Equals

true, Encoding 

GetHashCode

11

271


, UTF16 
System.Net.Sockets.NetworkStream. , 
, 5 , 7. UTF
16 2 . GetString
Encoding 5 ,
2 . GetString 
7 , GetString , 3 ,
!
, Encoding
.
, 
, 
, .
,
Encoding ( )
GetDecoder. ,
System.Text.Decoder. Decoder,
Encoding, . .NET Framework
SDK , 
Decoder. FCL Decoder
. FCL, GetDecoder
.
Decoder : GetChars GetCharCount.
, , 
GetChars GetCharCount Encoding. 
, , 
. ,
.


, , . Decoder
.
, Encoding, /
. , Decoder,
.
, GetDecoder Encoding
GetEncoder. , System.
Text.Encoder, . ,
.NET Framework SDK ,
Encoder. FCL 
Encoder . , Decoder, 
FCL, GetEncoder
.
, Encoder, : GetBytes GetByteCount.
, Encoder,
, .

272

IV

Base-64
UTF16 UTF8 .

base64. FCL base
64, , , Encoding.
base64
, System.
Convert.
base64 ,
FromBase64String FromBase64CharArray Convert.
base64
ToBase64String ToBase64CharArray Convert. 
:

using System;
public static class Program {
public static void Main() {
// 10 , .
Byte[] bytes = new Byte[10];
new Random().NextBytes(bytes);
// .
Console.WriteLine(BitConverter.ToString(bytes));
// base64 .
String s = Convert.ToBase64String(bytes);
Console.WriteLine(s);
// base64 .
bytes = Convert.FromBase64String(s);
Console.WriteLine(BitConverter.ToString(bytes));
}
}

( , 
):

3BB92740593586545FF1
O7knQFk1hlRf8Q==
3BB92740593586545FF1


String , 
. , String
,
, ,


11

273

. String 
, CLR
( String 
), , 
. , ,
, 
.

, . 
Microsoft FCL System. Security.
SecureString. SecureString, 
, .
.

.
, ,
AppendChar, InsertAt, RemoveAt SetAt.
, 
. , 

. , ,
, ,
 .
SecureString IDisposable,
, . 
,
Dispose SecureString. Dispose
, ,
. : SecureString
CriticalFinalizerObject (. 20),
Finalize SecureString, 
. String,
SecureString 
.
, SecureString,
. , FCL SecureString
. , , SecureString,
. 2 .NET Framework SecureString 
:
(cryptographic service provider,
CSP), . System.Security.Cryptography.CspParameters;
, X.509, . 
System.Security.Cryptography.X509Certificates.X509Certificate System.Security.
Cryptography.X509Certificates.X509Certificate2;

, . System.Diagnostics.Process System.Diagnostics.ProcessStartInfo.

274

IV

.NET Framework 
SecureString. , SecureString 
Windows Forms, Windows Presentation Foundation Web Form,

. , SecureString

. FCL, SecureString
.
, ,
SecureString. SecureString
, ,
. 
,
. 
.
SecureString String 
, 
. SecureString 
ToString
( String).
, ,
SecureString ( /unsafe 
C#):

using System;
using System.Security;
using System.Runtime.InteropServices;
public static class Program {
public static void Main() {
using (SecureString ss = new SecureString()) {
Console.Write("Please enter password: ");
while (true) {
ConsoleKeyInfo cki = Console.ReadKey(true);
if (cki.Key == ConsoleKey.Enter) break;
// SecureString.
ss.AppendChar(cki.KeyChar);
Console.Write("*");
}
Console.WriteLine();
// , .
DisplaySecureString(ss);
}
// 'using' SecureString Disposed,
// .
}

11

275

// , .
private unsafe static void DisplaySecureString(SecureString ss) {
Char* pc = null;
try {
// SecureString .
pc = (Char*) Marshal.SecureStringToCoTaskMemUnicode(ss);
// ,
// SecureString.
for (Int32 index = 0; pc[index] != 0; index++)
Console.Write(pc[index]);
}
finally {
// ,
// SecureString.
if (pc != null)
Marshal.ZeroFreeCoTaskMemUnicode((IntPtr) pc);
}
}
}
System.Runtime.InteropServices.Marshal 5 ,
SecureString .
, SecureString, IntPtr.
, 
. . 114
System.Runtime.InteropServices.Marshal, SecureString
, 
.

. 11-4. Marshal

SecureString

SecureStringToBSTR

ZeroFreeBSTR

SecureStringToCoTaskMemAnsi

ZeroFreeCoTaskMemAnsi

SecureStringToCoTaskMemUnicode

ZeroFreeCoTaskMemUnicode

SecureStringToGlobalAllocAnsi

ZeroFreeGlobalAllocAnsi

SecureStringToGlobalAllocUnicode

ZeroFreeGlobalAllocUnicode

1 2

Windows , 
, . 

(CLR) .NET Framework
(FCL). , , , 
. ,
, , 
.


(enumerated type) , ,
. Color, 
, 
:

internal enum Color {


White,
//
Red,
//
Green,
//
Blue,
//
Orange
//
}

0.
1.
2.
3.
4.

, , White 0, Green 1 . .

, .
, , ,
, . 
, , ,
, 
( White 0, 0 White). 
 , 

12

277

, . ,
, ,
, .
. , 
,
Color.Orange ( ),
Fruit ().
CLR ,
. ,
,
(, C++).
System.Enum,
System.ValueType, System.Object. , 
(. 5)
, . 
, .
C# 
. , Color
, :

internal struct Color : System.Enum {


// ,
// .
public const Color White = (Color) 0;
public const Color Red = (Color) 1;
public const Color Green = (Color) 2;
public const Color Blue= (Color) 3;
public const Color Orange = (Color) 4;
// ,
// Color.
// , .
public Int32 value__;
}
, C# , 
, System.
Enum. , . ,
,
. ,
. ,
,
, ,
.
System.Enum, ,
,
. ,
.

278

IV

! , , 
, 
.
, ,
, ,
. ,
, , , 
, .
, , 
, 
. 8.
, Enum GetUnderlyingType:

public static Type GetUnderlyingType(Type enumType);


, 
. ,
byte, sbyte, short, ushort, int (
C# ), uint, long ulong. ,
C# FCL. C#
; FCL ( Int32) 
: error CS1008: Type byte, sbyte, short, ushort, int, uint, long, or ulong expected
( CS1008: byte, sbyte, short, ushort, int, uint, long ulong).
C# , byte
(System.Byte):

internal enum Color : byte {


White,
Red,
Green,
Blue,
Orange
}
Color , 
, GetUnderlyingType:

// "System.Byte".
Console.WriteLine(Enum.GetUnderlyingType(typeof(Color)));
C# . 

(==, !=, <, >, <=, >=, +, , ^, &, |, ~, ++
). , value__
. , C# 
.
.
,
, System.Enum.ToString,
System.Enum:

12

Color c = Color.Blue;
Console.WriteLine(c);
Console.WriteLine(c.ToString());
Console.WriteLine(c.ToString("G"));
Console.WriteLine(c.ToString("D"));
Console.WriteLine(c.ToString("X"));

//
//
//
//
//

279

"Blue" ( ).
"Blue" ( ).
"Blue" ( ).
"3" ( ).
"03" ( ).

ToString
,
, : byte/sbyte 2 ,
short/ushort 4 , int/uint 8 long/ulong 2 .
.
ToString System.Enum Format,
:

public static String Format(Type enumType, Object value, String format);


ToString
. Format ToString:
value , 
. ,
Blue:

// "Blue".
Console.WriteLine(Enum.Format(typeof(Color), 2, "G"))

. 
Enum
, 
, . ,
,
, .
GetValues System.Enum ,
;
, 
:

public static Array GetValues(Type enumType);


GetValues ToString
:

Color[] colors = (Color[]) Enum.GetValues(typeof(Color));


Console.WriteLine("Number of symbols defined: " + colors.Length);
Console.WriteLine("Value\tSymbol\n\t");
foreach (Color c in colors) {
// .
Console.WriteLine("{0,5:D}\t{0:G}", c);
}

280

IV

Number of symbols defined: 5


Value Symbol
'
0 White
1 Red
2 Green
3 Blue
4 Orange
, 
. , 
( , . .)
ToString, , , 
, (, 
). GetValues, Enum
, :

// .
public static String GetName(Type enumType, Object value);
// : ,
// .
public static String[] GetNames(Type enumType);
, , 
. 
, , ,
. 
Parse Enum:

public static Object Parse(Type enumType, String value);


public static Object Parse(Type enumType,
String value, Boolean ignoreCase);
:

// Orange 4, 'c' 4.
Color c = (Color) Enum.Parse(typeof(Color), "orange", true);
// Brown , ArgumentException.
Color c = (Color) Enum.Parse(typeof(Color), "Brown", false);
// Color 1.
Color c = (Color) Enum.Parse(typeof(Color), "1", false);
// Color 23.
Color c = (Color) Enum.Parse(typeof(Color), "23", false);
, IsDefined Enum:

public static Boolean IsDefined(Type enumType, Object value);

12

281


:

// "True", Red Color 1.


Console.WriteLine(Enum.IsDefined(typeof(Color), 1));
// "True", White Color 0.
Console.WriteLine(Enum.IsDefined(typeof(Color), "White"));
// "False", .
Console.WriteLine(Enum.IsDefined(typeof(Color), "white"));
// "False" Color 10.
Console.WriteLine(Enum.IsDefined(typeof(Color), 10));
IsDefined . :

public void SetColor(Color c) {


if (!Enum.IsDefined(typeof(Color), c)) {
throw(new ArgumentOutOfRangeException("c", c, "Invalid Color value."));
}
// White, Red, Green, Blue Orange.
...
}
 SetColor :

SetColor((Color) 547);
, 547, ,
SetColor ArgumentOutOfRangeException, ,
.
! IsDefined , 
. , IsDefined ,
. , IsDefined
, ;
, 
, . 
, IsDefined , 
, . . 
, Color , SetColor
. SetColor IsDefined ,
White, Red, Green, Blue Orange. ,
Color Purple, SetColor
Purple, 
.
, System.Enum ToObject, 
Byte, SByte, Int16, UInt16, Int32, UInt32, Int64 UInt64
.

282

IV

.
,
. , :
, . FCL , 
, . 
: . , 
, 
.


. 
GetAttributes System.IO.File FileAttributes.
FileAttributes , Int32,
 . FCL FileAttributes
:

[Flags, Serializable]
public enum FileAttributes {
ReadOnly
= 0x0001,
Hidden
= 0x0002,
System
= 0x0004,
Directory
= 0x0010,
Archive
= 0x0020,
Device
' 0x0040,
Normal
= 0x0080,
Temporary
= 0x0100,
SparseFile
= 0x0200,
ReparsePoint
= 0x0400,
Compressed
= 0x0800,
Offline
= 0x1000,
NotContentIndexed = 0x2000,
Encrypted
= 0x4000
}
, , :

String file = @"C:\Boot.ini";


FileAttributes attributes = File.GetAttributes(file);
Console.WriteLine("Is {0} hidden? {1}", file,
(attributes & FileAttributes.Hidden) == FileAttributes.Hidden);
:

File.SetAttributes(@"C:\Boot.ini",
FileAttributes.ReadOnly | FileAttributes.Hidden);
FileAttributes , , ,
, , 
. ,
, . , 

12

283

, 
, , .
,
, 
, . 
.
None, 0, 
, (.
ReadWrite).
System.FlagsAttribute:

[Flags]
// C# "Flags", "FlagsAttribute".
internal enum Actions {
None
= 0
Read
= 0x0001,
Write
= 0x0002,
ReadWrite = Actions.Read | Actions.Write,
Delete
= 0x0004,
Query
= 0x0008,
Sync
= 0x0010
}
Actions , 
. 
, . ,
:

Actions actions = Actions.Read | Actions.Delete;


Console.WriteLine(actions.ToString());

// 0x0005.
// "Read, Delete".

ToString 
. 0x0005 . , 
Actions [Flags], ToString 
, .
0x0001 0x0005, ToString Read, Delete.
Actions [Flags], ToString 5.
ToString
: G (), D () X (
).
, [Flags].
, , 
. [Flags] , ToString
.
1. , ,
.
2. (AND)
, , ,
, , 
, . 

284

IV

, 
.
3.
, , 
. ToString
.
4. , 
, .
5. 0 
0, 
.
6. 0.
Actions [Flags], 
. F:

// [Flags]
// .
internal enum Actions {
None
= 0
Read
= 0x0001,
Write
= 0x0002,
ReadWrite = Actions.Read | Actions.Write,
Delete
= 0x0004,
Query
= 0x0008,
Sync
= 0x0010
}
Actions actions = Actions.Read | Actions.Delete;
Console.WriteLine(actions.ToString("F"));

// 0x0005.
// "Read, Delete".

,
, , 
, .
: , ,
. , Actions 
All 0x001F.
Actions 0x001F All. 
.

. , ,
, Parse Enum.
:

// Query 8, 'a' 8.
Actions a = (Actions) Enum.Parse(typeof(Actions), "Query", true);
Console.WriteLine(a.ToString()); // "Query".
// Query, Read, 'a' 9.
a = (Actions) Enum.Parse(typeof(Actions), "Query, Read", false);
Console.WriteLine(a.ToString()); // "Read, Query".

12

285

// Actions 28.
a = (Actions) Enum.Parse(typeof(Actions), "28", false);
Console.WriteLine(a.ToString()); // "Delete, Query, Sync".
Parse :
1. .
2. (+) (), 
Parse ,
,
.
3. ( ), 
.
4. 
. , 
System.ArgumentException. ,
(OR),
.
5. , 
.
IsDefined
. :
, IsDefined 
, , .
, ,
IsDefined ;
, IsDefined
, . 

, IsDefined false.

1 3

, 
. Microsoft .NET (CLR)
(singledimension), (multidimen
sion) (jagged). System.Array,
System.Object. , 
,
, . :

Int32[] myIntegers;
// .
myIntegers = new Int32[100]; // 100 Int32.
myIntegers
Int32. myIntegers null,
.
100 Int32; 0.
, 100
Int32 . , 

SyncBlockIndex, .
myIntegers.
:

Control[] myControls;
// .
myControls = new Control[50]; // 50 Control.
myControls
Control. myControls 
null, . 
50 Control; null.
Control ,
; . 
myControls.

(. 131).

13

287

. 131.
Controls :

myControls[1] = new Button();


myControls[2] = new TextBox();
myControls[3] = myControls[2]; // .
myControls[46] = new DataGrid();
myControls[48] = new ComboBox();
myControls[49] = new Button();
(CLS), 
. , C#,
, , , Micro
soft Visual Basic .NET. , 
, Microsoft 
. CLR 
, . , 
,
,
0, .
. 131 ,
(overhead). ( ),
( 0) .
. ,
.
. 
, 
SZ . 
, IL
, newarr, ldelem, ldelema, ldlen stelem. 
. 
:

// Doubles.
Double[,] myDoubles = new Double[10, 20];

288

IV

// String.
String[,,] myStrings = new String[5, 3, 10];
CLR (jagged) .
,
. 
.
, Point:

// Point.
Point[][] myPolygons = new Point[3][];
// myPolygons[0] 10 Point.
myPolygons[0] = new Point[10];
// myPolygons[1] 20 Point.
myPolygons[1] = new Point[20];
// myPolygons[2] 30 Point.
myPolygons[2] = new Point[30];
// .
for (Int32 x = 0; x < myPolygons[0].Length; x++)
Console.WriteLine(myPolygons[0][x]);
CLR . ,
, , , 100 
( 0 99), 100 5
System.IndexOutOfRangeException.

, CLR.

, JIT
, .
 ,
, C# (.
).


CLR 
, . :
,

. CLR
. ( Array.Copy,
.) :

13

289

// FileStream.
FileStream[,] fs2dim = new FileStream[5, 10];
// Object.
Object[,] o2dim = fs2dim;
// .
// CS0030: 'object[*,*]'
// 'System.IO.Stream[]'.
Stream[] s1dim = (Stream[]) o2dim;
// Stream.
Stream[,] s2dim = (Stream[,]) o2dim;
// String.
// , InvalidCastException.
String[,] st2dim = (String[,]) o2dim;
// Int32 ( ).
Int32[] i1dim = new Int32[5];
// .
// CS0030: 'int[]' 'object[]'.
Object[] o1dim = (Object[]) i1dim;
// , Array.Copy
// .
// Int32.
Object[] ob1dim = new Object[i1dim.Length];
Array.Copy(i1dim, ob1dim, i1dim.Length);
Array.Copy . 
, memmove C, , memmove 
. , ,
. Copy 
:
,
Int32[] Object[];
,
Object[] Int32[];
(widening) CLR,
Int32[] Double[];

, , 
Object[] IFormattable[]. Object[] 
IFormattable[], .

290

IV

Copy:

// , .
internal struct MyValueType : IComparable {
public Int32 CompareTo(Object obj) {
...
}
}
public static class Program {
public static void Main() {
// 100 .
MyValueType[] src = new MyValueType[100];
// IComparable.
IComparable[] dest = new IComparable[src.Length];
// IComparable
// .
Array.Copy(src, dest, src.Length);
}
}
, FCL 
Array.Copy.
,
(array covariance). , 
. , :

String[] sa = new String[100];


Object[] oa = sa;
// oa String.
oa[5] = "Jeff";
// : CLR ,
// oa String; .
oa[3] = 5;
// : CLR ,
// oa Int32;
// ArrayTypeMismatchException.
oa Object[], 
String[]. , 5
, 5 Int32, Object.
, CLR ,
.
, Int32.
, , CLR 
ArrayTypeMismatchException.

13

291


, BlockCopy System.Buffer 
, Array.Copy. BlockCopy 

, Copy. Int32 
, . BlockCopy 

, Byte[], 
Unicode ( ), Char[].

.

, ConstrainedCopy
System.Array. ,
, 
. ConstrainedCopy
(constrained execution region, CER).
, ConstrainedCopy 
, 
. , 
, .


System.Array
 , CLR 
FileStream[] AppDomain.

FileStream[] fsArray;
FileStream[] System.Array, 
System.Array. , 
fsArray. ,
System.Array , Clone,
CopyTo, GetLength, GetLongLength, GetLowerBound, GetUpperBound, Length Rank.
System.Array 
, AsReadOnly, BinarySearch, Clear,
ConstrainedCopy, ConvertAll, Copy, Exists, Find, FindAll, FindIndex, FindLast, FindLastIndex,
ForEach, IndexOf, LastIndexOf, Resize, Reverse, Sort TrueForAll.
. 
.  
, 
.
SDK, ,
.

292

IV

IEnumerable,
ICollection IList
,
, IEnumerable, ICollection IList.
, System.Array
. System.Array ,
System.Object.
, System.Array 
, 
.
CLR , System.Array IEnu
merable<T>, ICollection<T> IList<T>,  , 
, . 
, . 
CLR : 
CLR IEnumerable
<T>, ICollection<T> IList<T> ( T ), 
, , 
. .

Object
Array ( IEnumerable, ICollection, IList)
Object[]
(IEnumerable, ICollection, IList of Object)
String[]
(IEnumerable, ICollection, IList of String)
Stream[]
(IEnumerable, ICollection, IList of Stream)
FileStream[] (IEnumerable, ICollection, IList of FileStream)
.
.
( )
.
, :

FileStream[] fsArray;
FileStream[] CLR
IEnumerable<FileStream>, ICollection<FileStream> IList<FileStream>. ,
FileStream[] IEnumerable<Stream>,
IEnumerable<Object>, ICollection<Stream>, ICollection<Object>, IList<Stream> IList<
Object>. CLR , 
fsArray 
. , fsArray 
:

void M1(IList<FileStream> fsList) { ... }


void M2(ICollection<Stream> sCollection) { ... }
void M3(IEnumerable<Object> oEnumerable) { ... }
: ,
. ,
:

13

293

DateTime[] dtArray; // .
DateTime[] IEnumerable<DateTime>,
ICollection<DateTime> IList<DateTime>, ,
System.ValueType System.Object. , dtArray
M3, 
, 
.


, 
. , .
, Array.Copy ,
, 
.
, . 
, 
; ,
, , ,
. , .
, ,
Array.Copy, . : Array.Copy 
.
, ,
, null,
. Microsoft
, , 
. .
, :

// .
Appointment[] appointments = GetAppointmentsForToday();
for (Int32 a = 0; a < appointments.Length; a++) {
...
}
, , 
:

// .
Appointment[] appointments = GetAppointmentsForToday();
if (appointments != null) {
for (Int32 a = 0, a < appointments.Length; a++) {
// X appointments[a].
}
}

, null .

294

IV

, . ,
, , 
.


. 

CreateInstance Array. 
, , ,
. CreateInstance
,
, , . 
, , Create
Instance, ElementType[] ( ElementType ), 
.

System.Decimal.
2005 2009 , 1 4 
. .
, 
, GetLowerBound GetUpperBound
System.Array, .

using System;
public sealed class DynamicArrays {
public static void Main() {
// [2005..2009][1..4].
Int32[] lowerBounds = { 2005, 1 };
Int32[] lengths
= { 5, 4 };
Decimal[,] quarterlyRevenue = (Decimal[,])
Array.CreateInstance(typeof(Decimal), lengths, lowerBounds);
Console.WriteLine("{0,4} {1,9} {2,9} {3,9} {4,9}",
"Year", "Q1", "Q2", "Q3", "Q4");
Int32 firstYear = quarterlyRevenue.GetLowerBound(0);
Int32 lastYear
= quarterlyRevenue.GetUpperBound(0);
Int32 firstQuarter = quarterlyRevenue.GetLowerBound(1);
Int32 lastQuarter = quarterlyRevenue.GetUpperBound(1);
for (Int32 year = firstYear; year <= lastYear; year++) {
Console.Write(year + " ");
for (Int32 quarter = firstQuarter; quarter <= lastQuarter; quarter++) {
Console.Write("{0,9:C} ", quarterlyRevenue[year, quarter]);
}
Console.WriteLine();
}
}
}

13

295

Year
2005
2006
2007
2008
2009

Q1
$0.00
$0.00
$0.00
$0.00
$0.00

Q2
$0.00
$0.00
$0.00
$0.00
$0.00

Q3
$0.00
$0.00
$0.00
$0.00
$0.00

Q4
$0.00
$0.00
$0.00
$0.00
$0.00


CLR :
. SZ
( singledimensional, zerobased) ;
.
,
( ):

using System;
public sealed class Program {
public static void Main() {
Array a;
// .
a = new String[0];
Console.WriteLine(a.GetType()); // "System.String[]"
// .
a = Array.CreateInstance(typeof(String),
new Int32[] { 0 }, new Int32[] { 0 });
Console.WriteLine(a.GetType()); // "System.String[]"
// .
a = Array.CreateInstance(typeof(String),
new Int32[] { 0 }, new Int32[] { 1 });
Console.WriteLine(a.GetType()); // "System.String[*]" < !
Console.WriteLine();
// .
a = new String[0, 0];
Console.WriteLine(a.GetType()); // "System.String[,]"
// .
a = Array.CreateInstance(typeof(String),
new Int32[] { 0, 0 }, new Int32[] { 0, 0 });
Console.WriteLine(a.GetType()); // "System.String[,]"
// "1" .
a = Array.CreateInstance(typeof(String),

296

IV

new Int32[] { 0, 0 }, new Int32[] { 1, 1 });


Console.WriteLine(a.GetType()); // "System.String[,]"
}
}
Console.WriteLine 
. 
System.String[], 1 System.String[*].
, CLR , . 
: C# String[*], ,
C#,
. GetValue SetValue
Array, 
.
0 1
System.String[,]. CLR 
, .
, : System.String[*,*],
CLR ,

.

, 
. . ,
IL ( newarr, ldelem, ldelema, ldlen stelem) 
, JIT
. , JIT
, , 
, ,
. , JIT
, ,
. :

using System;
public static class Program {
public static void Main() {
Int32[] a = new Int32[5];
for(Int32 index = 0; index < a.Length; index++) {
// X a[index].
}
}
}
, , Length
for. Length , 
. JIT 
, Length Array, , 
, 

13

297

.
. , 
JIT 
. 
, 
, . Length
, .
, , JIT ,
, Length 1,
,
. , JIT ,
:

(( Length 1) <= a.GetUpperBound(0))


. 
JIT , 
, 
. .
, , 

. JIT ,
.
, JIT , 
, , 
.
, , 
(jagged) . C# CLR 
, () ,
, 
. :
, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64,
UInt64, Char, Single, Double, Decimal, Boolean,
, .
, ,
.
, 
, , , 
! , 
, , 
SecurityPermission Skip Verification.
C# ( , 
) :

using System;
using System.Diagnostics;
public static class Program {
public static void Main() {

298

IV

const Int32 numElements = 100;


const Int32 testCount = 10000;
Stopwatch sw;
// .
Int32[,] a2Dim = new Int32[numElements, numElements];
// ( ).
Int32[][] aJagged = new Int32[numElements][];
for (Int32 x = 0; x < numElements; x++)
aJagged[x] = new Int32[numElements];
// 1: , .
sw = Stopwatch.StartNew();
for (Int32 test = 0; test < testCount; test++)
Safe2DimArrayAccess(a2Dim);
Console.WriteLine("{0}: Safe2DimArrayAccess", sw.Elapsed);
// 2:
//
.
sw = Stopwatch.StartNew();
for (Int32 test = 0; test < testCount; test++)
SafeJaggedArrayAccess(aJagged);
Console.WriteLine("{0}: SafeJaggedArrayAccess", sw.Elapsed);
// 3: .
sw = Stopwatch.StartNew();
for (Int32 test = 0; test < testCount; test++)
Unsafe2DimArrayAccess(a2Dim);
Console.WriteLine("{0}: Unsafe2DimArrayAccess", sw.Elapsed);
}
private static void Safe2DimArrayAccess(Int32[,] a) {
for (Int32 x = 0; x < a.GetLength(0); x++) {
for (Int32 y = 0; y < a.GetLength(1); y++) {
Int32 element = a[x, y];
}
}
}
private static void SafeJaggedArrayAccess(Int32[][] a) {
for (Int32 x = 0; x < a.GetLength(0); x++) {
for (Int32 y = 0; y < a[x].GetLength(0); y++) {
Int32 element = a[x][y];
}
}
}
private static unsafe void Unsafe2DimArrayAccess(Int32[,] a) {
Int32 dim0LowIndex = 0; // a.GetLowerBound(0);
Int32 dim0HighIndex = a.GetUpperBound(0);

13

299

Int32 dim1LowIndex = 0; // a.GetLowerBound(1);


Int32 dim1HighIndex = a.GetUpperBound(1);
Int32 dim0Elements = dim0HighIndex X dim0LowIndex;
fixed (Int32* pi = &a[0, 0]) {
for (Int32 x = dim0LowIndex; x <= dim0HighIndex; x++) {
Int32 baseOfDim = x * dim0Elements;
for (Int32 y = dim1LowIndex; y <= dim1HighIndex; y++) {
Int32 element = pi[baseOfDim + y];
}
}
}
}
}
Unsafe2DimArrayAccess unsafe, 
fixed C#.
/unsafe Allow Unsafe Code Build
Microsoft Visual Studio.
:

00:00:02.7977902: Safe2DimArrayAccess
00:00:02.2690798: SafeJaggedArrayAccess
00:00:00.2265131: Unsafe2DimArrayAccess
, . 
, , 
, 
 ,
,
. :
,
. ,
,
. ,
.

, 
, ,

. , 
:
, 
 fixed C# 
;
,
. 
, , 
;

300

IV

 CLR 

.
, . ,
, ,
CLR .
CASPol.exe,
.NET Framework.



,
:
, ( 
);
, . SecureString 
11 , 
SecureStringToCoTaskMemUnicode System.Runtime.Interop
Services.Marshal;
, .
,
 , , stack
alloc C# ( , alloca C). stackalloc

, 
. 
, , , , ,
FCL.
, ()
, ;
. , , /
unsafe C#.
StackallocDemo , stackalloc
C#:

using System;
public static class Program {
public static void Main() {
StackallocDemo();
InlineArrayDemo();
}
private static void StackallocDemo() {
unsafe {

13

301

const Int32 width = 20;


Char* pc = stackalloc Char[width]; // .
String s = "Jeffrey Richter";

// 15 .

for (Int32 index = 0; index < width; index++) {


pc[width X index X 1] =
(index < s.Length) ? s[index] : '.';
}
// ".....rethciR yerffeJ".
Console.WriteLine(new String(pc, 0, width));
}
}
private static void InlineArrayDemo() {
unsafe {
CharArray ca;
// .
Int32 widthInBytes = sizeof(CharArray);
Int32 width = widthInBytes / 2;
String s = "Jeffrey Richter"; // 15 .
for (Int32 index = 0; index < width; index++) {
ca.Characters[width X index X 1] =
(index < s.Length) ? s[index] : '.';
}
// ".....rethciR yerffeJ".
Console.WriteLine(new String(ca.Characters, 0, width));
}
}
}
internal unsafe struct CharArray {
// .
public fixed Char Characters[20];
}
, 
,
.
, CharArray . 
:
( ),
( );
, , 
unsafe;
fixed;

302

IV

;
: Boolean, Char, SByte, Byte,
Int32, UInt32, Int64, UInt64, Single Double.
,
,
. . Inline
ArrayDemo
. , StackallocDemo, .

1 4


(multiple inheritance) ,
. TransmitData, 
, ReceiveData,
. , SocketPort,
, . , SocketPort
: TransmitData ReceiveData.
,
SocketPort, . CLR,
, ,
. , CLR 
. 
,
, , .


.NET Framework System.Object, 4 
: ToString, Equals, GetHashCode GetType.
, ,
Object. , ,
Object,
.
Object :
, 
Object, 
;
, 
Object, Object .
CLR (
, Object).
. ,

, ,
.

304

IV

CLR , , , 
.
. ,

CLR . ,
, 

. C# CLR 
, , , 
.

, 
. , 
, , 
, . 
.


, .
: , 
( C# ),
,
. 
, .
CLR ,
, , CLS
,
. C#
.
C# ,
interface.
Framework Class Library:

public interface IDisposable {


void Dispose();
}
public interface IEnumerable {
IEnumerator GetEnumerator();
}
public interface IEnumerable<T> : IEnumerable {
IEnumerator<T> GetEnumerator();
}
public interface ICollection<T> : IEnumerable<T>, IEnumerable {
void
Add(T item);
void
Clear();

14

Boolean
void
Boolean
Int32
Boolean

305

Contains(T item);
CopyTo(T[] array, Int32 arrayIndex);
Remove(T item);
Count
{ get; } // .
IsReadOnly { get; } // .

}
CLR , 
. CLR 
, 
. ,
.
(public, protected, internal . .).
 
I, . CLR 
( ) 
. 
, 16.
.
, 
, . 
. ,
TCollection<T> TEnumerable<T>
IEnumerable. :
, ICollection<T>,
, ICollection<T>, IEnumerable<T> IEnumerable;
, , ICollec
tion<T>, , 
IEnumerable<T> IEnumerable.


, , , 

. C# ,
; .
System.IComparable<T> ( MSCorLib.dll)
:

public interface IComparable<T> {


Int32 CompareTo(T other);
}
, , 
, , Point:

using System;
// Point System.Object IComparable<T> Point.
public sealed class Point : IComparable<Point> {

306

IV

private Int32 m_x, m_y;


public Point(Int32 x, Int32 y) {
m_x = x;
m_y = y;
}
// IComparable<T> Point.
public Int32 CompareTo(Point other) {
return Math.Sign(Math.Sqrt(m_x * m_x + m_y * m_y)
 Math.Sqrt(other.m_x * other.m_x + other.m_y * other.m_y));
}
public override String ToString() {
return String.Format("({0}, {1})", m_x, m_y);
}
}
public static class Program {
public static void Main() {
Point[] points = new Point[] {
new Point(3, 3),
new Point(1, 2),
};
// CompareTo IComparable<T> Point.
if (points[0].CompareTo(points[1]) > 0) {
Point tempPoint = points[0];
points[0] = points[1];
points[1] = tempPoint;
}
Console.WriteLine("Points from closest to (0, 0) to farthest:");
foreach (Point p in points)
Console.WriteLine(p);
}
}
C# , , , 
public. CLR , 
. ,
, , .
. , 
, 
.
, 
,
. 
, .
, :

14

using System;
public static class Program {
public static void Main() {
/************************* *************************/
Base b = new Base();
// Dispose b: "Dispose Base".
b.Dispose();
// Dispose b: "Dispose Base".
((IDisposable)b).Dispose();
/************************* ************************/
Derived d = new Derived();
// Dispose d: "Dispose Derived".
d.Dispose();
// Dispose d: "Dispose Derived".
((IDisposable)d).Dispose();
/************************* *************************/
b = new Derived();
// Dispose b: "Dispose Base".
b.Dispose();
// Dispose b: Dispose Derived.
((IDisposable)b).Dispose();
}
}
// Object IDisposable.
internal class Base : IDisposable {
// .
public void Dispose() {
Console.WriteLine("Bases Dispose");
}
}
// IDisposable.
internal class Derived : Base, IDisposable {
// Dispose.
// 'new' ,
// Dispose IDisposable.
new public void Dispose() {
Console.WriteLine("Deriveds Dispose");
// : ,
// ( ).

307

308

IV

// base.Dispose();
}
}


System.String FCL
System.Object. , String : IComparable,
ICloneable, IConvertible, IEnumerable, IComparable<String>, IEnumerable<Char>
IEquatable<String>. , String (
) , Object. String
, .
CLR , , 
. ,
, . , CLR 
, Object, 
, :

// s String.
String s = "Jeffrey";
// s, ,
// String, Object, IComparable, ICloneable,
// IConvertible, IEnumerable . .
// cloneable String.
ICloneable cloneable = s;
// cloneable, ,
// ICloneable ( ,
// Object).
// comparable String.
IComparable comparable = s;
// comparable, ,
// IComparable ( ,
// Object).
// enumerable String.
// 
// , .
IEnumerable enumerable = (IEnumerable) comparable;
// enumerable, ,
// IEnumerable ( ,
// Object).
String
, , ,
, String, Jeffrey.
, . 
s String, , , 
String (, Length). s

14

309

, Object (
, GetType).
cloneable ICloneable, ,
Clone, . , 
, Object (, GetType), CLR
, Object. cloneable
, 
, String. , compa
rable, CompareTo , Object,
.
! , 
( ) . 
, ,
,
, CLR 
. 
CLR , 
.


( )
CLR,
(. 1). , 
, , 
. , 
, , 
. , :

internal sealed class SimpleType : IDisposable {


public void Dispose() { Console.WriteLine("Dispose"); }
}
:
, Object, 
;
,
IDisposable. , Dispose
, IDisposable;
, Dispose, SimpleType.
, C# ,
SimpleType Dispose Dispose
IDisposable. C# , 
, . 
, . ,
Dispose , C# 
.

310

IV

, C# 
, , SimpleType
. ,
Dispose , 
Dispose IDisposable.

public sealed class Program {


public static void Main() {
SimpleType st = new SimpleType();
// Dispose.
st.Dispose();
// Dispose IDisposable.
IDisposable d = st;
d.Dispose();
}
}
Dispose,
SimpleType. d IDisposable.
d SimpleType. 
d.Dispose() Dispose IDisposable.
C# , Dispose
Dispose IDisposable, ,
 . :

Dispose
Dispose
SimpleType, :

internal sealed class SimpleType : IDisposable {


public void Dispose() { Console.WriteLine("public Dispose"); }
void IDisposable.Dispose() { Console.WriteLine("IDisposable Dispose"); }
}
Main,
, :

public Dispose
IDisposable Dispose
C# ,
( IDisposable.Dispose),
(explicit interface method implementation, EIMI). :
C# ,
( ). ,
, private, 
, .

.

14

311

, EIMI ,
, . , EIMI
; 
( ) , 
/ . 
, . . 
EIMI.


C# CLR ,
. 
.
, .
( IComparable) 
, Object.
.
. :

private void SomeMethod1() {


Int32 x = 1, y = 2;
IComparable c = x;
// CompareTo Object,
// y Int32.
c.CompareTo(y);
// .
// CompareTo Object;
// "2" ( String) ,
// ArgumentException.
c.CompareTo("2");
}
, 
, FCL ICompa
rable<T>. , 
:

private void SomeMethod2() {


Int32 x = 1, y = 2;
IComparable<Int32> c = x;
// CompareTo Object,
// y Int32.
c.CompareTo(y);
// .
// CompareTo Int32;
// "2" ( String) ,
// String Int32.
c.CompareTo("2");
}

312

IV

,
. : Some
Method1 CompareTo IComparable 
Object; y ( Int32)
y. SomeMethod2 CompareTo
IComparable<T> Int32; y ,
.
FCL 
IComparable, ICollection, IList, IDictionary .
,
. 
FCL ,
, .NET Framework . 

.

, ,
. , IEnumerab
le<T> IEnumerable. ,
IEnumerable<T>, IEnumerable.
, , 
,
. , 
Object,
. 
, ,

.
,
, 
. , , 
.

using System;
// IComparable<T> .
public sealed class Number: IComparable<Int32>, IComparable<String> {
private Int32 m_val = 5;
// CompareTo IComparable<Int32>.
public Int32 CompareTo(Int32 n) {
return m_val.CompareTo(n);
}
// CompareTo IComparable<String>.
public Int32 CompareTo(String s) {

14

313

return m_val.CompareTo(Int32.Parse(s));
}
}
public static class Program {
public static void Main() {
Number n = new Number();
// n 5 Int32.
IComparable<Int32> cInt32 = n;
Int32 result = cInt32.CompareTo(5);
// n "5" String.
IComparable<String> cString = n;
result = cString.CompareTo("5");
}
}


. 
.
, 
. 
. :

public static class SomeType {


private static void Test() {
Int32 x = 5;
Guid g = new Guid();
// M ,
// Int32 IComparable, IConvertible.
M(x);
// M ,
// Guid IComparable, IConvertible.
M(g);
}
// T, M, ,
// IComparable IConvertible.
private static Int32 M<T>(T t) where T : IComparable, IConvertible {
...
}
}
!
,
. ,

314

IV

, . 
,
.
, ,
,
( ), .
, 
.

. 
M x ( Int32, ).
x M . M t.CompareTo(...),
(
, CompareTo).
, M , x
M :

private static Int32 M(IComparable t) {


...
}
C# 
IL, ,
. , 
C# IL, 
,
.



, 
, . , ,
:

public interface IWindow {


Object GetMenu();
}
public interface IRestaurant {
Object GetMenu();
}
, .
, :

// System.Object
// IWindow IRestaurant.
public sealed class MarioPizzeria : IWindow, IRestaurant {

14

315

// GetMenu IWindow.
Object IWindow.GetMenu() { ... }
// GetMenu IRestaurant.
Object IRestaurant.GetMenu() { ... }
// GetMenu (),
// .
public Object GetMenu() { ... }
}
GetMenu,
C#, GetMenu 
.
, MarioPizzeria, 
, :

MarioPizzeria mp = new MarioPizzeria();


// GetMenu MarioPizzeria.
mp.GetMenu();
// IWindow.GetMenu.
IWindow window = mp;
window.GetMenu();
// IRestaurant.GetMenu.
IRestaurant restaurant = mp;
restaurant.GetMenu();



,
. 
, 
. , 
, 
.  System.Object
System.Object,
. , 
EIMI, .
IComparable:

public interface IComparable {


Int32 CompareTo(Object other);
}
,
System.Object. , ,
:

316

IV

internal struct SomeValueType : IComparable {


private Int32 m_x;
public SomeValueType(Int32 x) { m_x = x; }
public Int32 CompareTo(Object other) {
return(m_x  ((SomeValueType) other).m_x);
}
}
SomeValueType, :

public static void Main() {


SomeValueType v = new SomeValueType(0);
Object o = new Object();
Int32 n = v.CompareTo(v); // .
n = v.CompareTo(o);
// InvalidCastException.
}
:
v 
CompareTo, , CompareTo 
Object;
,
, CompareTo SomeValueType, 
InvalidCastException.
, EIMI.
SomeValueType, EIMI:

internal struct SomeValueType : IComparable {


private Int32 m_x;
public SomeValueType(Int32 x) { m_x = x; }
public Int32 CompareTo(SomeValueType other) {
return(m_x  other.m_x);
}
// : public/private.
Int32 IComparable.CompareTo(Object other) {
return CompareTo((SomeValueType) other);
}
}
. ,
CompareTo. Object, 
SomeValueType. , , 
other SomeValueType, . 
, CompareTo
, SomeValueType , 
IComparable. Some
ValueType CompareTo, ICom
parable. CompareTo, 
EIMI.

14

317


:

public static void Main() {


SomeValueType v = new SomeValueType(0);
Object o = new Object();
Int32 n = v.CompareTo(v); // .
n = v.CompareTo(o);
// .
}
, ,
:

public static void Main() {


SomeValueType v = new SomeValueType(0);
IComparable c = v;
// !
Object o = new Object();
Int32 n = c.CompareTo(v); // .
n = c.CompareTo(o);
// InvalidCastException.
}
,
CLR .
Main .
EIMI , IConvertible,
ICollection, IList IDictionary.
.


!
EIMI, 
EIMI , . ,
EIMI .
, EIMI (, 
). EIMI
( ):
, , EIMI
, Microsoft Visual Studio IntelliSense;
, 
;
EIMI .
.NET Framework
, 
. 
, Int32 , IConvertible.
, , ,
, IConvertible
Int32 . , :

318

IV

public static void Main() {


Int32 x = 5;
Single s = x.ToSingle(null); // IConvertible.
}
C# : error
CS0117: int does not contain a definition for ToSingle ( CS0117: int
ToSingle). 
, , Int32 ToSingle 
, .
ToSingle Int32, IConvertible:

public static void Main() {


Int32 x = 5;
Single s = ((IConvertible) x).ToSingle(null);
}
,
. 
Int32 IConvertible 
,  .
.
, , EIMI , EIMI
. :

internal class Base : IComparable {


// (EIMI).
Int32 IComparable.CompareTo(Object o) {
Console.WriteLine("Bases CompareTo");
return 0;
}
}
internal sealed class Derived : Base, IComparable {
// , .
public Int32 CompareTo(Object o) {
Console.WriteLine("Deriveds CompareTo");
// EIMI :
// "error CS0117: 'Base' does not contain a definition for 'CompareTo'".
base.CompareTo(o);
return 0;
}
}
CompareTo Derived base.CompareTo,
C#. ,
Base CompareTo,
. CompareTo,

14

319

IComparable. CompareTo Derived


:

// , .
public Int32 CompareTo(Object o) {
Console.WriteLine("Deriveds CompareTo");
// EIMI .
IComparable c = this;
c.CompareTo(o);
return 0;
}
this c IComparable. 
c CompareTo. CompareTo Derived
CompareTo IComparable Derived,
. ,
Derived IComparable:

internal sealed class Derived : Base /*, IComparable */ { ... }


CompareTo CompareTo Base.
,
.

, . Derived
. 
Base Derived:

internal class Base : IComparable {


// (EIMI).
Int32 IComparable.CompareTo(Object o) {
Console.WriteLine("Bases IComparable CompareTo");
return CompareTo(o); // .
}
// ( ).
public virtual Int32 CompareTo(Object o) {
Console.WriteLine("Bases virtual CompareTo");
return 0;
}
}
internal sealed class Derived : Base, IComparable {
// , .
public override Int32 CompareTo(Object o) {
Console.WriteLine("Deriveds CompareTo");

320

IV

// Base.
return base.CompareTo(o);
}
}
: , 
. 
, , . , EIMI
.
EIMI, 
, . ! EIMI
, , 
.

:
?
, 
? . ,
.

. 
, , . ,
(IConvertible), 
(ISerializable) . . ,
System.ValueType
.
.
, 
, . 
, 
, . 
.
, 
, . , 
COM COM 
Microsoft Word Microsoft Internet Explorer. 

, .
, 

. . 

.
FCL , , 
. System.IO.Stream , 
, Read Write. (System.

14

321

IO.FileStream, System.IO.MemoryStream System.Net.Sockets.NetworkStream)


Stream. Microsoft
Stream , 
. , 
/,
Stream.
, , 
, : Stream 
. ,
Windows Forms, Button, CheckBox, ListBox
System.Windows.Forms.Control,
, Control.
(collections), Microsoft
FCL . System.Collections.Generic 
: IEnumerable<T>, ICollection<T>,
IList<T> IDictionary<TKey, TValue>. Microsoft 
( List<T>, Dictionary<TKey, TValue>, Queue<T>, Stack<T> .),
. ,
 . ,
List<T>, Dictionary<TKey, TValue> Queue<T> 
.
, , .
, , 
, . ,
IList<T>, , 
, , . 
.
, , 
, . , FCL
IComparer<T>, .
, FCL Comparer<T>, 
() 
. , 
.

1 5


, . Microsoft
.NET Framework !
(delegate).
, ++,
. ,
( CLR).

, .


qsort ,
. Microsoft Windows !
, ,
. .NET Framework !
. , ,
: , !
, ,
.
/++ ,
. , !
, , !
, . , /++ !
(
).
.NET Framework !
, Windows. !
.NET Framework , .
, :

using System;
using System.Windows.Forms;
using System.IO;

15

323

// ; ,
// Int32 void.
internal delegate void Feedback(Int32 value);
public sealed class Program {
public static void Main() {
StaticDelegateDemo();
InstanceDelegateDemo();
ChainDelegateDemo1(new Program());
ChainDelegateDemo2(new Program());
}
private static void StaticDelegateDemo() {
Console.WriteLine(" Static Delegate Demo ");
Counter(1, 3, null);
Counter(1, 3, new Feedback(Program.FeedbackToConsole));
Counter(1, 3, new Feedback(FeedbackToMsgBox)); // "Program." .
Console.WriteLine();
}
private static void InstanceDelegateDemo() {
Console.WriteLine(" Instance Delegate Demo ");
Program p = new Program();
Counter(1, 3, new Feedback(p.FeedbackToFile));
Console.WriteLine();
}
private static void ChainDelegateDemo1(Program p) {
Console.WriteLine(" Chain Delegate Demo 1 ");
Feedback fb1 = new Feedback(FeedbackToConsole);
Feedback fb2 = new Feedback(FeedbackToMsgBox);
Feedback fb3 = new Feedback(p.FeedbackToFile);
Feedback fbChain = null;
fbChain = (Feedback) Delegate.Combine(fbChain, fb1);
fbChain = (Feedback) Delegate.Combine(fbChain, fb2);
fbChain = (Feedback) Delegate.Combine(fbChain, fb3);
Counter(1, 2, fbChain);
Console.WriteLine();
fbChain = (Feedback)
Delegate.Remove(fbChain, new Feedback(FeedbackToMsgBox));
Counter(1, 2, fbChain);
}
private static void ChainDelegateDemo2(Program p) {
Console.WriteLine(" Chain Delegate Demo 2 ");
Feedback fb1 = new Feedback(FeedbackToConsole);
Feedback fb2 = new Feedback(FeedbackToMsgBox);
Feedback fb3 = new Feedback(p.FeedbackToFile);

324

IV

Feedback fbChain = null;


fbChain += fb1;
fbChain += fb2;
fbChain += fb3;
Counter(1, 2, fbChain);
Console.WriteLine();
fbChain = new Feedback(FeedbackToMsgBox);
Counter(1, 2, fbChain);
}
private static void Counter(Int32 from, Int32 to, Feedback fb) {
for (Int32 val = from; val <= to; val++) {
// , .
if (fb != null)
fb(val);
}
}
private static void FeedbackToConsole(Int32 value) {
Console.WriteLine("Item=" + value);
}
private static void FeedbackToMsgBox(Int32 value) {
MessageBox.Show("Item=" + value);
}
private void FeedbackToFile(Int32 value) {
StreamWriter sw = new StreamWriter("Status", true);
sw.WriteLine("Item=" + value);
sw.Close();
}
}
, .
Feedback. !
. Feedback ,
Int32 void.
typedef /++, .
Program Counter. !
, from to. Counter
fb, !!
Feedback. Counter ,
( fb null) ( !
fb). !
.
.

15

325



, Counter,
, . !
StaticDelegateDemo .
StaticDelegateDemo Counter, !
, fb Counter, null.
fb null,
.
Counter Feedback !
. ! !
, !
, . Feedback
( Program.FeedbackToConsole), ,
. , new,
Counter.
Counter FeedbackToConsole,
Program. FeedbackToConsole , !
.
FeedbackToConsole Program
, Counter !
Program. ,
Counter FeedbackToConsole . !
, Counter .
,
,
, ! ,
.
Counter StaticDelegateDemo ,
Feedback !
Program.FeedbackToMsgBox. FeedbackToMsgBox , !
, .
. , !
Feedback , !
FeedbackToConsole FeedbackToMsgBox Program
Feedback,
( Int32) (void). ,
FeedbackToConsole :

private static Boolean FeedbackToConsole(String value) {


...
}
C#
error CS0123: The signature of method FeedbackToConsole does not match

326

IV

this delegate type ( CS0123: FeedbackToConsole !


).
C#, CLR
. (covariance) , !
, , . 
(contra!variance) , !
, . ,
:

delegate Object MyCallback(FileStream s);


, , !
:

String SomeMethod(Stream s);


, SomeMethod ( String), !
, , (Object); !
. SomeMethod ( Stream) ,
(FileStream); !
.
: !
, void. , ,
MyCallback:

Int32 SomeOtherMethod(Stream s);


, SomeOtherMethod, ( Int32)
, MyCallback ( Object);
, Int32 . !
void ,
, !
. , C#
.



, ,
. , !
, InstanceDelegateDemo
.
, p Program Instance
DelegateDemo. Program
. Counter !
Feedback, p.FeedbackToFile.
FeedbackToFile,
, . Counter
, fb,

15

327

FeedbackToFile, p
.
FeedbackToFile FeedbackToConsole FeedbackToMsgBox,
, .
( Status AppBase .)
,
, .
, !
. ,

. , , !
.


, :
delegate C#, !
new ,
( !
, !).
, !
. , CLR
. !
CLR ,
!
. ,
.
! :

internal delegate void Feedback(Int32 value);


, , !
, :

internal class Feedback : System.MulticastDelegate {


// .
public Feedback(Object object, IntPtr method);
// , .
public virtual void Invoke(Int32 value);
// , .
public virtual IAsyncResult BeginInvoke(Int32 value,
AsyncCallback callback, Object object);
public virtual void EndInvoke(IAsyncResult result);
}
: , Invoke,
BeginInvoke EndInvoke. !

328

IV

Invoke. BeginInvoke EndInvoke


23, .
ILDasm.exe, ,
(. 15!1):

. 151. ILDasm.exe ,

Feedback, Sys
tem.MulticastDelegate, .NET Framework Class
Library ( MulticastDelegate).
! System.MulticastDelegate
System.Delegate, , , System.Object.
, !
; FCL . !
, , , !

MulticastDelegate, , !
, Delegate, MulticastDelegate. !
, Delegate Combine Remove.
( , .)
, Delegate.
MulticastDelegate,
Delegate,
.
, internal.
public, !
Feedback .
, (!
), . ,
, , !
.
MulticastDelegate, !
, MulticastDelegate. ,
(. 15!1).

15

329

. 15-1. MulticastDelegate

_target

System.Object

! !
, null. ! !
,
, !
. !
, ,
this

_methodPtr

System.Int32

, CLR

_prev

System.Multicast null.
Delegate
(
)

:
, . , !
, , , Program.Feedback
ToConsole p.FeedbackToFile. ,
!
, ,
, .
object , IntPtr (!
MethodDef MethodRef), !
, method. !
object null. !
_target _methodPtr. null
_invocationList. , !
.
, ,
. :

Feedback fbStatic = new Feedback(Program.FeedbackToConsole);


Feedback fbInstance = new Feedback(new Program().FeedbackToFile);
fbStatic fbInstance
! Feedback (. 15!2).

. 152. , ,
,

330

IV

Delegate !
: Target Method.
. Target ,
. , Target ,
_target. , Target null.
Method System.Reflection.MethodInfo,
. , Method , !
_methodPtr MethodInfo
.
!, , ,
:

Boolean DelegateRefersToInstanceMethodOfType(MulticastDelegate d, Type type) {


return((d.Target != null) && d.Target.GetType() == type);
}
, (!
, FeedbackToMsgBox):

Boolean DelegateRefersToMethodOfName(MulticastDelegate d, String methodName) {


return(d.Method.Name == methodName);
}
, .
, !, ,
.
Counter:

private static void Counter(Int32 from, Int32 to, Feedback fb) {


for (Int32 val = from; val <= to; val++) {
// , .
if (fb != null)
fb(val);
}
}
, !
. if , null fb. ,
, .
null , fb , 
! Feedback, null. ,
fb, (val),
. Invoke !
!, , fb , !
. , :

fb(val);
, :

fb.Invoke(val);

15

331

Counter ILDasm.exe, , !
, Invoke . . 15!3
IL! Counter. IL_0009
Invoke Feedback.

. 153. ILDasm.exe ,
Invoke Feedback
, Counter Invoke , :

private static void Counter(Int32 from, Int32 to, Feedback fb) {


for (Int32 val = from; val <= to; val++) {
// , .
if (fb != null)
fb.Invoke(val);
}
}
, , Invoke !
Feedback. Invoke _target
_methodPtr . : !
Invoke , Feedback,
( ) Invoke Int32 !
void.


( )
,
. (chaining) , !
!, , !
. ,
ChainDelegateDemo1 , .

332

IV

Console.WriteLine !, !
fb1, fb2 fb3 (. 15!4).

. 154. ,
fb1, fb2 fb3
! ! Feedback
, . !
fbChain null !
. Combine Delegate !
:

fbChain = (Feedback) Delegate.Combine(fbChain, fb1);


Combine !
null fb1. Combine fb1, !
fbChain !,
fb1 (. 15!5).

. 155. 

15

333

, Combine:

fbChain = (Feedback) Delegate.Combine(fbChain, fb2);


Combine , fbChain !,
!. !
_target _methodPtr.
, , _invocationList
!. ( 0)
, FeedbackTo
Console ( , fbChain). !
( 1) , !
FeedbackToMsgBox ( fb2). , fbChain
! (. 15!6).

. 156. 

Combine:

fbChain = (Feedback) Delegate.Combine(fbChain, fb3);


, , fbChain !, Combine
! (. 15!7). , ! !
_target _methodPtr ! ,
_invocationList !.
( 0 1)
, ! .
( 2) ,
FeedbackToFile ( fb3). , !
fbChain !. :
, _invocationList,
.

334

IV

. 157. 
, fbChain !
Counter:

Counter(1, 2, fbChain);
Counter , Invoke !
! Feedback, . 15!3. Invoke !
, fbChain, !
, _invocationList null, ,
, !
. !
: FeedbackToConsole, FeedbackToMsgBox FeedbackToFile.
Invoke Feedback :

public void Invoke(Int32 value) {


Delegate[] delegateSet = _invocationList as Delegate[];
if (delegateSet != null) {
// , .
foreach (Feedback d in delegateSet)
d(value); // .
} else {
// ,
// .
// .
_methodPtr.Invoke(_target, value);
// .

15

335

//
// C#.
}
}
, Remove
Delegate. ChainDelegateDemo1 :

fbChain = (Feedback) Delegate.Remove(fbChain, new Feedback(FeedbackToMsgBox));


Remove ( 0),
!, (
fbChain). Remove , target _methodPtr
(
Feedback). Remove
, ! _invo
cationList
!
. Remove null.
: Remove ,
_target _methodPtr.
! Feedback, void.
:

public delegate Int32 Feedback(Int32 value);


Invoke :

public Int32 Invoke(Int32 value) {


Int32 result;
Delegate[] delegateSet = _invocationList as Delegate[];
if (delegateSet != null) {
// , .
foreach (Feedback d in delegateSet)
result = d(value); // .
} else {
// ,
// .
// .
result = _methodPtr.Invoke(_target, value);
// .
//
// C#.
}
return result;
}
!
result. result
(
); , !
Invoke.

336

IV

C#
C# , !
+= = .
Delegate.Combine Delegate.Remove . !
. ChainDelegateDemo1
ChainDelegateDemo2 (. ) !
IL!. , ChainDelegateDemo2
+= = C#.
, !
IL! ILDasm.exe. , C# !
+= =
Combine Remove Delegate .


, ! !
. Invoke !
, , !
. , .
, .
, , !
, . , !
, ,
. !
? !
,
. , .
, , MulticastDele
gate GetInvocationList,
,
:

public abstract class MulticastDelegate : Delegate {


// ,
// .
public sealed override Delegate[] GetInvocationList();
}
GetInvocationList , MulticastDelegate,
Delegate, !
! . GetInvocationList !
,
; .
_invocationList null, ,
, .
, !
:

15

using System;
using System.Text;
// Light.
internal sealed class Light {
// Light.
public String SwitchPosition() {
return "The light is off";
}
}
// Fan.
internal sealed class Fan {
// Fan.
public String Speed() {
throw new InvalidOperationException("The fan broke due to overheating");
}
}
// Speaker.
internal sealed class Speaker {
// Speaker.
public String Volume() {
return "The volume is loud";
}
}
public sealed class Program {
// , .
private delegate String GetStatus();
public static void Main() {
// .
GetStatus getStatus = null;
//
// .
getStatus += new GetStatus(new Light().SwitchPosition);
getStatus += new GetStatus(new Fan().Speed);
getStatus += new GetStatus(new Speaker().Volume);
// ,
// .
Console.WriteLine(GetComponentStatusReport(getStatus));
}
// ,
// .
private static String GetComponentStatusReport(GetStatus status) {

337

338

IV

// , .
if (status == null) return null;
// .
StringBuilder report = new StringBuilder();
// , .
Delegate[] arrayOfDelegates = status.GetInvocationList();
// .
foreach (GetStatus getStatus in arrayOfDelegates) {
try {
// .
report.AppendFormat("{0}{1}{1}", getStatus(), Environment.NewLine);
}
catch (InvalidOperationException e) {
// .
Object component = getStatus.Target;
report.AppendFormat(
"Failed to get status from {1}{2}{0}Error: {3}{0}{0}",
Environment.NewLine,
((component == null) ? "" : component.GetType() + "."),
getStatus.Method.Name,
e.Message);
}
}
// .
return report.ToString();
}
}
, :

The light is off


Failed to get status from Fan.Speed
Error: The fan broke due to overheating
The volume is loud


C#
, !
. .
:

button1.Click += new EventHandler(button1_Click);

15

339

button1.Click , :

void button1_Click(Object sender, EventArgs e) {


// ...
}
button1_Click
, .

! EventHandler ,
button1_Click. ! EventHandler CLR,
,
. !
. , !
.
:

button1.Click += button1_Click;
, C# Microsoft !
. !
, , , . ,
, C#, !
IL!, !
CLR . ,
C#
.

1:
-
, C# ,
!, . :

internal sealed class AClass {


public static void CallbackWithoutNewingADelegateObject() {
ThreadPool.QueueUserWorkItem(SomeAsyncTask, 5);
}
private static void SomeAsyncTask(Object o) {
Console.WriteLine(o);
}
}
QueueUserWorkItem ThreadPool !
! WaitCallback,
SomeAsyncTask. C# , ,
! WaitCallback,
. , C# !
IL! ! WaitCallback, !
.

340

IV

2:

, SomeAsyncTask, !
QueueUserWorkItem ThreadPool. C# !
, . !
, :

internal sealed class AClass {


public static void CallbackWithoutNewingADelegateObject() {
ThreadPool.QueueUserWorkItem(
delegate(Object obj) { Console.WriteLine(obj); },
5);
}
}
: QueueUserWorkItem
! delegate , !
, C# !
( AClass). ! ,

. ILDasm.exe, !
. !
ILDasm.exe , C# <Callback
WithoutNewingADelegateObject>b__0. : !
, ,
C# !
.
ILDasm.exe, , C#
System.Runtime.CompilerServices.CompilerGeneratedAttribute
, , . !
.
, !
( ), . !
!
() . !
(!
, unsafe). , !
!
, , ,
.
, public, protected, internal,
virtual, sealed, override abstract.
, C#
( ):

internal sealed class AClass {


// .

15

341

// : CallbackWithoutNewingADelegateObject
// .
// : .
[CompilerGenerated]
private static WaitCallback <>9__CachedAnonymousMethodDelegate1;
public static void CallbackWithoutNewingADelegateObject() {
if (<>9__CachedAnonymousMethodDelegate1 == null) {
// .
<>9__CachedAnonymousMethodDelegate1 =
new WaitCallback(<CallbackWithoutNewingADelegateObject>b__0);
}
ThreadPool.QueueUserWorkItem(<>9__CachedAnonymousMethodDelegate1, 5);
}
[CompilerGenerated]
private static void <CallbackWithoutNewingADelegateObject>b__0(Object obj) {
Console.WriteLine(obj);
}
}
WaitCall
back: void Object. !
, , (Object obj) !
delegate.
, ; !
, , (
, ). ,
,
( , CallbackWithoutNewingADelegate
Object ).
. :

internal sealed class AClass {


private static String sm_name; // .
public static void CallbackWithoutNewingADelegateObject() {
ThreadPool.QueueUserWorkItem(
// .
delegate(Object obj) { Console.WriteLine(sm_name+ ": " + obj); },
5);
}
}
CallbackWithoutNewingADelegateObject ,
.

, , ,
this . , !
,
:

342

IV

internal sealed class AClass {


private String m_name; // .
// .
public void CallbackWithoutNewingADelegateObject() {
ThreadPool.QueueUserWorkItem(
// .
delegate(Object obj) { Console.WriteLine(m_name+ ": " + obj); },
5);
}
}

3:

, !
, :

button1.Click +=
delegate(Object sender, EventArgs e)
{ MessageBox.Show("The Button was clicked!"); };
,
, . !
sender e.
, C#
:

button1.Click +=
delegate { MessageBox.Show("The Button was clicked!"); };
: (Object sender, EventArgs e). !
, ,
CLR !
. !
, EventHandler ( ,
Click Button).
.
! ,
delegate , !
. , ,
void, return !
.

4:


, !
. ,

15

343

, .
:

internal sealed class AClass {


public static void UsingLocalVariablesInTheCallbackCode(Int32 numToDo) {
// .
Int32[] squares = new Int32[numToDo];
AutoResetEvent done = new AutoResetEvent(false);
// .
for (Int32 n = 0; n < squares.Length; n++) {
ThreadPool.QueueUserWorkItem(
delegate(Object obj) {
Int32 num = (Int32) obj;
// .
squares[num] = num * num;
// , ( ) .
if (Interlocked.Decrement(ref numToDo) == 0)
done.Set();
},
n);
}
// .
done.WaitOne();
// .
for (Int32 n = 0; n < squares.Length; n++)
Console.WriteLine("Index {0}, Square={1}", n, squares[n]);
}
}
, C# ,
. !
, numToDo, , squares done.
.
,
( CLR).
? ,
, !
. ,
. UsingLocalVariables
InTheCallbackCode , !
!
, .
, , , !
C# . C# !
( ):

344

IV

internal sealed class AClass {


public static void UsingLocalVariablesInTheCallbackCode(Int32 numToDo) {
// .
WaitCallback callback1 = null;
// .
<>c__DisplayClass2 class1 = new <>c__DisplayClass2();
// .
class1.numToDo = numToDo;
class1.squares = new Int32[class1.numToDo];
class1.done = new AutoResetEvent(false);
// .
for (Int32 n = 0; n < class1.squares.Length; n++) {
if (callback1 == null) {
//
// .
callback1 = new WaitCallback(
class1.<UsingLocalVariablesInTheCallbackCode>b__0);
}
ThreadPool.QueueUserWorkItem(callback1, n);
}
// .
class1.done.WaitOne();
// .
for (Int32 n = 0; n < class1.squares.Length; n++)
Console.WriteLine("Index {0}, Square={1}", n, class1.squares[n]);
}
// ,
//
// Aclass.
[CompilerGenerated]
private sealed class <>c__DisplayClass2 : Object {
//
// .
public Int32[] squares;
public Int32 numToDo;
public AutoResetEvent done;
// .
public <>c__DisplayClass2 { }

15

345

// , .
public void <UsingLocalVariablesInTheCallbackCode>b__0(Object obj) {
Int32 num = (Int32) obj;
squares[num] = num * num;
if (Interlocked.Decrement(ref numToDo) == 0)
done.Set();
}
}
}
! , !
C#.
, , !
. , , , !
, !
. , , !
Visual Studio !
.
: !
, , !
, !
. , !

, . !
,
.
, .

// String.
String[] names = { "Jeff", "Kristin", "Aidan" };
// , 'i'.
Char charToFind = 'i';
names = Array.FindAll(names, delegate(String name)
{ return (name.IndexOf(charToFind) >= 0); });
// .
names = Array.ConvertAll<String, String>(names, delegate(String name)
{ return name.ToUpper(); });
// .
Array.Sort(names, String.Compare);
// .
Array.ForEach(names, Console.WriteLine);

346

IV


, , ,
. , fb !
, Feedback, !
:

fb(item); // item Int32.


, , !
. ,
,
.
. !
10, EventSet.
. !
,
. , !
.
, System.Delegate ,
, !
. :

public abstract class Delegate {


// , .
public static Delegate CreateDelegate(Type type, MethodInfo method);
public static Delegate CreateDelegate(Type type, MethodInfo method,
Boolean throwOnBindFailure);
// , .
public static Delegate CreateDelegate(Type type,
Object firstArgument, MethodInfo method); // firstArgument means this
public static Delegate CreateDelegate(Type type,
Object firstArgument, MethodInfo method, Boolean throwOnBindFailure);
// , .
public Object DynamicInvoke(params Object[] args);
}
CreateDelegate Delegate,
, type. MethodInfo ,
;
API (. 22). !
, CreateDelegate firstArgu
ment, ,
this ( ). , CreateDelegate Argu
mentException, , !
method. , method, !
, , !

15

347

type. throwOnBindFailure false,


null.
! System.Delegate !
CreateDelegate, . !
. Microsoft , !
. ,

String, MethodInfo. , ,
.
DynamicInvoke System.Delegate
!, , !
. DynamicInvoke !
, .
, , !
ArgumentException. DynamicInvoke , !
.
CreateDelegate Dyna
micInvoke:

using System;
using System.Reflection;
using System.IO;
// .
internal delegate Object TwoInt32s(Int32 n1, Int32 n2);
internal delegate Object OneString(String s1);
public static class Program {
public static void Main(String[] args) {
if (args.Length < 2) {
String fileName = Path.GetFileNameWithoutExtension(
Assembly.GetEntryAssembly().Location);
String usage =
@"Usage:" +
"{0}{1} delType methodName [Arg1] [Arg2]" +
"{0} where delType must be TwoInt32s or OneString"+
"{0} if delType is TwoInt32s, methodName must be Add or Subtract" +
"{0} if delType is OneString, methodName must be NumChars or Reverse" +
"{0}" +
"{0}Examples:" +
"{0} {1} TwoInt32s Add 123 321" +
"{0} {1} TwoInt32s Subtract 123 321" +
"{0} {1} OneString NumChars \"Hello there\"" +
"{0} {1} OneString Reverse \Hello there\"";
Console.WriteLine(usage, Environment.NewLine, fileName);
return;
}

348

IV

// delType .
Type delType = Type.GetType(args[0]);
if (delType == null) {
Console.WriteLine("Invalid delType argument: " + args[0]);
return;
}
Delegate d;
try {
// Arg1 .
MethodInfo mi = typeof(Program).GetMethod(args[1],
BindingFlags.NonPublic | BindingFlags.Static);
// , .
d = Delegate.CreateDelegate(delType, mi);
}
catch (ArgumentException) {
Console.WriteLine("Invalid methodName argument: " + args[1]);
return;
}
// , ,
// .
Object[] callbackArgs = new Object[args.Length 2];
if (d.GetType() == typeof(TwoInt32s)) {
try {
// String Int32.
for (Int32 a = 2; a < args.Length; a++)
callbackArgs[a 2] = Int32.Parse(args[a]);
}
catch (FormatException) {
Console.WriteLine("Parameters must be integers.");
return;
}
}
if (d.GetType() == typeof(OneString)) {
// String.
Array.Copy(args, 2, callbackArgs, 0, callbackArgs.Length);
}
try {
// .
Object result = d.DynamicInvoke(callbackArgs);
Console.WriteLine("Result = " + result);
}
catch (TargetParameterCountException) {
Console.WriteLine("Incorrect number of parameters specified.");
}
}

15

// , Int32.
private static Object Add(Int32 n1, Int32 n2) {
return n1 + n2;
}
// , Int32.
private static Object Subtract(Int32 n1, Int32 n2) {
return n1 n2;
}
// , String.
private static Object NumChars(String s1) {
return s1.Length;
}
// , String.
private static Object Reverse(String s1) {
Char[] chars = s1.ToCharArray();
Array.Reverse(chars);
return new String(chars);
}
}

349

1 6

,  ,
. 
, , 
.
,
.
(generics) ,
(CLR) , 
, 
.
, , , , 
, , ,
. 
. , 
, Int32s, String . .,
DateTime, Versions...
. CLR
, , 
. , CLR
.
, CLR
, , .
, FCL 
, .
. , .
FCL, ,
List<T> System.Collections.Generic.
( 
):

[Serializable]
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>,
IList, ICollection, IEnumerable {

16

public
public
public
public
public
public
public
public
public
public
public

351

List();
void Add(T item);
Int32 BinarySearch(T item);
void Clear();
Boolean Contains(T item);
Int32 IndexOf(T item);
Boolean Remove(T item);
void Sort();
void Sort(IComparer<T> comparer);
void Sort(Comparison<T> comparison);
T[] ToArray();

public Int32 Count { get; }


public T this[Int32 index] { get; set; }
}
<T> List ,
. 
, (, T), 
 (type parameters). T ,
, 
. , List T 
( Add T) 
( ToArray T) . 
 ( C# this). 
get, T,  set,
T. T ,
, ,
.
, List<T> 
, ,
.
. , 
List,  DateTime.

private static void SomeMethod() {


// (List), DateTime.
List<DateTime> dtList = new List<DateTime>();
// DateTime .
dtList.Add(DateTime.Now);
// .
// DateTime .
dtList.Add(DateTime.MinValue); // .
// String .
dtList.Add("1/1/2004");
// .
// DateTime .
DateTime dt = dtList[0];
// .
}

352

IV


.
, 
, . 
C++ Java
.

, CLR , 
, . 
, ,
. 
String Add .

, , 
. SomeMethod 
(DateTime), 
dt ( 0).


, Object.
,
CLR . 5 
, , 
, , , 
. 
,
CLR . 
(. ), CLR
,
.
, ,

ArrayList FCL List.

.

using
using
using
using

System;
System.Collections;
System.Collections.Generic;
System.Diagnostics;

public static class Program {


public static void Main() {
ValueTypePerfTest();
ReferenceTypePerfTest();
}

16

private static void ValueTypePerfTest() {


const Int32 count = 10000000;
using (new OperationTimer("List<Int32>")) {
List<Int32> l = new List<Int32>(count);
for (Int32 n = 0; n < count; n++) {
l.Add(n);
Int32 x = l[n];
}
l = null; // .
}
using (new OperationTimer("ArrayList of Int32")) {
ArrayList a = new ArrayList();
for (Int32 n = 0; n < count; n++) {
a.Add(n);
Int32 x = (Int32) a[n];
}
a = null; // .
}
}
private static void ReferenceTypePerfTest() {
const Int32 count = 10000000;
using (new OperationTimer("List<String>")) {
List<String> l = new List<String>();
for (Int32 n = 0; n < count; n++) {
l.Add("X");
String x = l[n];
}
l = null; // .
}
using (new OperationTimer("ArrayList of String")) {
ArrayList a = new ArrayList();
for (Int32 n = 0; n < count; n++) {
a.Add("X");
String x = (String) a[n];
}
a = null; // .
}
}
}
// .
internal sealed class OperationTimer : IDisposable {
private Int64 m_startTime;
private String m_text;
private Int32 m_collectionCount;

353

354

IV

public OperationTimer(String text) {


PrepareForOperation();
m_text = text;
m_collectionCount = GC.CollectionCount(0);
// ,
// .
m_startTime = Stopwatch.GetTimestamp();
}
public void Dispose() {
Console.WriteLine("{0,6:###.00} seconds (GCs={1,3}) {2}",
(Stopwatch.GetTimestamp() 5 m_startTime) /
(Double) Stopwatch.Frequency,
GC.CollectionCount(0) 5 m_collectionCount, m_text);
}
private static void PrepareForOperation() {
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
Release ( 
) , :

.10
2.02
.52
.53

seconds
seconds
seconds
seconds

(GCs=
(GCs=
(GCs=
(GCs=

0)
30)
6)
6)

List<Int32>
ArrayList of Int32
List<String>
ArrayList of String

, List Int32 ,
ArrayList . : 
2 , 20 ! ,
(Int32) ArrayList ,
, , 30 , List .
:
.
List . ,

. , 
, .
, CLR

.
.
.

16

355

FCL
, , FCL 
. Microsoft

. , ,
, ,
. , 
, . , ,
, , ,
. . 161
.

. 16-1.

List<T>
Dictionary<TKey, TValue>
SortedDictionary<TKey, TValue>
Stack<T>
Queue<T>
LinkedList<T>


ArrayList
Hashtable
SortedList
Stack
Queue

. 
Dictionary SortedDictionary KeyValuePair<TKey, TValue>, 
DictionaryEntry. LinkedList 
LinkedListNode<T>.
Microsoft , 
 T 
T (, TKey TValue). T 
, I (, IComparable).
, , 
, , 
, . FCL
,
. . 162 
.

. 16-2.

IList<T>
IDictionary<TKey, TValue>
ICollection<T>
IEnumerator<T>
IEnumerable<T>
IComparer<T>
IComparable<T>


IList
IDictionary
ICollection
IEnumerator
IEnumerable
IComparer
IComparable

356

IV

: 
. 
. , List<T>
IList<T>, List< Date
Time> IList.
, System.Array, , 
, AsReadOnly, Binary
Search, ConvertAll, Exists, Find, FindAll, FindIndex, FindLast, FindLastIndex, ForEach,
IndexOf, LastIndexOf, Resize, Sort TrueForAll. .

public abstract class Array : ICloneable, IList, ICollection, IEnumerable {


public static void Sort<T>(T[] array);
public static void Sort<T>(T[] array, IComparer<T> comparer);
public static Int32 BinarySearch<T>(T[] array, T value);
public static Int32 BinarySearch<T>(T[] array, T value,
IComparer<T> comparer);
...
}
.

public static void Main() {


// .
Byte[] byteArray = new Byte[] { 5, 1, 4, 2, 3 };
// Byte[].
Array.Sort<Byte>(byteArray);
// Byte[].
Int32 i = Array.BinarySearch<Byte>(byteArray, 1);
Console.WriteLine(i); // "0".
}

Power Collections Wintellect


Microsoft Wintellect Power Collections,
STL
C++ CLR. Power Collections 
. . Web http://Wintellect.com. 
, 
. . 163
Power Collections.

16

357

. 16-3. Power Collections


Wintellect

BigList<T>

T. ,
100

Bag<T>

T.

OrderedBag<T>

T. 

Set<T>

T.

OrderedSet<T>

T.

Deque<T>

. ,
/

OrderedDictionary
<TKey,TValue>

MultiDictionary
<TKey,TValue>

. ,
,

OrderedMultiDictionary
<TKey,TValue>


( ). 


CLR .
Microsoft .
IL, .

.
( C#, Microsoft Visual
Basic .NET ), 

.
IL 
.
JIT, IL, 
, .
,
.

, 
.
, ,
, .

358

IV

IntelliSense Microsoft Visual Studio 



.
, CLR.

.


, CLR
, . 
.  ,
CLR .
(), (), 
.  ,
CLR ( 
).

. 
, . CLR 
. , 
, . 
, CLR , 
. .

using System;
using System.Collections.Generic;
// .
internal sealed class DictionaryStringKey<TValue> :
Dictionary<String, TValue> {
}
public static class Program {
public static void Main() {
Object o = null;
// Dictionary<,> 5.
Type t = typeof(Dictionary<,>);
// ().
o = CreateInstance(t);
Console.WriteLine();
// DictionaryStringKey<> 5.
t = typeof(DictionaryStringKey<>);
// ().
o = CreateInstance(t);
Console.WriteLine();

16

359

// DictionaryStringKey<Guid> .
t = typeof(DictionaryStringKey<Guid>);
// ().
o = CreateInstance(t);
// .
Console.WriteLine("Object type=" + o.GetType());
}
private static Object CreateInstance(Type t) {
Object o = null;
try {
o = Activator.CreateInstance(t);
Console.Write("Created instance of {0}", t.ToString());
}
catch (ArgumentException e) {
Console.WriteLine(e.Message);
}
return o;
}
}
, :

Cannot create an instance of System.Collections.Generic.


Dictionary2[TKey,TValue] because Type.ContainsGenericParameters is true.
Cannot create an instance of DictionaryStringKey1[TValue] because
Type.ContainsGenericParameters is true.
Created instance of DictionaryStringKey1[System.Guid]
Object type=DictionaryStringKey1[System.Guid]
, CreateInstance
Activator ArgumentException. , 
,
.
,
(), , ,
. ,
Dictionary 2, TKey TValue.
DictionaryStringKey 1, TValue.
, CLR 
(. 4). . 
, , List<T>,
List<DateTime> List<String>,
.
(. 8),
. 

360

IV

,  
. , , 
.

internal sealed class GenericTypeThatRequiresAnEnum<T> {


static GenericTypeThatRequiresAnEnum() {
if (!typeof(T).IsEnum) {
throw new ArgumentException("T must be an enumerated type");
}
}
}
CLR

. . ,
 . 
, 
.


, , .
 CLR 
, , .
, List<T> Object, List<String> List<Guid>
Object. , DictionaryStringKey<TValue> 
Dictionary<String, TValue>, DictionaryStringKey<Guid> 
Dictionary<String, Guid>. , 
, ,
, .
, Node .

internal sealed class Node<T> {


public T m_data;
public Node<T> m_next;
public Node(T data) : this(data, null) {
}
public Node(T data, Node<T> next) {
m_data = data; m_next = next;
}
public override String ToString() {
return m_data.ToString() +
((m_next != null) ? m_next.ToString() : null);
}
}
:

16

361

private static void SameDataLinkedList() {


Node<Char> head = new Node<Char>('C');
head = new Node<Char>('B', head);
head = new Node<Char>('A', head);
Console.WriteLine(head.ToString());
}
Node m_next ,
m_data . , 
( ) . ,
Node , 
Char, DateTime, String.
, Node, 
TypedNode ( Node ),
. 
.

internal class Node {


protected Node m_next;
public Node(Node next) {
m_next = next;
}
}
internal sealed class TypedNode<T> : Node {
public T m_data;
public TypedNode(T data) : this(data, null) {
}
public TypedNode(T data, Node next) : base(next) {
m_data = data;
}
public override String ToString() {
return m_data.ToString() +
((m_next != null) ? m_next.ToString() : null);
}
}

. .

private static void DifferentDataLinkedList() {


Node head = new TypedNode<Char>('.');
head = new TypedNode<DateTime>(DateTime.Now, head);
head = new TypedNode<String>("Today is ", head);
Console.WriteLine(head.ToString());
}

362

IV



.
(<) 
(>), . 
,
. 
, :

List<DateTime> dt = new List<DateTime>();


, :

internal sealed class DateTimeList : List<DateTime> {


// !
}
, , (
):

DateTimeList dt = new DateTimeList();



, . 
, .
: , 
:

Boolean sameType = (typeof(List<DateTime>) == typeof(DateTimeList));


sameType false, 
. , ,
, DateTimeList,
List<DateTime>. , List<Date
Time>, DateTimeList, DateTimeList 
List<DateTime>. .
, C#
, . 
using,
:

using DateTimeList = System.Collections.Generic.List<System.DateTime>;


using DateTimeList. 
DateTimeList System.Collections.Generic.List
<System.DateTime>. ,
, 
. sameType 
true.

Boolean sameType = (typeof(List<DateTime>) == typeof(DateTimeList));

16

363


JIT , 
, CLR IL , 
, 
. , , .
: CLR 
+ , (code explosion),

.
, CLR ,
. , 
 ,
CLR + . 
, List<DateTime> (
AppDomain), CLR List<DateTime>
. .
CLR
, 
. , , CLR List<String>,
List<Stream>, String Stream 
. , .
CLR , 
(32 32
64 64 Windows) ,
.
 , CLR 
. , 
. 
(, Int32 UInt32 32 ), CLR
, 
.


,
. CLR
. 
(, IComparable)
.
. CLR 
. 
, 
, . 
.
FCL ( 
System.Collections.Generic):

364

IV

public interface IEnumerator<T> : IDisposable, IEnumerator {


T Current { get; }
}
.
, Triangle Point,
Current Point.

internal sealed class Triangle : IEnumerator<Point> {


private Point[] m_vertices;
// Current IEnumerator<Point> 5 Point.
Point Current { get { ... } }
}
, ,
:

internal sealed class ArrayEnumerator<T> : IEnumerator<T> {


private T[] m_array;
// Current IEnumerator<T> T.
T Current { get { ... } }
}
: ArrayEnumerator T ( T 
, , ArrayEnumerator,
T ). , Current 
T. 14.


CLR 
, . 
,
. 
15, :
Invoke, BeginInvoke EndInvoke. 
, ,
 ,
.
, :

public delegate TReturn CallMe<TReturn, TKey, TValue>(TKey key, TValue value);


, :

public sealed class CallMe<TReturn, TKey, TValue> : MulticastDelegate {


public CallMe(Object object, IntPtr method);
public TReturn Invoke(TKey key, TValue value);
public IAsyncResult BeginInvoke(TKey key, TValue value,
AsyncCallback callback, Object object);
public TReturn EndInvoke(IAsyncResult result);
}

16

365

FCL .
. :

// .
public delegate void Action<T>(T obj);
// .
public delegate Int32 Comparison<T>(T x, T y);
// .
public delegate TOutput Converter<TInput, TOutput>(TInput input);
// , , .
public delegate Boolean Predicate<T>(T obj);
, FCL, 
10:

public delegate void EventHandler<TEventArgs>(


object sender, TEventArgs e) where TEventArgs : EventArgs;
where . 
.



, , ,
.  ,

. CLR , 
,
. ,
, :

internal sealed class GenericType<T> {


private T m_value;
public GenericType(T value) { m_value = value; }
public TOutput Converter<TOutput>() {
TOutput result = (TOutput) Convert.ChangeType(m_value, typeof(TOutput));
return result;
}
}
GenericType  (T),
Converter  (TOutput). 
GenericType, . Converter 
, m_value, 
, . 
.

366

IV

Swap:

private static void Swap<T>(ref T o1, ref T o2) {


T temp = o1;
o1 = o2;
o2 = temp;
}
Swap :

private static void CallingSwap() {


Int32 n1 = 1, n2 = 2;
Console.WriteLine("n1={0}, n2={1}", n1, n2);
Swap<Int32>(ref n1, ref n2);
Console.WriteLine("n1={0}, n2={1}", n1, n2);
String s1 = "Aidan", s2 = "Kristin";
Console.WriteLine("s1={0}, s2={1}", s1, s2);
Swap<String>(ref s1, ref s2);
Console.WriteLine("s1={0}, s2={1}", s1, s2);
}
, out
ref, , ,
out/ref, , , 
. out/reg
8. , Exchange Compare
Exchange Interlocked :

public static class Interlocked {


public static T Exchange<T>(ref T location1, T value) where T: class;
public static T CompareExchange<T>(
ref T location1, T value, T comparand) where T: class;
}


C#
. ,
# (type inference)
. , (
) ,
. :

private static void CallingSwapUsingInference() {


Int32 n1 = 1, n2 = 2;
Swap(ref n1, ref n2); // Swap<Int32>.
String s1 = "Aidan";
Object s2 = "Kristin";
Swap(ref s1, ref s2); // , .
}

16

367

: Swap 
. Swap C# ,
n1 n2 Int32, Swap, Int32.
C# 
, , . 
Swap C# , s1 String, s2 Object (
s2 String). s1 s2 , 
 Swap
: error CS0411: The type arguments for method Program.Swap<T>(ref
T, ref T) cannot be inferred from the usage. Try specifying the type arguments explicitly
( CS0411:  Program.Swap<T>(ref T, ref T) 
. ).
, 
, ,
:

private static void Display(String s) {


Console.WriteLine(s);
}
private static void Display<T>(T o) {
Display(o.ToString()); // Display(String).
}
Display :

Display("Jeff");
Display(123);
Display<String>("Aidan");

// Display(String).
// Display<T>(T).
// Display<T>(T).

Display,
String, Display ( T String). C#
, , 
Display, String. 
Display, String,
Display. , ,
. , 
Display, ToString,
String, .
Display , String. 
,  
, .
, Display,
. Display ToString
, 
Display.

368

IV


C# , , , , 
.
,  .
C# 
, # Microsoft ,
. ,
, # 
, . ,
+ . ,
+, .


C# , 
, ,
. .

private static Boolean MethodTakingAnyType<T>(T o) {


T temp = o;
Console.WriteLine(o.ToString());
Boolean b = temp.Equals(o);
return b;
}
(temp) T,
.
, , , 
, , 
,
, Object (, ToString Equals).
:

private static T Min<T>(T o1, T o2) {


if (o1.CompareTo(o2) < 0) return o1;
return o2;
}
Min o1 CompareTo. 
CompareTo, # 
,
.
: error CS0117: T does not contain a definition for
CompareTo ( CS0117: T CompareTo).
,
, , 
, Object, ! .
, CLR 
(constraints), .

16

369

,
, .
Min, ( ):

public static T Min<T>(T o1, T o2) where T : IComparable<T> {


if (o1.CompareTo(o2) < 0) return o1;
return o2;
}
where C# , T 
IComparable (T).
CompareTo,
IComparable<T>.
, , 
, , 
. , : error
CS0309: The type object must be convertible to System.IComparable<object> in order
to use it as a parameter T in the generic type or method Program.Min<T>(T, T)| (
CS0309: object System.IComparable<object>,
T
Program.Min<T>(T, T)).

private static void CallMin() {


Object o1 = "Jeff", o2 = "Richter";
Object oMin = Min<Object>(o1, o2); // CS0309.
}
, System.Object 
IComparable<Object>. , System.Object 
.
.
.  
, ( Min). CLR
 . 
. .

//
internal
internal
internal

:
sealed class AType {}
sealed class AType<T> {}
sealed class AType<T1, T2> {}

// : AType<T>, .
internal sealed class AType<T> where T : IComparable<T> {}
// : AType<T1, T2>.
internal sealed class AType<T3, T4> {}
internal sealed class AnotherType {
// :
private static void M() {}

370

IV

private static void M<T>() {}


private static void M<T1, T2>() {}
// : M<T>, .
private static void M<T>() where T : IComparable<T> {}
// : M<T1, T2>.
private static void M<T3, T4>() {}
}

, , ,
, . 
, 
, . ,

, ,  
, . 
.

internal class Base {


public virtual void M<T1, T2>()
where T1 : struct
where T2 : class {
}
}
internal sealed class Derived : Base {
public override void M<T3, T4>()
where T3 : EventArgs
// .
where T4 : class
// .
{ }
}
: Error CS0460:
Constraints for override and explicit interface implementation methods are inherited
from the base method so cannot be specified directly ( CS0460: 

). 
M<T3, T4> Derived where, 
. :  ( T1
T3, 2 4), ( ) .
, CLR
. 
: , / 
. .

16

371


 . 
, 
. : System.
Object, System.Array, System.Delegate, System.MulticastDelegate, System.ValueType, System.
Enum System.Void.

,  , ,
. , :

internal sealed class PrimaryConstraintOfStream<T> where T : Stream {


public void M(T stream) {
stream.Close();// OK.
}
}
 T 
Stream ( System.IO), , ,
PrimaryConstraintOfStream,  Stream
(, FileStream). 
, System.Object. ,
System.Object, C# : error CS0702:
Constraint cannot be special class object ( CS0702:
object).
: class struct. class 
,  .
, , 
, :

internal sealed class PrimaryConstraintOfClass<T> where T : class {


public void M() {
T temp = null;// , T .
}
}
temp null , ,
T , 
null. T , 
, 
null.
struct , 
. , 
. CLR System.
Nullable<T> , null 
. ,  Nullable<T>
struct, CLR ,
Nullable<Nullable<T>>. null
18.
,  struct.

372

IV

internal sealed class PrimaryConstraintOfStruct<T> where T : struct {


public static T Factory() {
// ,
// .
return new T();
}
}
T new , 
, T ,
. T ,
class, , 
.



. 
,  , 
. , 
 , (
, ). 
. 14.

. , , 
, 
.  
.
.

private static List<TBase> ConvertIList<T, TBase>(IList<T> list)


where T : TBase {
List<TBase> baseList = new List<TBase>(list.Count);
for (Int32 index = 0; index < list.Count; index++) {
baseList.Add(list[index]);
}
return baseList;
}
ConvertIList , T
 TBase. , 
T, , TBase.
ConvertIList.

private static void CallingConvertIList() {


// List<String> ( IList<String>).
IList<String> ls = new List<String>();
ls.Add("A String");
// IList<String> IList<Object>.
IList<Object> lo = ConvertIList<String, Object>(ls);

16

373

// IList<String> IList<IComparable>.
IList<IComparable> lc = ConvertIList<String, IComparable>(ls);
// IList<String> IList<IComparable<String>>.
IList<IComparable<String>> lcs =
ConvertIList<String, IComparable<String>>(ls);
// IList<String> IList<String>.
IList<String> ls2 = ConvertIList<String, String>(ls);
// IList<String> IList<Exception>.
IList<Exception> le = ConvertIList<String, Exception>(ls);// Error
}
ConvertIList , String 
Object. String Object, 
. ConvertIList 
, String IComparable. String 
IComparable, 
. ConvertIList , String
IComparable<String>. String ICompa
rable<String>, . 
ConvertIList , String .
ConvertIList , String Exception.
String Exception, 
, : error CS0309: The type
string must be converted to System.Exception in order to use it as parameter T in
the generic type or method SomeType.ConvertIList<T,TBase>(System.Collectons.Gene
ric.IList<T> ( CS0309: string System.Excep
tion, T
SomeType.ConvertIList<T,TBase>(System.Collectons.Generic.IList<T>).


 .
, 
, .
: #
struct, .
.
 .

internal sealed class ConstructorConstraint<T> where T : new() {


public static T Factory() {
// ,
//
// ,
// .
return new T();
}
}

374

IV

new T ,
, T 
. , , 
, ,
.
 
, 
. CLR (, , C#)
. Microsoft,
, .


, 

, , .


,
, .

private static void CastingAGenericTypeVariable1<T>(T obj) {


Int32 x = (Int32) obj ; // .
String s = (String) obj; // .
}
, 
. 
, , Object:

private static void CastingAGenericTypeVariable2<T>(T obj) {


Int32 x = (Int32) (Object) obj ;
// .
String s = (String) (Object) obj;
// .
}
, CLR 
InvalidCastException.
as C#.
String ( Int32 ).

private static void CastingAGenericTypeVariable3<T>(T obj) {


String s = obj as String; // .
}


null ,
.

private static void SettingAGenericTypeVariableToNull<T>() {


T temp = null;
// CS0403 Cannot convert null to type parameter 'T'
// because it could be a value type
// ( CS0403 null 5 ,

16

375

// T .)
}
T , , 
null . ,
temp null, .
C# Microsoft ,
. #
default.

private static void SettingAGenericTypeVariableToDefaultValue<T>() {


T temp = default(T); // .
}
default C# JIT
CLR , temp null, T
, temp, .

null
null ==
!= , , .

private static void ComparingAGenericTypeVariableWithNull<T>(T obj) {


if (obj == null) { /* , 5 */ }
}
T , .
obj null.
C# . 
. 
JIT, , if true, 
if . 
!=, JIT 
if ( true), 
if.
, struct, # ,
, null, 
.



,  .

private static void ComparingTwoGenericTypeVariables<T>(T o1, T o2) {


if (o1 == o2) { } // .
}
T , , 
,
, ==. T 
class, , == true,
. :

376

IV

T , operator==,
==. , 
!=.
(Byte, Int32,
Single, Decimal ) # , 
. ,
ComparingTwoGenericTypeVariables struct,
.  ,
. 
, ,
.
, , , , 
.


, , ,
. 5 , C# 
Byte, Int16, Int32, Int64, Decimal . , 
, C# ( +, , * /),
. 
, . 
,
. .

private static T Sum<T>(T num) where T : struct {


T sum = default(T) ;
for (T n = default(T) ; n < num ; n++)
sum += n;
return sum;
}
, : 
struct default(T), sum n
. :
error CS0019: Operator < cannot be applied to operands of type T and T (
CS0019: < T ).
error CS0023: Operator ++ cannot be applied to operand of type T ( CS0023:
++ ).
error CS0019: Operator += cannot be applied to operands of type T and T (
CS0019: += T ).
CLR,
( ) 
. ,
(. 22),
. . 
. , CLR 
Microsoft .

1 7

Microsoft
.NET Framework , (custom
attributes). 
. ,
, !
!. ( 
.)

HTML!, , Notepad.exe.
HTML! , !
. HTML!
, (Web!) ,
, . ,
HTML
.
!
( C#) .
!
, . ,
!
, .
Microsoft ASP.NET Microsoft Windows Communication Foundation.
Windows Communication Foundation !
, () , !
XAML.

. !
!
. .NET Framework (Windows Forms, Web Forms,
Web! XML . .) , !
( ) . !
, .NET Framework, !
.

378

IV


, public, private, static , .
, .
? , ! ,
? , ,
?
,
, !
. !
, Microsoft
, .
,
.
, CLR! !
.
, : !
. !
. !

.
.NET Framework (FCL) !
, . !
.
DllImport CLR,
, DLL!.
Serializable !
, .
AssemblyVersion !
.
Flags ,
, .
C# . C# !
, !
, , . . ,
, , .

using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal sealed class OSVERSIONINFO {
public OSVERSIONINFO() {
OSVersionInfoSize = (UInt32) Marshal.SizeOf(this);
}
public UInt32 OSVersionInfoSize = 0;
public UInt32 MajorVersion
= 0;

17

public UInt32 MinorVersion


public UInt32 BuildNumber
public UInt32 PlatformId

379

= 0;
= 0;
= 0;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]


public String CSDVersion
= null;
}
internal sealed class MyClass {
[DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean GetVersionEx(
[In, Out] OSVERSIONINFO ver);
}
StructLayout OSVERSIONINFO,
MarshalAs CSDVersion, DllImport GetVersionEx, In Out
ver GetVersionEx.
. , Microsoft Visual Basic .NET
(<, >).
CLR ,
. !
TypeDef (, , , !
), MethodDef (), ParamDef, FieldDef, PropertyDef, EventDef, Assem!
blyDef ModuleDef. Assem!
blyRef, ModuleRef, TypeRef MemberRef. , C# !
, ,
, , (, , , !
), , ( ), , ,
, , !.
C# , , !
. . !
, !
( ). ,
, .

using System;
[assembly: SomeAttr]
[module: SomeAttr]

// .
// .

[type: SomeAttr]
internal sealed class SomeType
<[typevar: SomeAttr] T> {

// .

[field: SomeAttr]
public Int32 SomeField = 0;

// .

[return: SomeAttr]
[method: SomeAttr]
public Int32 SomeMethod(

// .
// .

// .

380

IV

[param: SomeAttr]
// .
Int32 SomeParam) { return SomeParam; }
[property: SomeAttr]
public String SomeProp {
[method: SomeAttr]
get { return null; }
}

// .
//  get.

[event: SomeAttr]
[field: SomeAttr]
[method: SomeAttr]

// .
// .
//
// add remove.
public event EventHandler SomeEvent;
}
, , , ,
.
.
(CLS), System.
Attribute. C# CLS! . .NET
Framework SDK
: StructLayoutAttribute, MarshalAsAttribute, DllImportAttribute, InAttribute
OutAttribute. System.Runtime.InteropService,
. !
, System.Attribute,
CLS! .
C# Attribute
, !
. .
, [DllImport(...)] [DllImportAttri
bute(...)].
, .
. ,

. , !
.
. , DllImport !
GetVersionEx:

[DllImport("Kernel32", CharSet=CharSet.Auto, SetLastError=true)]


.
DllImportAttribute
String.
Kernel32. (positional para!
meters) : !
.

17

381

? !
DllImportAttribute !
. , DllImportAttribute !
Kernel32, CharSet
SetLastError CharSet.Auto true. , !
, !
. , !
DllImportAttribute.
, .
, ver GetVersionEx In Out.

. C#
,
. Attribute !
, .
!
:

[Serializable][Flags]
[Serializable, Flags]
[FlagsAttribute, SerializableAttribute]
[FlagsAttribute()][Serializable()]


, System.Attribute, !
. ,
. , Microsoft !
. !
FlagsAttribute:

namespace System {
public class FlagsAttribute : System.Attribute {
public FlagsAttribute() {
}
}
}
: FlagsAttribute Attribute, CLS!
. ,
public,
Attribute. , ,
. FlagsAttribute
.

382

IV

!
. , ! ,
, ,
( ) !
.
, ( )
.
, .

. !
, ,
.
, FlagsAttribute
, !
. . !
, ,
! System.AttributeUsageAttribute:

namespace System {
[AttributeUsage(AttributeTargets.Enum, Inherited = false)]
public class FlagsAttribute : System.Attribute {
public FlagsAttribute() {
}
}
}
AttributeUsageAttribute.
, ! , !
. AttributeUsageAttribute , !
, !
. !
, !
. AttributeUsage ,
Flags .
, ,
AttributeUsageAttribute . FCL:

[Serializable]
[AttributeUsage(AttributeTargets.Class, Inherited=true)]
public sealed class AttributeUsageAttribute : Attribute {
internal static AttributeUsageAttribute Default =
new AttributeUsageAttribute(AttributeTargets.All);
internal Boolean m_allowMultiple = false;
internal AttributeTargets m_attributeTarget = AttributeTargets.All;
internal Boolean m_inherited = true;
// .
public AttributeUsageAttribute(AttributeTargets validOn) {

17

383

m_attributeTarget = validOn;
}
internal AttributeUsageAttribute(AttributeTargets validOn,
Boolean allowMultiple, Boolean inherited) {
m_attributeTarget = validOn;
m_allowMultiple = allowMultiple;
m_inherited = inherited;
}
public Boolean AllowMultiple {
get { return m_allowMultiple; }
set { m_allowMultiple = value; }
}
public Boolean Inherited {
get { return m_inherited; }
set { m_inherited = value; }
}
public AttributeTargets ValidOn {
get { return m_attributeTarget; }
}
}
, AttributeUsageAttribute , !
, ,
. System.AttributeTargets FCL :

[Flags, Serializable]
public enum AttributeTargets {
Assembly
= 0x0001,
Module
= 0x0002,
Class
= 0x0004,
Struct
= 0x0008,
Enum
= 0x0010,
Constructor
= 0x0020,
Method
= 0x0040,
Property
= 0x0080,
Field
= 0x0100,
Event
= 0x0200,
Interface
= 0x0400,
Parameter
= 0x0800,
Delegate
= 0x1000,
ReturnValue
= 0x2000,
GenericParameter = 0x4000,
All
= Assembly
| Module
Constructor | Method
Interface
| Parameter
GenericParameter
}

| Class
| Property
| Delegate

| Struct
| Enum |
| Field
| Event |
| ReturnValue|

384

IV

AttributeUsageAttribute ,

: AllowMultiple Inherited.
!
. , Flags Serializable
. error CS0579: Duplicate Flags
attribute ( CS0579: Flags) !
:

[Flags][Flags]
enum Color {
Red
}

. FCL ConditionalAttribute !
, ( EnvironmentPermissionAttribute, File
IOPermissionAttribute, ReflectionPermissionAttribute, RegistryPermissionAttribute !
), .
AllowMultiple, ,
.
AttributeUsageAttribute Inherited ,
!
. :

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
Inherited=true)]
internal class TastyAttribute : Attribute {
}
[Tasty][Serializable]
internal class BaseType {
[Tasty] protected virtual void DoSomething() { }
}
internal class DerivedType : BaseType {
protected override void DoSomething() { }
}
AnotherType DoSomething Tasty,
. AnotherType , FCL! Seria
lizableAttribute .
.NET Framework , !
, , , , .
, Inherited true !
. , !
.
.

17

385


AttributeUsage, CLR !
, , !
. !
Attribute
UsageAttribute.


/
,
, ,
. , !
, , !
.
,
. !
, Boolean, Char, Byte,
SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, String, Type, Object
. ,
, ,
, ,
CLS.
, !
, , .
, , Type, !
typeof C#, . !
, , Object
Int32, String ( null).
,
.
:

using System;
internal enum Color { Red }
[AttributeUsage(AttributeTargets.All)]
internal sealed class SomeAttribute : Attribute {
public SomeAttribute(String name, Object o, Type[] types) {
// 'name' String.
// 'o'
// ( ).
// 'types' Type
// .
}
}

386

IV

[Some("Jeff", Color.Red, new Type[] { typeof(Math), typeof(Console) })]


internal sealed class SomeType {
}
,
,
.
. , !
,
.
! ,
: , !
, . , ,
, !
. :
, !
, . 1! !
. !
, !
, , 1! !
. !
, .



. , !
,
,
.
12 , Flags
System.Enum ToString Format. !
!, ,
, , Flags. !
, (reflection).
, 22.
Microsoft Format Enum,
:

public static String Format(Type enumType, Object value, String format) {


// FlagsAttribute?
if (enumType.IsDefined(typeof(FlagsAttribute), false)) {
// ; ,
// .
...
} else {

17

387

// ; ,
// .
...
}
...
}
IsDefined Type,
,
FlagsAttribute. IsDefined true, !
FlagsAttribute, Format ,
. IsDefined false, Format
.
, , ,
( !
) . !
!
FCL . !
System.Type IsDefined, .
, ,
. System.Attribute. , CLS!
System.Attribute;
IsDefined, GetCustomAttributes Get
CustomAttribute. . , !
(, , !
, , , , , ,
, ), ,
. , !
. . 17!1.

. 17-1. System.Attribute,
CLS-

IsDefined

true , !
Attribute .
, () !

GetCustomAttributes

, !
,
. ,
!
, .
(), , , !
.
, .
,
AllowMultiple true

388

IV

. 17-1. ()

GetCustomAttribute

, !
. (!
), , ,
.
, null. !
, !
System.Reflection.AmbiguousMatchException.
,
AllowMultiple false

, IsDefined,
. ,
, , ,
, . IsDefined !
,
.
!, GetCustomAttributes GetCustom
Attribute.
, , ,
. !
.
, ,
!
. , , . ,
, !
, .
System.Reflection , !
: Assembly, Module, Enum,
ParameterInfo, MemberInfo, Type, MethodInfo, ConstructorInfo, FieldInfo, EventInfo, Proper
tyInfo *Builder.
IsDefined GetCustomAttributes. System.Attribute
GetCustomAttribute.
GetCustomAttributes, , ,
Object (Object[]), Attribute (Attribute[]). !
, , ,
, CLS. ,
, CLS, .
.NET Framework.
, Attribute, Type MethodInfo
, inherit.
, ,
. !
, , ,
,
Attribute.

17

389

: ! IsDefined, GetCustom
Attribute GetCustomAttributes,
, . ,
, !
, , .
, !
.
, !
. ; !

, .

using System;
using System.Diagnostics;
using System.Reflection;
[assembly: CLSCompliant(true)]
[Serializable]
[DefaultMemberAttribute("Main")]
[DebuggerDisplayAttribute("Richter", Name = "Jeff", Target = typeof(Program))]
public sealed class Program {
[Conditional("Debug")]
[Conditional("Release")]
public void DoSomething() { }
public Program() {
}
[CLSCompliant(true)]
[STAThread]
public static void Main() {
// , .
ShowAttributes(typeof(Program));
// .
MemberInfo[] members = typeof(Program).FindMembers(
MemberTypes.Constructor | MemberTypes.Method,
BindingFlags.DeclaredOnly | BindingFlags.Instance |
BindingFlags.Public | BindingFlags.Static,
Type.FilterName, "*");
foreach (MemberInfo member in members) {
// , .
ShowAttributes(member);
}
}
private static void ShowAttributes(MemberInfo attributeTarget) {
Attribute[] attributes = Attribute.GetCustomAttributes(attributeTarget);

390

IV

Console.WriteLine("Attributes applied to {0}: {1}",


attributeTarget.Name, (attributes.Length == 0 ? "None" : String.Empty));
foreach (Attribute attribute in attributes) {
// .
Console.WriteLine(" {0}", attribute.GetType().ToString());
if (attribute is DefaultMemberAttribute)
Console.WriteLine(" MemberName={0}",
((DefaultMemberAttribute) attribute).MemberName);
if (attribute is ConditionalAttribute)
Console.WriteLine(" ConditionString={0}",
((ConditionalAttribute) attribute).ConditionString);
if (attribute is CLSCompliantAttribute)
Console.WriteLine(" IsCompliant={0}",
((CLSCompliantAttribute) attribute).IsCompliant);
DebuggerDisplayAttribute dda = attribute as DebuggerDisplayAttribute;
if (dda != null) {
Console.WriteLine(" Value={0}, Name={1}, Target={2}",
dda.Value, dda.Name, dda.Target);
}
}
Console.WriteLine();
}
}
, :

Attributes applied to Program:


System.SerializableAttribute
System.Diagnostics.DebuggerDisplayAttribute
Value=Richter, Name=Jeff, Target=Program
System.Reflection.DefaultMemberAttribute
MemberName=Main
Attributes applied to DoSomething:
System.Diagnostics.ConditionalAttribute
ConditionString=Release
System.Diagnostics.ConditionalAttribute
ConditionString=Debug
Attributes applied to Main:
System.STAThreadAttribute
System.CLSCompliantAttribute
IsCompliant=True
Attributes applied to .ctor: None

17

391


, , !
, .
,
. Match
System.Attribute, , !
. !
Attribute.Match Equals, !
. Match
, . :

using System;
[Flags]
internal enum Accounts {
Savings = 0x0001,
Checking = 0x0002,
Brokerage = 0x0004
}
[AttributeUsage(AttributeTargets.Class)]
internal sealed class AccountsAttribute : Attribute {
private Accounts m_accounts;
public AccountsAttribute(Accounts accounts) {
m_accounts = accounts;
}
public override Boolean Match(Object obj) {
// Match
// Attribute, .
// if (!base.Match(obj)) return false;
//
//
//
//
if

'this' null, obj, null,


.
: , ,
Match .
(obj == null) return false;

//
//
//
if

.
: , ,
Match .
(this.GetType() != obj.GetType()) return false;

// obj , .
// : ,
// , .
AccountsAttribute other = (AccountsAttribute) obj;

392

IV

//
//
//
if

, .
, accounts 'this'
accounts other.
((other.m_accounts & m_accounts) != m_accounts)
return false;

return true; // .
}
public override Boolean Equals(Object obj) {
// Equals
// Object, .
// if (!base.Equals(obj)) return false;
//
//
//
//
if

'this' null, obj, null,


.
: , ,
Match .
(obj == null) return false;

//
//
//
if

.
: , ,
Match .
(this.GetType() != obj.GetType()) return false;

// obj , .
// : ,
// , .
AccountsAttribute other = (AccountsAttribute) obj;
//
//
//
if

.
, accounts 'this'
accounts other.
(other.m_accounts != m_accounts)
return false;

return true; // .
}
// GetHashCode, Equals .
public override Int32 GetHashCode() {
return (Int32) m_accounts;
}
}
[Accounts(Accounts.Savings)]
internal sealed class ChildAccount { }
[Accounts(Accounts.Savings | Accounts.Checking | Accounts.Brokerage)]
internal sealed class AdultAccount { }

17

393

public sealed class Program {


public static void Main() {
CanWriteCheck(new ChildAccount());
CanWriteCheck(new AdultAccount());
// ,
// AccountsAttribute.
CanWriteCheck(new Program());
}
private static void CanWriteCheck(Object obj) {
// .
Attribute checking = new AccountsAttribute(Accounts.Checking);
// , .
Attribute validAccounts = Attribute.GetCustomAttribute(
obj.GetType(), typeof(AccountsAttribute), false);
// "Checking",
// , .
if ((validAccounts != null) && checking.Match(validAccounts)) {
Console.WriteLine("{0} types can write checks.", obj.GetType());
} else {
Console.WriteLine("{0} types can NOT write checks.", obj.GetType());
}
}
}
, :

ChildAccount types can NOT write checks.


AdultAccount types can write checks.
Program types can NOT write checks.
, Match,
Match Attribute,
Equals ,
.


,
Attribute

, . ,
, ,
, Attribute. ,
GetCustomAttribute(s) Attribute
!!
, . , CLR

394

IV

( ). , set
,
. ,
.
!
System.Reflection.CustomAttributeData. !
GetCustomAttributes, !
. : !
Assembly, Module, ParameterInfo MemberInfo.
System.Reflection (. 22). !
, !
ReflectionOnlyLoad ( 22) Assembly,
CustomAttributeData. , ReflectionOnly
Load CLR ! , !
.
GetCustomAttributes CustomAttributeData ,
CustomAttributeData IList<CustomAttributeData>.
,
! . CustomAttributeData,
, !
!. , Constructor
, , ConstructorArguments
,
IList<CustomAttributeTypedArgument>, NamedArguments !
, IList<Cus
tomAttributeNamedArgument>. : , !
!
.
, !
CustomAttributeData:

using
using
using
using

System;
System.Diagnostics;
System.Reflection;
System.Collections.Generic;

[assembly: CLSCompliant(true)]
[Serializable]
[DefaultMemberAttribute("Main")]
[DebuggerDisplayAttribute("Richter", Name="Jeff", Target=typeof(Program))]
public sealed class Program {
[Conditional("Debug")]
[Conditional("Release")]
public void DoSomething() { }
public Program() {
}

17

395

[CLSCompliant(true)]
[STAThread]
public static void Main() {
// , .
ShowAttributes(typeof(Program));
// .
MemberInfo[] members = typeof(Program).FindMembers(
MemberTypes.Constructor | MemberTypes.Method,
BindingFlags.DeclaredOnly | BindingFlags.Instance |
BindingFlags.Public | BindingFlags.Static,
Type.FilterName, "*");
foreach (MemberInfo member in members) {
// , .
ShowAttributes(member);
}
}
private static void ShowAttributes(MemberInfo attributeTarget) {
IList<CustomAttributeData> attributes =
CustomAttributeData.GetCustomAttributes(attributeTarget);
Console.WriteLine("Attributes applied to {0}: {1}",
attributeTarget.Name, (attributes.Count == 0 ? "None" : String.Empty));
foreach (CustomAttributeData attribute in attributes) {
// .
Type t = attribute.Constructor.DeclaringType;
Console.WriteLine(" {0}", t.ToString());
Console.WriteLine(" Constructor called={0}", attribute.Constructor);
IList<CustomAttributeTypedArgument> posArgs = attribute.ConstructorArguments;
Console.WriteLine(" Positional arguments passed to constructor:" +
((posArgs.Count == 0) ? " None" : String.Empty));
foreach (CustomAttributeTypedArgument pa in posArgs) {
Console.WriteLine("
Type={0}, Value={1}", pa.ArgumentType, pa.Value);
}
IList<CustomAttributeNamedArgument> namedArgs = attribute.NamedArguments;
Console.WriteLine(" Named arguments set after construction:" +
((namedArgs.Count == 0) ? " None" : String.Empty));
foreach(CustomAttributeNamedArgument na in namedArgs) {
Console.WriteLine(" Name={0}, Type={1}, Value={2}",
na.MemberInfo.Name, na.TypedValue.ArgumentType, na.TypedValue.Value);
}
Console.WriteLine();
}
Console.WriteLine();
}
}

396

IV

, :

Attributes applied to Program:


System.SerializableAttribute
Constructor called=Void .ctor()
Positional arguments passed to constructor: None
Named arguments set after construction: None
System.Diagnostics.DebuggerDisplayAttribute
Constructor called=Void .ctor(System.String)
Positional arguments passed to constructor:
Type=System.String, Value=Richter
Named arguments set after construction:
Name=Name, Type=System.String, Value=Jeff
Name=Target, Type=System.Type, Value=Program
System.Reflection.DefaultMemberAttribute
Constructor called=Void .ctor(System.String)
Positional arguments passed to constructor:
Type=System.String, Value=Main
Named arguments set after construction: None
Attributes applied to DoSomething:
System.Diagnostics.ConditionalAttribute
Constructor called=Void .ctor(System.String)
Positional arguments passed to constructor:
Type=System.String, Value=Release
Named arguments set after construction: None
System.Diagnostics.ConditionalAttribute
Constructor called=Void .ctor(System.String)
Positional arguments passed to constructor:
Type=System.String, Value=Debug
Named arguments set after construction: None
Attributes applied to Main:
System.CLSCompliantAttribute
Constructor called=Void .ctor(Boolean)
Positional arguments passed to constructor:
Type=System.Boolean, Value=True
Named arguments set after construction: None
System.STAThreadAttribute
Constructor called=Void .ctor()
Positional arguments passed to constructor: None
Named arguments set after construction: None
Attributes applied to .ctor: None

17

397


! ,
. !
. !
!
. , NUnit ,
TestFixtureSetUp, Setup, TearDown, TestFixtureTearDown Test, ,
NUnit .
NUnit !
. NUnit
, !
. , !
NUnit !
. , , !
.
, System.Diagnostics.Conditional
Attribute, . :

// #define TEST
#define VERIFY
using System;
using System.Diagnostics;
[Conditional("TEST")][Conditional("VERIFY")]
public sealed class CondAttribute : Attribute {
}
[Cond]
public sealed class Program {
public static void Main() {
Console.WriteLine("CondAttribute is {0}applied to Program type.",
Attribute.IsDefined(typeof(Program),
typeof(CondAttribute)) ? "" : "not ");
}
}
CondAttribute,
, !
TEST VERIFY.
.

1 8

null

, 
null . 
. , ,
. ,
32 , Int32 FCL.
, 
null. . 
Microsoft .NET Framework 
, CLR 
Int32 null.
Microsoft ADO.NET ,
null. , ,
System.Data.SqlTypes , 
null,  
. , SqlDecimal 38
, Decimal 29. 
, SqlString
, String.

Microsoft Language Integrated Query (LINQ)


, null, 
.
: Java java.util.Date ,
null. CLR System.DateTime
null. Java 
Web, CLR,
, Java null,
CLR , .

18

, null

399

Microsoft CLR 
, null (nullable value type). ,
, FCL System.Nullable<T>.
.

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct Nullable<T> where T : struct {
// .
private Boolean hasValue = false; // null.
internal T value = default(T);
// , .
public Nullable(T value) {
this.value = value;
this.hasValue = true;
}
public Boolean HasValue { get { return hasValue; } }
public T Value {
get {
if (!hasValue) {
throw new InvalidOperationException(
"Nullable object must have a value.");
}
return value;
}
}
public T GetValueOrDefault() { return value; }
public T GetValueOrDefault(T defaultValue) {
if (!HasValue) return defaultValue;
return value;
}
public override Boolean Equals(Object other) {
if (!HasValue) return (other == null);
if (other == null) return false;
return value.Equals(other);
}
public override int GetHashCode() {
if (!HasValue) return 0;
return value.GetHashCode();
}
public override string ToString() {
if (!HasValue) return "";
return value.ToString();
}

400

IV

public static implicit operator Nullable<T>(T value) {


return new Nullable<T>(value);
}
public static explicit operator T(Nullable<T> value) {
return value.Value;
}
}
, null.
Nullable<T> , 
. ,
,
. : T Nullable
struct, 
null.
Int32, 
null, :

Nullable<Int32> x = 5;
Nullable<Int32> y = null;
Console.WriteLine("x: HasValue={0}, Value={1}",
x.HasValue, x.Value);
Console.WriteLine("y: HasValue={0}, Value={1}",
y.HasValue, y.GetValueOrDefault());
:

x: HasValue=True, Value=5
y: HasValue=False, Value=0

,
null, C#
C#
x y Nullable<Int32>. 
C# , null,
C# .
, C#
, null. C# 
x y, :

Int32? x = 5;
Int32? y = null;
C# Int32? Nullable<Int32>. C#
. C#
, null, . C# 
, 
null. :

18

, null

401

private static void ConversionsAndCasting() {


// Int32 Nullable<Int32>.
Int32? a = 5;
// 'null' Nullable<Int32>.
Int32? b = null;
// Nullable<Int32> Int32.
Int32 c = (Int32) a;
// ,
// null.
Double? d = 5; // Int32>Double? (d is 5.0 as a double)
Double? e = b; // Int32?>Double? (e is null)
}
C# ,
null. :

private static void Operators() {


Int32? a = 5;
Int32? b = null;
// (+ ++  ! ~)
a++;
// a = 6
b = b; // b = null
// (+  * / % & | ^ << >>)
a = a + 3; // a = 9
b = b * 3; // b = null;
//
if
if
if

(== !=)
(a == null) { /* no */ } else { /* yes */ }
(b == null) { /* yes */ } else { /* no */ }
(a != b)
{ /* yes */ } else { /* no */ }

// (< > <= >=)


if (a < b)
{ /* no */ } else { /* yes */ }
}
C# :
(+, ++, !, ~). null,
null.
(+, , *, /, %, &, |, ^, <<, >>).
null, null.
(==, !=). null, 
. null, .
null, 
.

402

IV

(<>, <=, >=). null, 


false. null,
.
, ,
null, . :

private static Int32? NullableCodeSize(Int32? a, Int32? b) {


return a + b;
}
IL. 
C# IL:

private static Nullable<Int32> NullableCodeSize(


Nullable<Int32> a, Nullable<Int32> b) {
Nullable<Int32> nullable1 = a;
Nullable<Int32> nullable2 = b;
if (!(nullable1.HasValue & nullable2.HasValue)) {
return new Nullable<Int32>();
}
return new Nullable<Int32>(
nullable1.GetValueOrDefault() + nullable2.GetValueOrDefault());
}

null C#
C# , null (nullcoalescing
operator). ?? . 
null, .
null, .
null .
,
, null. ,
null:

private static void NullCoalescingOperator() {


Int32? b = null;
// :
// x = (b.HasValue) ? b.Value : 123
Int32 x = b ?? 123;
Console.WriteLine(x); // "123"
// :
// String temp = GetFilename();
// filename = (temp != null) ? temp : "Untitled";
String filename = GetFilename() ?? "Untitled";
}

18

, null

403

CLR
, null
CLR , 
null. , GetType

, null, CLR. 
, .
CLR.

, null
Nullable<Int32>, 
null. ,
Object;
Nullable<Int32>. , 
null , , Nullable<Int32> 
null. CLR
, null, 
, , null,
.
, Nullable<T> CLR , 
null; , CLR null. 
null, CLR . , Nullable<Int32>
5 , Int32 5. ,
:

// Nullable<T> null T.
Int32? n = null;
Object o = n; // o is null
Console.WriteLine("o is null={0}", o == null); // "True"
n = 5;
o = n; // o Int32
Console.WriteLine("os type={0}", o.GetType()); // "System.Int32"

, null
CLR T T Nullable<T>.
null
Nullable<T>, CLR Nullable<T> null. :

// Int32.
Object o = 5;
// Nullable<Int32> Int32.
Int32? a = (Int32?) o; // a = 5
Int32 b = (Int32) o; // b = 5

404

IV

// , null.
o = null;
// "" Nullable<Int32> Int32.
a = (Int32?) o;
// a = null.
b = (Int32) o;
// NullReferenceException.
, null,
CLR, , . , 
.
:

private static void UnboxingAllocations() {


const Int32 count = 1000000;
// Int32.
Object o = 5;
Int32 numGCs = GC.CollectionCount(0);
for (Int32 x = 0; x < count; x++) {
Int32 unboxed = (Int32) o;
}
Console.WriteLine("Number of GCs={0}", GC.CollectionCount(0)  numGCs);
numGCs = GC.CollectionCount(0);
for (Int32 x = 0; x < count; x++) {
Int32? unboxed = (Int32?) o;
}
Console.WriteLine("Number of GCs={0}", GC.CollectionCount(0)  numGCs);
}
:

Number of GCs=0
Number of GCs=30
,
o Int32, Nullable<Int32>.
30 , 
. 5 , 

. ,
nullable , 
hasValue. 
nullable, CLR Nullable<T>,
hasValue true ,
. 
.

18

, null

405

GetType ,
null
GetType Nullable<T> CLR
T Nullable<T>. :

Int32? x = 5;
// "System.Int32", "System.Nullable<Int32>".
Console.WriteLine(x.GetType());

,
null
n Nullable<Int32> 
IComparable<Int32>. Int32 Nullable<T>
IComparable<Int32>. C# 
, CLR .
.

Int32? n = 5;
Int32 result = ((IComparable) n).CompareTo(5);
Console.WriteLine(result);

//
// .
// 0

CLR ,
,
null. , 
:

Int32 result = ((IComparable) (Int32) n).CompareTo(5); // .

CLR

1 9

,
, (exception handling).
.
, , 
, , !

, . !
, !
. , , ,
! , .
, 
!
: !
, , !
, (, !
) . ,
, ,
. !
, !
. !
.
!
.
, . , !
, .
, !
. , !
.
CLR !
, .
, ,
. !
, , !
. , !

19

409

. !
, , ,
.
, !
. !
, !
. , !
.


API Win32 COM Microsoft !
. !
Win32 false, ! .
false, GetLast
Error. , COM HRESULT.
, 1, , !
, .
Microsoft API Win32 COM
.
.
, ++,
.
,
, , Microsoft !
( , !
, !
).
.
, . ,
, . ,
, !
. !
, ,
. !
. ,
, , ++.
!
, 32! .
, , .
0, ,
, .
, !
! ,
, .
! 32!
. ,

410

CLR

, .
, . ,
, , ,
.
,
,
, . ,
, ,
.
, , :
! . Win32!
, , ,
, , ,
. , ,
, . , CLR
.
, , . !
, , !
,
. ,
. , !
. 32!
Win32 COM ,
, , !
, .
Microsoft .NET Framework ,
32! , .
.
Microsoft ! !
, ,
. , ,
, !
. ,
.


C#
,
. ,
. , !
, .NET Framework !
C#. , .NET
Framework 
(structured exception handling, SEH) Windows. SEH
, Programming Applications for Microsoft Windows,
4 Edition, Microsoft Press, 1999 (Windows : !

19

411

Win32! 64! Windows, 4! .,


.: , .: ! , 2001 .).
C#
. ,
. !
try, catch finally .

private void SomeMethod() {


try {
//
//
}
catch
//
//
//
}
catch
//
//
//
}
catch
//
//

try ,
.
(InvalidOperationException) {
catch ,
InvalidOperationException ( ,
).
(IOException) {
catch ,
IOException ( ,
).
{
catch ,
.

// , ,
// . .
throw;
}
finally {
// finally ,
// , try.
// , .
}
// finally , try
// catch
// .
}

.
, , try finally
try catch. catch, !
. .

412

CLR

try
try ,
. finally.
try , !
.
catch. catch
, , , !
. try catch
finally, try .

catch
catch , !
. try
catch. try , CLR
catch. !
finally ( ). finally,
, .
, catch,
(catch type). C#! !
System.Exception . ,
catch, InvalidOperationException (
), IOException ( ). catch (
) ; !
catch System.Exception,
, catch.
!!
catch Microsoft Visual Studio,
!
$exception.
CLR catch , !
. !
, System.Exception
( ). C#
, catch,
, .
try ( ,
try) , CLR catch , !
.
, CLR
, .
catch, , , !
. .
, , CLR !
finally. , try,

19

413

, catch, !
. : finally, catch,
, catch, !
.
, finally !
catch. ,
. :
, , !
;
, ,
, ;
catch.
, .
, CLR
: catch,
.
, catch !
finally, .
finally ,
finally. finally ,
, catch.
C# . !
,
System.Exception. catch !
( ,
). Exception , , !
.

finally
finally , .
,
try . , try , finally
, :

private void ReadData(String pathname) {


FileStream fs = null;
try {
fs = new FileStream(pathname, FileMode.Open);
// .
...
}
catch (IOException) {
// catch
// IOException ( ).
...
}

414

CLR

finally {
// .
if (fs != null) fs.Close();
}
}
try ,
; , , finally ,
, .
, , finally !
, ,
.
, try finally.
try . finally
, catch, try
finally.
finally, !
, finally. : finally
, ,
try. finally ,
. finally,
CLR ,
finally. CLR
, try ( !
), ( ,
) .

(CLS)
, CLS-
CLR!
, Exception,
CLS. CLR
, !
CLS !, String, Int32, DateTime . . !
C# Exception ,
IL! C++/CLI , Ex!
ception, .
, CLR ,
, , , !
Exception. 2.0 CLR catch !
CLS! .
C# , , !
CLS , C# !
, .
2.0 CLR Microsoft RuntimeWrapped
Exception ( System.Runtime.CompilerServices).

19

415

Exception, CLS!
. RuntimeWrappedException Object ( !
, WrappedException
). CLR 2.0 , CLS,
CLR RuntimeWrappedException !
, !
. , CLR
CLS CLS!. ,
Exception, CLS !
, .
C# ,
Exception, , C# 2.0 !
CLS , !
:

private void SomeMethod() {


try {
// try ,
// .
}
catch (Exception e) {
// C# 2.0 CLS3 .
// C# 2.0 ,
// CLS.
throw; // ().
}
catch {
// C#
// , CLS .
throw; // ().
}
}
, CLR !
, catch ( ), !
.
CLR 2.0, catch C#
, CS1058: A previous catch clause already catches all
exceptions. All non!exceptions thrown will be wrapped in a System.Runtime.Com!
pilerServices.RuntimeWrappedException (CS1058: catch !
. !
System.Runtime.CompilerServices.RuntimeWrappedException).
.NET Framework 2.0:
catch catch, catch !
;
CLR, ,
, catch (Exception) !
RuntimeWrappedException. , CLR !
, CLS, ,

416

CLR

catch, . CLR
RuntimeCompatibilityAttribute:

using System.Runtime.CompilerServices;
[assembly:RuntimeCompatibility(WrapNonExceptionThrows = false)]
. !
!
.
( CLR ) ,
( CLR ).

?
, ,
! , . !
, : ,
. : , !
. , !
. , , Read
.
: , ,
20 , 10!.
, !
. , , ? !
. !
, , !
, . ,
, Read !
.
! !
. , !
. , , !
Read , :
. !
, ! , Read !
, ,
. , !
Read, .
Read
, , !
, , Read
. ,
.

19

417

!
. !
. , !
Read, , !
.
, , ,
. !
!
. !
, !
( , ).
,
, , . !
, !
. !
, FileStream ( ) StringBuilder (
), ( , !
, . .).
. !
Read (), Write (), Flush (),
Append (), Insert (), Remove () . . , !
, ,
.
:

internal class Account {


public static void Transfer(Account from, Account to, Decimal amount) {
...
}
}
Transfer Account Decimal, !
, . ,
Transfer .
: from to
null , from !
to ,
, !
,
.
Transfer !
, , !
. :
void. , Transfer, , !
, ,
.

418

CLR


,
:

, Stack
OverflowException;

, , !
FileNotFoundException;

IL! , !
VerificationException;

JIT! IL!,
OutOfMemoryException.

, ,
.
:

private void InfiniteLoop() {


while (true) ;
}
1000 , 1001
. ? ,
, Abort Thread.
, ,
ThreadAbortException. ,
CLR , Microsoft ASP.NET
Microsoft SQL Server, ,
, .

System.Exception
CLR Int32 String
( ). Microsoft !
, System.Exception
, CLS! !
, System.Exception, !
, CLS!. C# !
CLS! .
System.Exception (. 19!1).

19

419

. 19-1. System.Exception

Message

String


.

,
. !
!
, !
,
!

Data

IDictionary

!!
. , !
,
. , !
,

Source

String

, !

StackTrace

String

,
!
.

TargetSite

MethodBase ,

HelpLink

String

URL (, file://C:\MyApp\
Help.htm#MyExceptionHelp), !

.
,
!

(
!
),

InnerException

Exception

,

.
null.
Exception !
GetBaseException, !


420

CLR

, FCL
.NET Framework Class Library
( System.Exception).
, MSCorLib.dll;
(, !
, . 22).

System.Exception
System.ApplicationException
System.Reflection.InvalidFilterCriteriaException
System.Reflection.TargetException
System.Reflection.TargetInvocationException
System.Reflection.TargetParameterCountException
System.Threading.WaitHandleCannotBeOpenedException
System.IO.IsolatedStorage.IsolatedStorageException
System.Runtime.CompilerServices.RuntimeWrappedException
System.SystemException
System.AccessViolationException
System.AppDomainUnloadedException
System.ArgumentException
System.ArgumentNullException
System.ArgumentOutOfRangeException
System.DuplicateWaitObjectException
System.Text.DecoderFallbackException
System.Text.EncoderFallbackException
System.ArithmeticException
System.DivideByZeroException
System.NotFiniteNumberException
System.OverflowException
System.ArrayTypeMismatchException
System.BadImageFormatException
System.CannotUnloadAppDomainException
System.Collections.Generic.KeyNotFoundException
System.ContextMarshalException
System.DataMisalignedException
System.ExecutionEngineException
System.FormatException
System.Reflection.CustomAttributeFormatException
System.IndexOutOfRangeException
System.InvalidCastException
System.InvalidOperationException
System.ObjectDisposedException
System.InvalidProgramException
System.IO.IOException
System.IO.DirectoryNotFoundException
System.IO.DriveNotFoundException
System.IO.EndOfStreamException
System.IO.FileLoadException
System.IO.FileNotFoundException
System.IO.PathTooLongException

19

System.MemberAccessException
System.FieldAccessException
System.MethodAccessException
System.MissingMemberException
System.MissingFieldException
System.MissingMethodException
System.MulticastNotSupportedException
System.NotImplementedException
System.NotSupportedException
System.PlatformNotSupportedException
System.NullReferenceException
System.OperationCanceledException
System.OutOfMemoryException
System.InsufficientMemoryException
System.RankException
System.Reflection.AmbiguousMatchException
System.Reflection.ReflectionTypeLoadException
System.Resources.MissingManifestResourceException
System.Resources.MissingSatelliteAssemblyException
System.Runtime.InteropServices.ExternalException
System.Runtime.InteropServices.COMException
System.Runtime.InteropServices.SEHException
System.Runtime.InteropServices.InvalidComObjectException
System.Runtime.InteropServices.InvalidOleVariantTypeException
System.Runtime.InteropServices.MarshalDirectiveException
System.Runtime.InteropServices.SafeArrayRankMismatchException
System.Runtime.InteropServices.SafeArrayTypeMismatchException
System.Runtime.Remoting.RemotingException
System.Runtime.Remoting.RemotingTimeoutException
System.Runtime.Remoting.ServerException
System.Runtime.Serialization.SerializationException
System.Security.Cryptography.CryptographicException
System.Security.Cryptography.CryptographicUnexpectedOperationException
System.Security.HostProtectionException
System.Security.Policy.PolicyException
System.Security.Principal.IdentityNotMappedException
System.Security.SecurityException
System.Security.VerificationException
System.Security.XmlSyntaxException
System.StackOverflowException
System.Threading.AbandonedMutexException
System.Threading.SynchronizationLockException
System.Threading.ThreadAbortException
System.Threading.ThreadInterruptedException
System.Threading.ThreadStartException
System.Threading.ThreadStateException
System.TimeoutException
System.TypeInitializationException
System.TypeLoadException
System.DllNotFoundException
System.EntryPointNotFoundException

421

422

CLR

System.TypeUnloadedException
System.UnauthorizedAccessException
System.Security.AccessControl.PrivilegeNotHeldException
Microsoft : System.Exception
, , System.
Exception System.SystemException System.ApplicationException. CLR
, SystemException, ,
, ApplicationException.
catch, CLR!
.
, , : !
Exception (,
IsolatedStorageException), CLR! ApplicationException
( , TargetInvocationException), !
SystemException ( , FormatException). !
, , SystemException ApplicationException !
. Microsoft
, ,
, .


, ,
, .
.
Exception 
? . !
, ,
, , !
. , FCL, !
, FCL , !
. , !
System.Exception. ,
!
, . ,
,
, . ,
System.Exception !
,
.

? !
,
. , !
. !
. !

19

423

,
. !
.
, ,

.
, (
FCL! ),
. !
, , !
, . Microsoft
, FCL,
, .


, , ,
IFormattable IComparable, !
:

internal sealed class SomeType {


public void SomeMethod(Object o) {
if (!((o is IFormattable) && (o is IComparable))) {
throw new MissingInterfaceException(...);
}
// , .
...
}
}
FCL ,
MissingInterfaceException . :
Exception.
. : Exception, ArgumentException ?
, , , !
, .
MissingInterfaceException ArgumentException, !
, ArgumentException,
. , ,
. , , !
, ( ArgumentException), !
, !
(MissingInterfaceException). MissingInterface
Exception , , !
ArgumentException. MissingInterfaceException, !
, ArgumentException, .
!
.

424

CLR

MissingInterfaceException Exception, !
, .
, !
. ,

. ,
,
.

, . , ,
( !
), , !
.
,
, . !
Exception . ,
, .
, !
sealed.
Exception :
( ), !
!
;
, String !
;
, (String) !
, Exception, !
;
, SerializationInfo Streaming
Context, , Exception.
: , Exception
; ,
,
.
, !
.
, ,
Exception. , .
, System.ArgumentException String
ParamName ( , Exception). Argument
Exception ( !
) String, !
ParamName, , !
.
ArgumentException ParamName,
, . ,

19

425

!
, , !
, .
, ,
.
, !
.
,
. ,
[Serializable] ISerializable GetObjectData
( SecurityPermission) , !
SerializationInfo StreamingContext. : ,
, !
. :

using
using
using
using

System;
System.Text;
System.Runtime.Serialization;
System.Security.Permissions;

// DiskFullException.
[Serializable]
public sealed class DiskFullException : Exception, ISerializable {
// .
private String m_diskpath;
// , .
public String DiskPath { get { return m_diskpath; } }
// Message,
// ( ).
public override String Message {
get {
if (m_diskpath == null) return base.Message;
StringBuilder msg = new StringBuilder(base.Message);
msg.AppendFormat(
" (DiskPath={0}){1}",
m_diskpath, Environment.NewLine);
return msg.ToString();
}
}
// .
public DiskFullException() : base() { }
public DiskFullException(String message) : base(message) { }
public DiskFullException(String message, Exception innerException)
: base(message, innerException) { }
// ,
// .

426

CLR

public DiskFullException(String message, String diskpath)


: this(message) { m_diskpath = diskpath; }
public DiskFullException(String message, String diskpath, Exception innerException)
: this(message, innerException) { m_diskpath = diskpath; }
// .
// , .
// .
private DiskFullException(SerializationInfo info, StreamingContext context)
: base(info, context) {
// .
m_diskpath = info.GetString("DiskPath");
}
// ; SecurityPermission ,
// .
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void GetObjectData(
SerializationInfo info, StreamingContext context) {
// .
base.GetObjectData(info, context);
// .
info.AddValue("DiskPath", m_diskpath);
}
}


, ,
. , !
, !
. !
, .
! !
, , !
. !
,
. :
, , !
. ,
. , !
, !
. , ,
. ,
, !
.

19

427

, ,
. ,
, !
. !
, !
. (,
) .


, !
, , !
,
! . . !,
, , , !
. !, ,
,
. , , !
, .
Account Transfer. !
. !
, , !
, null.
, !
. from.
, from .
, !

.
!
, , !
, System.ArgumentException.
, System.ArgumentException, System.Argument
NullException, System.ArgumentOutOfRangeException System.DuplicateWaitObjectException.
, !
, ArgumentException,
ArgumentException. : System.ComponentModel.InvalidEnumArgumentException
ArgumentException, Microsoft
,
System.dll, MSCorLib.dll.
!
, Debug.Assert.
!
. !

, ,

428

CLR

. , !
, !
Debug.Assert, !
. Debug.Assert
;
. !
Debug.Assert,

.
,
! . , !
, .
, , . !
, , , !
, ( String,
). , , !
.
, ,
, !
, !
. , !
. :

#define BADCODE
using System;
using System.Threading;
public static class Program {
public static void Main() {
Int32[] denominators = { 1, 2, 3 };
// .
ThreadPool.QueueUserWorkItem(Divide100By, denominators);
// : Divide100By
// .
Thread.Sleep(50);
// Divide100By.
denominators[2] = 0;
Console.WriteLine("Press <Enter> when you see the results.");
Console.ReadLine();
}
private static void Divide100By(Object o) {

19

429

#if BADCODE
// .
Int32[] denominators = (Int32[]) o;
#else
// , .
// .
Int32[] denominatorsInput = (Int32[]) o;
Int32[] denominators = new Int32[denominatorsInput.Length];
Array.Copy(denominatorsInput, denominators, denominators.Length);
#endif
// , .
for (Int32 index = 0; index < denominators.Length; index++) {
if (denominators[index] == 0)
throw new ArgumentOutOfRangeException("denominators",
String.Format("Index {0} contains 0", index));
}
Console.WriteLine(
"All denominators are valid; DivideByZeroException cant occur.");
// : Main
// .
Thread.Sleep(100);
// , .
for (Int32 index = 0; index < denominators.Length; index++) {
Console.WriteLine("100 / {0} = {1}",
denominators[index], 100 / denominators[index]);
}
}
}
:

All denominators are valid; DivideByZeroException cant occur.


Press <Enter> when you see the results.
100 / 1 = 100
100 / 2 = 50
Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.
at Program.Divide100By(Object o) in C:\...\ArgumentValidation.cs:line 50
at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,
ContextCall
back callback, Object state)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)
, !
. Main
, Divide100By !
DivideByZeroException, , , !

430

CLR

, !
, , BADCODE.
Divide100By ,
. DivideBy
ZeroException . !
BADCODE, :

All denominators are valid; DivideByZeroException cant occur.


Press <Enter> when you see the results.
100 / 1 = 100
100 / 2 = 50
100 / 3 = 33

finally
!, finally ! ,
, !
. finally ,
, !
, finally. finally
!
. , , ( ),
finally:

using System;
using System.IO;
public sealed class SomeType {
private void SomeMethod() {
// .
FileStream fs = new FileStream(@"C:\Data.bin ", FileMode.Open);
try {
// 100 .
Console.WriteLine(100 / fs.ReadByte());
}
finally {
// finally ,
// ,
// (, 0) .
fs.Close();
}
}
}
,
, !
. , C#
lock using. ,
try finally, !

19

431

finally. , C# !
using. ,
.

using System;
using System.IO;
internal sealed class SomeType {
private void SomeMethod() {
// .
using (FileStream fs =
new FileStream(@"C:\Data.bin", FileMode.Open)) {
// 100 .
Console.WriteLine(100 / fs.ReadByte());
}
}
}
using 20, lock
24.


catch.
, , ,
, . , !
. :

try {
// , , ,
// ...
}
catch (Exception) {
...
}
, !
. !
?
: ,
. , !
.
, , , , !
.
, .
, !
. !
, , !
, . ,

432

CLR

, . ( !
.) , !
. ,
, !
, . !
,
, ( !
), .
, !
, ,
. !
, , !
.
,
FailFast System.Environment.
, System.Exception !
catch ,
. (
) System.Exception ,
!
. !
Microsoft FxCop catch (Exception),
throw. .
, , ,
.
(. 23). ,
, , CLR
, . !
EndXxx, !
. EndXxx , ,
. !
, , EndXxx,
.


, , . !
, ,

. ( ):

public String CalculateSpreadsheetCell(Int32 row, Int32 column) {


String result;
try {
result = /* */
}
catch (DivideByZeroException) {

19

433

result = " : ";


}
catch (OverflowException) {
result = " : ";
}
return result;
}

,
.
. 0, CLR
DivideByZeroException. !
,
.
. ,
CLR OverflowException, !
.
, !
, !
. System.Exception ( !
), ,
try ( OutOf
MemoryException StackOverflowException).


, ,
. ,
. 10 (, !
! , !
Serializable). !
, ?
.
, , !
, !
. :

public void SerializeObjectGraph(FileStream fs,


IFormatter formatter, Object rootObj) {
// .
Int64 beforeSerialization = fs.Position;
try {
// .
formatter.Serialize(fs, rootObj);
}

434

CLR

catch { // .
// .
fs.Position = beforeSerialization;
// .
fs.SetLength(fs.Position);
// : finally,
// .
// , ,
// .
throw;
}
}
, , !
. , ,
, .
,
. !
. #
. #
throw, .
,
catch, .
, C# , , !
throw .


!
, :

public Int32 SomeMethod(Int32 x){


try {
return 100 / x;
}
catch (DivideByZeroException e) {
throw new ArgumentOutOfRangeException("x cant be 0", e);
}
}
SomeMethod Int32, !
100 .
x , 0, ArgumentOut
OfRangeException. !
. , x 0, !
. , , x 0,
100. x 0, !
DivideByZeroException, !

19

435

, ArgumentOutOfRangeException. !
,
. , DivideByZeroException !
InnerException ArgumentOutOfRangeException.
, !
, .
, !
. !
,
, .
System.Excep
tion ,
. ,
, !
. , !
, System.Exception ,
.
, , , ,
.
, (
). PhoneBook,
.
:

internal sealed class PhoneBook {


private String m_pathname; // .
// .
public String GetPhoneNumber(String name) {
String phone;
FileStream fs = null;
try {
fs = new FileStream(m_pathname, FileMode.Open);
(Code to read from fs until name is found)
phone = /* */
}
catch (FileNotFoundException e) {
// , ,
// .
throw new NameNotFoundException(name, e);
}
catch (IOException e) {
// , ,
// .
throw new NameNotFoundException(name, e);
}
finally {
if (fs != null) fs.Close();

436

CLR

}
return phone;
}
}
( !
), PhoneBook ,
, . ,
! ,
FileNotFoundException IOException, .
,
. , , !
, . GetPhoneNumber !
!
NameNotFoundException.
,
, NameNotFoundException
. !
FileNotFoundException IOException,
,
PhoneBook.
! ,
. !, , .
, !
. !, . FileNotFound
Exception , StackTrace
, FileStream. , !
NameNot
FoundException, ,
catch, !
. , !
.
, PhoneBook .
PhoneBookPathname, !
,
. ,
, GetPhoneNumber , !
, . : !
GetPhoneNumber,
PhoneBook. , !
PhoneBook.


,
, .

19

437

,
. !
, .
!
( HRESULT, !
. .). , , !
, , !
, .
, !
. !
.
++ , !
. ,
!
. , , !
,
, ,
.
, !
, ,
. , !
, ,
.
. ,
++ ,
,
.
,
. !
!. ,
, , ,
, ,
. !
, ,
, .
, ,
.
, ,
.NET Framework. , , JIT!
x86, ,
JIT! IA64 JIT!!
.NET Compact Framework.
JIT!
Microsoft, .
. !
, , !
, .

438

CLR

.
, !
.
, !
, PerfMon.exe
ActiveX System Monitor, Windows. !
, , !
.NET Framework (. 19!1).

. 191. .NET CLR PerfMon.exe


! ,
. !
. , Micro!
soft , Parse !
Int32 , ,
. Parse , !
.
!
, , Microsoft Int32 , !
TryParse:

public static Boolean TryParse(String s, out Int32 result) { ... }


public static Boolean TryParse(String s, NumberStyles styles,
IFormatProvider, provider, out Int32 result) { ...}
, , ,
Int32 (String).
result. true, result !
32! .
false, result 0, .

19

439

. TryXxx !
false . !
. , TryParse Int32 Argu
mentException, , , , Out
OfMemoryException, TryParse .
, ! !
.
. !
, , , ,
. , ,
, , ,
, .
,
.
, !
,
TryXxx. , !
, , , !
TryXxx, ,
. !
, , !
!
.


, CLR
catch, . catch
, (unhandled
exception). , CLR
.
, ,
.
, , !
.
!
. !
,
, !
. Microsoft
CLR : !
(. 19!2),
Microsoft.
Windows Error Reporting (!
. http://WinQual.Microsoft.com).

440

CLR

. 192. ,
Microsoft
Microsoft !
. !
, , VeriSign ID
( Authenticode). ,
!
.
, Microsoft, !
Shareware Starter Kit (http://msdn.microsoft.com/
vstudio/downloads/starterkits/). Web!
, !
. , ,
, Windows Error Reporting.
,
, !
. CLR,
, , ! !
.
FCL ( . ):
UnhandledException System.AppDomain;
Windows Forms OnThreadException
System.Windows.Forms.NativeWindow,
System.Windows.Forms.Application ThreadException System.Win
dows.Forms.Application;
ASP.NET Web Form Error System.Web.UI.Temp
lateControl. TemplateControl System.Web.UI.Page System.Web.
UI.UserControl. , Error System.
Web.HTTPApplication.
, (ASP.NET Web Services, WSE Web
Services, Windows Communication Foundation Web Services, Windows Presentation
Foundation . .) Microsoft
.

, ,

19

441

Web! Web!. , !
, !
,
. ,
. ,
(, , Microsoft SQL Server),
.

, ,
. , !

.


, System.Exception !
StackTrace. catch , ,
, !
. !
. !
, .
StackTrace Exception . ,
CLR, .
! Exception, !
null. ,
null .
CLR ,
throw.
, CLR . , !
catch StackTrace ,
CLR. CLR , !
, !
, .
! CLR
, CLR
. !
, , , CLR !
:

private void SomeMethod() {


try { ... }
catch (Exception e) {
...
throw e; // CLR , .
// FxCop , .
}
}

442

CLR

( !
throw ) CLR !
.
, CLR :

private void SomeMethod() {


try { ... }
catch (Exception e) {
...
throw;
// ,
// CLR.
// FxCop .
}
}

, , CLR, . !
, , Windows
. , !
, !
Windows Error Reporting !
, , CLR
. ,
,
, .
, , !
:

private void SomeMethod() {


Boolean trySucceeds = false;
try {
...
trySucceeds = true;
}
finally {
if (!trySucceeds) { /* */ }
}
}
, StackTrace, , !
,
catch.
, System.Diagnostics.StackTrace,
, !
.
StackTrace :
StackTrace,
, StackTrace
, Exception.
CLR , , !
StackTrace System.Exception ToString

19

443

System.Diagnostics.StackTrace,
, .

. JIT! !
, !
. ( C#)
/debug. !
, JIT! !
, ,
.
JIT!
System.Diagnostics.DebuggableAttribute, . !
C# . isJIT
OptimizerDisabled true, JIT!!
.
/debug C# true.
System.Runtime.CompilerServices.MethodImplAttribute,
JIT! ,
. !
:

using System;
using System.Runtime.CompilerServices;
internal sealed class SomeType {
[MethodImpl(MethodImplOptions.NoInlining)]
public void SomeMethod() {
...
}
}


Microsoft Visual Studio :
Debug.Exceptions
(. 19!3).

. 193. Exceptions Visual Studio

444

CLR

, Visual Studio.
Common Language Runtime Exceptions, , !
Visual Studio (. 19!4).

. 194. CLR, ,
Exceptions Visual Studio
, , !
System.Exception (. 19!5).

. 195. Exceptions Visual Studio CLR,


System
! Thrown, !
. CLR !
catch.
, .
, ,
, ,
, .
Thrown , ,
!
. , !
, ,
; , .
,
Add. (. 19!6):

19

445

. 196. Visual Studio


Common Language Runtime
Exceptions, . :
System.Exception, ,
CLS, .
, , !
. , .
, !
. ,
,
Exception, Visual Studio.
, !
.
, , !
, Exception, !
, CLS.
, CLS,
.

2 0


( )

, , 

. , 
CLR, .
, , 
.

,

: , , 
, , . . 
, 
. 
. .
1. , , newobj
,
new C#.
2. , 
. 
.
3. , ( 
).
4. , ( ).
5. , .
, ,
.
, , ?

, ,
. ,

20

( )

447

.
( ) (
), .
: Task
Manager ( ) Microsoft Windows, ActiveX System Monitor,
NuMega BoundsChecker Compuware Purify Rational.
.
.
, , 
! .

.
, , ,
, . 4
. , 
, . 
Finalize, Dispose Close, . , 
, ,
. 4.
, , String, Attribute, Delegate Exception, 
, . ,
String,
.
, , 
( ) , 
, , , , ,
. ., . , 
, , ,
. ,
.


CLR
(managed heap).
, 
, . ,
: , 
?. .
.
, 
.
, CLR Microsoft .NET Framework. 
.
CLR 
, 
. . 

448

CLR

, NextObjPtr. , 
. NextObjPtr 
.
IL newobj . ( C#, C++/CLI
Microsoft Visual Basic) new,
newobj IL . newobj,
CLR .
1. , (
).
2. , 
. : 
 SyncBlockIndex. 32 
32 , 
8 , 64 64 ,
16 .
3. , ,
( ).
, ,
, NextObjPtr, 
. ( NextObjPtr
this), IL newobj ( new C#) 
. NextObjPtr
, , 
.
. 201 : , .
, NextObjPtr ( ).

. 201.

,
. ,
.
, , ,
. : 

, . , 
, ! ,
( )
. ,

. 
.

20

( )

449

, , 
, . ,
FileStream BinaryWriter. 
BinaryWriter,
FileStream. , ,
, 
. , ,
, , . 
, , , , 
.
,
, .
, , 
.
, . 

. , , 
, 
. . , .
new, , ,
, .
, , ,
, NextObjPtr.
, .
! .
0. 
, 
.
: , 
. 
0
. , ,
(, 1).

.
, 
, .


, , 
. , . ( 
, new 
OutOfMemoryException.) , 
? , .

450

CLR

(root). , 
.
null. , (
) ,
. ,
. .

internal sealed class SomeType {


private TextWriter m_textWriter;
public SomeType(TextWriter tw) {
m_textWriter = tw;
}
public void WriteBytes(Byte[] bytes) {
for (Int32 x = 0; x < bytes.Length; x++) {
m_textWriter.Write(bytes[x]);
}
}
}
WriteBytes JIT
. , CLR 
86, WriteBytes 
, . 202. ( ,
.)

. 202. , JIT,

20

( )

451

JIT
.
,
, .
WriteBytes , EBX
000000003, ESI 000000005,
ECX 00000000f.
( 000000028). :
EAX 00000001 00000001e. EDI 
Int32, 
. Int32 , JIT
EDI .
WriteBytes ,
. 
, 
. , x86 CLR
ECX EDX.
this, 
ECX. ,
WriteBytes this ECX EBX
, , bytes
EDX ESI .
000000017
WriteBytes, , ,
EBX ( this), ESI ( bytes) ECX ( m_textWriter),
, , , . ,

, .
, ,
.
, , . 
, , ,
, 
. , 
(marking). 
. , , SyncBlockIndex
. , 
, .
. 203 , 
, D F. .
D , ,
H. H .
.
, ,
.
, , 
. . , 

452

CLR

, , 
, ,  
.

. 203.

. , ,
. ,
.
, (compact phase).

, .
,
, .
, 
, , .
,
. ,
, , 
. NextObjPtr
,
. . 204 .

. 204.

20

( )

453

,
. , 
0, 
, . , 
CLR
.

. : , 
, . : 
, . , 
, , ,
. , 
, ,
, . ,
, 
.
,
. : 
( . ).
,
ANSI ++, . , 

. C++ , 
, 
, . CLR
,
.


. 202 , bytes (
ESI) 000000028.
,  Byte, bytes,

0x00000028 ( , ,
). , 
, 
.
. , .

using System;
using System.Threading;
public static class Program {
public static void Main() {
// Timer, TimerCallback
// 2000 .

454

CLR

Timer t = new Timer(TimerCallback, null, 0, 2000);


// , Enter.
Console.ReadLine();
}
private static void TimerCallback(Object o) {
// / .
Console.WriteLine("In TimerCallback: " + DateTime.Now);
// .
GC.Collect();
}
}
, 
. , ,
, TimerCallback !
, , TimerCallback 
2000 . Timer, 
t .  , 
. : TimerCallback
GC.Collect().
,
( ), Timer . 
, Main 
t . ,
Timer, .
, TimerCallback .
, Main, 
, t Timer.
, , ,
t, Quick Watch . ? 
, .

, Microsoft .
JIT IL , 
, , , 
. , JIT
, 
. ,
JIT , , t
Main .
, t , Timer, , 
. Timer , TimerCallback , Console.
ReadLine Main. . 
TimerCallback
.

20

( )

455

,
/debug+ C#. , ,
TimerCallback 
! ?
JIT , , 
, System.Diagnostics.DebuggableAttribute,
isJITOptimizerDisabled true. JIT 
, , ,
.
/debug+ C#
. , /optimize+ #
, 
.
, JIT .
( ),
, JIT 
. , , 

.
, ,
. ,
, . , 
.
Main .

public static void Main() {


// Timer, TimerCallback 2000 .
Timer t = new Timer(TimerCallback, null, 0, 2000);
// , Enter.
Console.ReadLine();
// t ReadLine (
// ).
t = null;
}
( /debug+)
( ) , Timer
Callback . , JIT 
, 
null . 
, JIT t = null;
,  , . 
Main.

public static void Main() {


// Timer, TimerCallback 2000 .
Timer t = new Timer(TimerCallback, null, 0, 2000);

456

CLR

// , Enter.
Console.ReadLine();
// t ReadLine.
// (t Dispose.)
t.Dispose();
}
, ( /debug+) 
( ), , TimerCallback
, . ,
, t, , 
Dispose ( t Dispose
this).



, ,
. , 
. , String, Attribute, Delegate Exception
.
, .
, System.IO.FileStream ( )
. Read Write
. System.Threading.Mutex 
, Windows ( ), 
Mutex.
(finalization) , CLR, 
,
. ,
, , , ,
, .
Finalize. , , Finalize
( ). , Finalize,
,
.
C# Microsoft , Finalize 

(, #
). , Finalize #
(~), .

internal sealed class SomeType {


// Finalize.
~SomeType() {
// Finalize.
}
}

20

( )

457

ILDasm.exe,
, # Finalize
. IL Finalize ,
try, base.Finalize finally.
! , C++, , 
, C# Finalize,
C++. , 
# (destructor).
Finalize , 
C++, , 
.
, , 
C# 
, C++. CLR 
, C# 
.
C# 
(finalizer). C# 
,
(~), 
. ,
.
Finalize Win32 CloseHandle,
. FileStream ,
. FileStream
Finalize, CloseHandle,
. , 
, FileStream . , 
, Finalize,
, , 
, .


CriticalFinalizerObject
System.Runtime.ConstrainedExe
cution CriticalFinalizerObject .

public abstract class CriticalFinalizerObject {


protected CriticalFinalizerObject() { /* */ }
// Finalize.
~CriticalFinalizerObject() { /* */ }
}

458

CLR

, , , CLR 
, CLR
.
, CriticalFinalizer
Object, CLR JIT, 
Finalize . 
, ,
. Finalize
, . CLR
Finalize
, .
, Finalize
, CLR.
CLR Finalize , CriticalFinalizerObject,
Finalize , CriticalFinalizerObject. 
, Finalize,
, CriticalFinalizerObject,
Finalize. , Finalize FileStream
, .
CLR Finalize , CriticalFinalizerObject,
(AppDomain) 
(, Microsoft SQL Server Microsoft ASP.NET). 
, ,
 
.

SafeHandle
Microsoft ,
Windows, , Windows 
(32 32 64
64). , 
System.Runtime.InteropServices SafeHandle 
. ( , .)

public abstract class SafeHandle : CriticalFinalizerObject, IDisposable {


// .
protected IntPtr handle;
protected SafeHandle(IntPtr invalidHandleValue, Boolean ownsHandle) {
this.handle = invalidHandleValue;
// ownsHandle true, ,
// SafeHandle ,
// .
}
protected void SetHandle(IntPtr handle) {
this.handle = handle;
}

20

( )

459

// , Dispose Close.
public void Dispose() { Dispose(true); }
public void Close() { Dispose(true); }
// Dispose.
// !
protected virtual void Dispose(Boolean disposing) {
// , Dispose, .
// , .
// ownsHandle false, .
// , , .
// ReleaseHandle.
// GC.SuppressFinalize(this), Finalize.
// ReleaseHandle true, .
// ReleaseHandleFailed Managed Debugging Assistant (MDA).
}
// Finalize.
// !
~SafeHandle() { Dispose(false); }
// ,
// , .
protected abstract Boolean ReleaseHandle();
public void SetHandleAsInvalid() {
// , , .
// GC.SuppressFinalize(this), Finalize.
}
public Boolean IsClosed {
get {
// , , .
}
}
public abstract Boolean IsInvalid {
get {
// .
// true,
// ( ,
// 0 @1).
}
}
// .
// .
public void
DangerousAddRef(ref Boolean success) {...}
public IntPtrDangerousGetHandle() {...}
public void
DangerousRelease() {...}
}

460

CLR

SafeHandle, ,
CriticalFinalizerObject , CLR
, . , : ,
SafeHandle , 
, ReleaseHandle
IsInvalid  get.
Windows , 
0 1. Microsoft.Win32.SafeHandle
SafeHandleZeroOrMinusOneIsInvald .

public abstract class SafeHandleZeroOrMinusOneIsInvalid : SafeHandle {


protected SafeHandleZeroOrMinusOneIsInvalid(Boolean ownsHandle)
: base(IntPtr.Zero, ownsHandle) {
}
public override Boolean IsInvalid {
get {
if (base.handle == IntPtr.Zero) return true;
if (base.handle == (IntPtr) (@1)) return true;
return false;
}
}
}
: SafeHandleZeroOrMinusOneIsInvalid ,
,
ReleaseHandle. Microsoft .NET Framework
, SafeHandleZeroOrMunusOneIsInvalid SafeFile
Handle SafeWaitHandle. Microsoft.Win32.
SafeHandles. SafeFileHandle.

public sealed class SafeFileHandle : SafeHandleZeroOrMinusOneIsInvalid {


public SafeFileHandle(IntPtr preexistingHandle, Boolean ownsHandle)
: base(ownsHandle) {
base.SetHandle(preexistingHandle);
}
protected override Boolean ReleaseHandle() {
// Windows, .
return Win32Native.CloseHandle(base.handle);
}
}
SafeWaitHandle .

:
, , .
, .NET Framework , 
, , SafeProcess
Handle, SafeThreadHandle, SafeTokenHandle, SafeFileMappingHandle, SafeFileMapView
Handle ( ReleaseHandle Win32 UnmapViewOfFile),

20

( )

461

SafeRegistryHandle ( ReleaseHandle Win32 RegClose


Key), SafeLibraryHandle ( ReleaseHandle Win32 Free
Library), SafeLocalAllocHandle ( ReleaseHandle Win32
LocalFree) .
( ) FCL. 
SafeFileHandle SafeWaitHandle. 
MSCorLib.dll System.dll. Microsoft 
,
. 
, ILDasm.exe IL
,
. , 
.


SafeHandle
, , SafeHandle, 
,
. , SafeHandle 
. , , SafeHandle, 
,
CLR. .

using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
internal static class SomeType {
[DllImport("Kernel32", CharSet=CharSet.Unicode, EntryPoint="CreateEvent")]
// .
private static extern IntPtr CreateEventBad(
IntPtr pSecurityAttributes, Boolean manualReset,
Boolean initialState, String name);
// .
[DllImport("Kernel32", CharSet=CharSet.Unicode, EntryPoint="CreateEvent")]
private static extern SafeWaitHandle CreateEventGood(
IntPtr pSecurityAttributes, Boolean manualReset,
Boolean initialState, String name);
public static void SomeMethod() {
IntPtr handle = CreateEventBad(IntPtr.Zero, false, false, null);
SafeWaitHandle swh = CreateEventGood(IntPtr.Zero, false, false, null);
}
}
, CreateEventBad IntPtr.
.NET Framework, 2.0, SafeHandle ,
IntPtr.

462

CLR

CLR Microsoft , 
. CreateEventBad ( ),
, ThreadAbortException 
handle .
. 
.
2.0 .NET Framework
SafeHandle . ,
CreateEventGood SafeWaitHandle, IntPtr.
CreateEventGood CLR Win32 CreateEvent.
CreateEvent , CLR , SafeWaitHandle
SafeHandle. CLR 
SafeWaitHandle, ,
CreateEvent. SafeWaitHandle 
, Thread
AbortException. 
. , SafeWaitHandle
Finalize, .
, , , SafeHandle, ,
. ,
,
. .
SafeHandle
. SafeHandle , 
. SafeHandle 
, 1. , SafeHandle
, CLR 
.
, CLR 
. , Win32 SetEvent.

[DllImport("Kernel32", ExactSpelling=true)]
private static extern Boolean SetEvent(SafeWaitHandle swh);
SafeWaitHandle CLR

. , .
? 
, SafeHandle, CLR ,
, 
. ,
0 .
, , IntPtr,
SafeHandle,
DangerousAddRef DangerousRelease
SafeHandle. Dangerous
GetHandle.

20

( )

463

, , CriticalHandle,
System.Runtime.InteropServices. ,
SafeHandle, . CriticalHandle

( ). SafeHandle, CriticalHandle 
CriticalHandleMinusOneIsInvalid CriticalHandleZeroOrMinusOneIs
Invalid. Microsoft , 
, ,
. , CriticalHandle,

.



! , 
. , .
. 
,
. ,
Finalize. ,
,
, Finalize, ,
.

, .
, ,
.

internal sealed class GCBeep {


// Finalize.
~GCBeep() {
// .
Console.Beep();
// , ,
// ,
// .
if (!AppDomain.CurrentDomain.IsFinalizingForUnload() &&
!Environment.HasShutdownStarted)
new GCBeep();
}
}
. 
Finalize ,
Beep GCBeep. Finalize GCBeep

464

CLR

. ,
GCBeep.

public static class Program {


public static void Main() {
// GCBeep ,
// , .
new GCBeep();
// 100@ .
for (Int32 x = 0; x < 10000; x++) {
Console.WriteLine(x);
Byte[] b = new Byte[100];
}
}
}
, Finalize , 
. , Finalize
, , 
. .

internal sealed class TempFile {


private String m_filename = null;
private FileStream m_fs;
public TempFile(String filename) {
// .
m_fs = new FileStream(filename, FileMode.Create);
// .
m_filename = filename;
}
// Finalize.
~TempFile() {
// , ,
// ,
// .
if (m_filename != null)
File.Delete(m_filename);
}
}
.

internal sealed class TempFile {


private String m_filename;
private FileStream m_fs;
public TempFile(String filename) {
try {

20

( )

465

// .
m_fs = new FileStream(filename, FileMode.Create);
// .
m_filename = filename;
}
catch {
// @ ,
// Finalize.
// SuppressFinalize . .
GC.SuppressFinalize(this);
// .
throw;
}
}
// Finalize.
~TempFile() {
// ,
// .
File.Delete(m_filename);
}
}
Finalize
.
, ,
, .
, , ,

, . ,
, , 
( . ).
, , , 

.
Fina
lize. Finalize ,
, . CLR
Finalize. 
Finalize, ,
Finalize, . 
, Finalize,
. 
, ,
.

466

CLR

Finalize
Finalize ,
.
0 . 
Finalize, 

.
Collect System.GC
CLR. Microsoft 
, .
Windows 
CLR Win32 CreateMemoryResourceNotification
QueryMemoryResourceNotification. Windows 
, CLR , 
.
CLR , CLR 
, ,
. ( . 21.)
CLR CLR 
( , ).
CLR , , Finalize
. , CLR
, , Windows
.
CLR Finalize. 
, Finalize , 
Finalize . ,
, ,
Finalize, .
Finalize 2
, . , CLR 
Finalize . 
Finalize 40 , CLR 
.
 
, Microsoft .
Finalize . 
CLR, CLR
Finalize, 40 .
GCBeep, . GCBeep
, (. ), 
GCBeep. ,
, , . ,

20

( )

467

GCBeep , 
GCBeep ,
CLR.
, CLR , 
Finalize.
GCBeep, Finalize 
GCBeep IsFinalizingForUnload AppDomain 
HasShutdownStarted System.Environment. IsFinalizingFor
Unload true, Finalize
. HasShutdownStarted true,
Finalize .


, : , 
, Finalize .
, .
, new 
. Finalize,

(finalization list) , 
. , 
Finalize, .
. 205 .
, . C, E, F, I J
Finalize
.

. 205.

468

CLR

System.Object Finalize, CLR 


, , Finalize
System.Object, 
. Finalize Object 
.
, B, E, G, G, I J .
.
,
freachable 
. ,
Finalize. , 
. 206.

. 206. ,
freachable
. 206 , B, G H ,
Finalize. , E, I J,
, Finalize .
CLR , 
Finalize.
,
.
freachable ( ), .
, ,
, Finalize. 
Finalize , 
, . , Finalize 
.
, , CLR 
. , , 
Finalize . , Finalize

20

( )

469

,
.
, 

Finalize .
freachable 
, , . ,
f finalization, :
freachable ,
Finalize. , reachable, ,
. freachable ,
, . , 
freachable, .
, , . ,

freachable, , 
. freachable ,
,
.
, , , 
: .
, CLR freachable, Finalize
.
, ,
, , freachable
. , , .
, , , 
, .
,
( ). . 207 
.

. 207.

470

CLR

:

Finalize , 
, .
: , ,
, .

,
, ,
. , , 
. 
, ,
, .
,
, (dispose pattern). 
, , ,
. , 
,  ,
, .
, Finalize, 
, ,

. , 
Finalize. 
, , System.IO.BinaryWriter.
, .
SafeHandle. Finalize, 
, , , 
( ), .
, SafeHandle, 
, SafeHandle IDisposable.
SafeHandle,
, .

// IDisposable
// , .
public abstract class SafeHandle : CriticalFinalizerObject, IDisposable {
//
// .
// Dispose IDisposable.
public void Dispose() {
// , .
Dispose(true);
}

20

( )

471

// Dispose.
public void Close() {
Dispose(true);
}
// Finalize ,
// .
~SafeHandle() {
// , .
Dispose(false);
}
// , .
// Finalize, Dispose Close.
// ,
// .
// , .
protected virtual void Dispose(Boolean disposing) {
if (disposing) {
// , .
// ,
// , ,
// Finalize .
// SafeHandle .
}
//
//
//
//
//
//
//

/ .
.
, .
ownsHandle false, .
, , .
ReleaseHandle.
GC.SuppressFinalize(this), Finalize.

}
}
.
, . , SafeHandle 
System.IDisposable, FCL :

public interface IDisposable {


void Dispose();
}
, , , 
. ,
Dispose, , 
, . , ,
, . 
 , 

472

CLR

, . Dispose Close, 
, .
, , SafeHandle
Close, Dispose.
, , 
Close, 
. , System.IO.FileStream 
, Close.
(close), (dispose) .
System.Threading.Timer Close,
.

! , 
,
. Dispose , 
.
Dispose, , , ,
. , 
,
Finalize.
, BinaryWriter
. Dispose BinaryWriter, (Dispose) 
Dispose , 
BinaryWriter. BinaryWriter 
, , , 
.
, SafeHandle:
Dispose Close , Finalize
. ,
Dispose, disposing.
, . Safe
Handle , , ,
ReleaseHandle, 
. , ,
Dispose Close ;
,
( ).
,
Dispose/Close . 
,
Dispose/Close, , 
. 
, , 

20

( )

473

Dispose/Close . ,
, , .
Finalize disposing Dispose 
false. Dispose ,
, Finalize. 
, CLR
FileStream Finalize. , FileStream
Finalize, .
, Dispose Close disposing
Dispose true. 
, . Dispose 
, (, FileStream).
, , FileStream
.
, SafeHandle , Dispose, 
, ,
. , SafeHandle , 
Dispose, 
. 
Dispose Close, Finalize.
. 
, Dispose,
, Dispose , 
.
FileStream, ,
Stream, Close IDisposable.Dispose, 
. FileStream Dispose, 
, SafeHandle,
.
! 
. 1 
IDisposable, .
IDisposable ,
, 
,
. , 1 IDisposable
, 
, 
, .
,
Dispose SuppressFinalize GC.
, SafeHandle, Dispose Close,
Finalize, 
. SuppressFinalize 

474

CLR

, , 
this. , CLR 
freachable,
Finalize , 
. , SafeHandle SuppressFinalize, 
.
.

,

, 
, . Safe
Handle System.IO.FileStream.
FileStream ,
. FileStream Win32 CreateFile,
SafeFileHandle,
FileStream. FileStream 
(, Length, Position, CanRead)
(Read, Write, Flush).
, , ,
, . .

using System;
using System.IO;
public static class Program {
public static void Main() {
// .
Byte[] bytesToWrite = new Byte[] { 1, 2, 3, 4, 5 };
// .
FileStream fs = new FileStream("Temp.dat", FileMode.Create);
// .
fs.Write(bytesToWrite, 0, bytesToWrite.Length);
// .
File.Delete("Temp.dat"); // IOException.
}
}
, , , , 
. , Delete File 
Windows , Delete
System.IO.IOException : The process cannot access the file Temp.dat
because it is being used by another process ( 
Temp.dat, ).

20

( )

475

, !
Write Delete, SafeFileHandle FileStream 
Finalize, Delete. 
, 99 100
.
, FileStream ,
,
. .

using System;
using System.IO;
public static class Program {
public static void Main() {
// .
Byte[] bytesToWrite = new Byte[] { 1, 2, 3, 4, 5 };
// .
FileStream fs = new FileStream("Temp.dat", FileMode.Create);
// .
fs.Write(bytesToWrite, 0, bytesToWrite.Length);
// .
fs.Dispose();
// .
File.Delete("Temp.dat"); // T .
}
}
, Dispose 
FileStream. Dispose Dispose,
Boolean, , , Dispose SafeFileHandle.
Win32 CloseHandle, Windows 
. Delete File Windows ,
, .
FileStream Close,
, , .

using System;
using System.IO;
public static class Program {
public static void Main() {
// .
Byte[] bytesToWrite = new Byte[] { 1, 2, 3, 4, 5 };
// .
FileStream fs = new FileStream("Temp.dat", FileMode.Create);

476

CLR

// .
fs.Write(bytesToWrite, 0, bytesToWrite.Length);
// .
fs.Close();
// .
File.Delete("Temp.dat"); // .
}
}
, Close 
,
.
, Dispose Close
. 
, . , 
. Write
. , 
, Write 
System.ObjectDisposedException : Cannot access a closed file (
).

using System;
using System.IO;
public static class Program {
public static void Main() {
// .
Byte[] bytesToWrite = new Byte[] { 1, 2, 3, 4, 5 };
// .
FileStream fs = new FileStream("Temp.dat", FileMode.Create);
// .
fs.Write(bytesToWrite, 0, bytesToWrite.Length);
// .
fs.Close();
// .
// ObjectDisposedException.
fs.Write(bytesToWrite, 0, bytesToWrite.Length);
// .
File.Delete("Temp.dat");
}
}

20

( )

477

, , FileStream,
; 
.
! , 
, ,
System.ObjectDisposedException,
. Dispose Close
ObjectDisposedException 
.

! 
Dispose Close. CLR
, . ,
, .
Dispose Close, , ,
. 
,
.
, , .
,
( ),
. , Dispose
Close, ,  , 
ObjectDisposedException.
Dispose Close , ,
(
), ,
,
.

using C#
Dispose
Close. ,
finally, 
. .

using System;
using System.IO;
public static class Program {
public static void Main() {
// .
Byte[] bytesToWrite = new Byte[] { 1, 2, 3, 4, 5 };

478

CLR

// .
FileStream fs = new FileStream("Temp.dat", FileMode.Create);
try {
// .
fs.Write(bytesToWrite, 0, bytesToWrite.Length);
}
finally {
// .
if (fs != null)
fs.Dispose();
}
// .
File.Delete("Temp.dat");
}
}
;
. , C# using, 
, ,
. 
using.

using System;
using System.IO;
public static class Program {
public static void Main() {
// .
Byte[] bytesToWrite = new Byte[] { 1, 2, 3, 4, 5 };
// .
using (FileStream fs = new FileStream("Temp.dat", FileMode.Create)) {
// .
fs.Write(bytesToWrite, 0, bytesToWrite.Length);
}
// .
File.Delete("Temp.dat");
}
}
using 
. , 
using. 
try finally. finally 
, IDisposable,
Dispose. , using
, IDisposable.

20

( )

479

C# using 
, 
.
using , 
IDisposable.
, 
. , .
Mutex IDisposable, Dispose
. .

, Mutex.
MutexLock, Main
MutexLock.

using System;
using System.Threading;
// .
// , , ;
// .
internal struct MutexLock : IDisposable {
private Mutex m_mutex;
// .
public MutexLock(Mutex m) {
m_mutex = m;
m_mutex.WaitOne();
}
// Dispose .
public void Dispose() {
m_mutex.ReleaseMutex();
}
}
public static class Program {
// , MutexLock.
public static void Main() {
// @.
Mutex m = new Mutex();
// , .
using (new MutexLock(m)) {
// .
}
}
}

480

CLR

! ,
IDisposable, MutexLock, .

. ,
IDisposable, 
. ,
. ,
, . 
, 
, , , 
, 
. 
(, MutexLock),
( ) , 
,
Dispose .


System.IO.FileStream 
. 
. .
FileStream
System.IO.StreamWriter, .

FileStream fs = new FileStream("DataFile.dat", FileMode.Create);


StreamWriter sw = new StreamWriter(fs);
sw.Write("Hi there");
// Close .
sw.Close();
// : StreamWriter.Close FileStream.
// FileStream .
: StreamWriter
Stream, FileStream 
. StreamWriter
Stream. StreamWriter 
. StreamWriter 
Stream.
BinaryWriter Dispose
Close ( StreamWriter 
, using C#). 
: BinaryWriter Stream 
. FileStream 
Win32 CloseHandle.

20

( )

481

Dispose Close File


Stream : BinaryWriter .
 , FileStream ,
, .
, , , Dispose Close?
, 
, . Finalize 
. FileStream , .
StreamWriter
, . , StreamWriter
, .
Microsoft? 
, 
, 
. Microsoft : StreamWriter
Finalize, 
FileStream. , ,
StreamWriter, . Microsoft 
, ,
Close Dispose.
.NET 2.0
Managed Debugging Assistants (MDA). , .NET Framework

MDA. 
. MDA ,
StreamWriter ,
. MDA Visual Studio,
Debug/Exceptions. Exceptions 
Managed Debugging Assistants,
StreamWriterBufferedDataLost
Thrown, Visual Studio
StreamWriter.



CLR GC (GC
handle table),
.
.
, . 
System.Runtime.
InteropServices.GCHandle, . GC
, 

482

CLR

GCHandle SecurityPermission Unmana


gedCode.

// System.Runtime.InteropServices.
public struct GCHandle {
// , .
public static GCHandle Alloc(object value);
public static GCHandle Alloc(object value, GCHandleType type);
// , GCHandle IntPtr.
public static explicit operator IntPtr(GCHandle value);
public static IntPtr ToIntPtr(GCHandle value);
// , IntPtr GCHandle.
public static explicit operator GCHandle(IntPtr value);
public static GCHandle FromIntPtr(IntPtr value);
// , GCHandle.
public static Boolean operator ==(GCHandle a, GCHandle b);
public static Boolean operator !=(GCHandle a, GCHandle b);
// ,
// ( 0).
public void Free();
// , / .
public object Target { get; set; }
// , true, 0.
public Boolean IsAllocated { get; }
// Pinned .
public IntPtr AddrOfPinnedObject();
public override Int32 GetHashCode();
public override Boolean Equals(object o);
}
, 
Alloc GCHandle,
, GCHandleType , /
. GCHandleType .

public enum GCHandleType {


Weak = 0, // .
WeakTrackResurrection = 1 // .
Normal = 2, // .
Pinned = 3 // .
}
, .

20

( )

483

Weak , :
, ,
. , Finalize ,
,  .
WeakTrackResurrection
, : , ,
. , Finalize ( 
) , , 
.
Normal ,
, 
(), . ,
, (). Alloc,
GCHandleType, , GCHandleType.Normal .
Pinned ,
, 
(), . ,
, (). ,
.
, , 
.
Alloc GCHandle 
GC ,
, Alloc. , 
GCHandleType. Alloc GCHandle. GCHand
le , , IntPtr,
.
GC GCHandle
Free ( , 
IntPtr ).
GC.
1. (
). GC, c 
Normal Pinned (
, ).
2. GC
Weak. , 
()
null.
3. . 
,
freachable.
, .
4. GC
WeakTrackResurrection. 
( ,

484

CLR

freachable), (
), null.
5. , , 
. ,
, ,
. Pinned ( 
), , , .
, ,
. Normal Pinned, .
.
Normal ,
,
, .
,
, 
. , Alloc
GCHandle Normal.
GCHandle IntPtr, IntPtr
. , 
IntPtr GCHandle,
Target, ( ) .
,
Free GCHandle, 
( , ).
, 
, .
,
. Pinned
.
String Win32. String
Pinned, 
,
. String , 
, 
String, .
CLR P/Invoke CLR 
Pinned ,
. GCHandle
Pinned  .
GCHandle 
. ,
.
.
, , 
. Alloc
GCHandle,  Pinned.

20

( )

485

GCHandle AddrOfPinnedObject.
IntPtr Pinned 
. ,
.
, 
Pinned.  
Free GCHandle, 
. 
, . 
.
: Weak WeakTrackResurrection.
,
. Weak 
,
. , Fax,
, MailManager .
Fax , .
, Fax , MailManager 
.
. ,
, , , 
.   
. Weak WeakTrackResurrection.
. Fax
MailManager ,
, Fax. MailManager Alloc 
GCHandle  Weak. MailManager
GCHandle , 
. MailManager 
,  Fax, 
, Fax.
MailManager Fax ,
GCHandle 
Target. Target null, Fax ,
MailManager GCHandle,
Free .
Target , Fax , 
Target ,
Fax;  Fax 
. MailManager 
, Fax .
, Fax 
.
, Weak WeakTrack
Resurrection , CLR , . 
, WeakTrack
Resurrection.

486

CLR

, .NET Framework
(weak reference dele
gate), . 
CLR Microsoft, , ,
.
GCHanlde , 
System WeakReference.
 GCHandle: 
Alloc GCHandle, Target
Target GCHandle, Finalize
Free GCHandle. ,
WeakReference,
. GCHandle,
GCHandleType Normal Pinned.
WeakReferences , , , 
, GCHandle. , Weak
Reference ( ), 
GCHandle ,
Finalize.
WeakReference 
.

using System;
using System.Collections.Generic;
public static class Program {
public static void Main() {
// MailManager.
MailManager mm = new MailManager();
// Fax.
Fax f = new Fax(mm);
// , Fax
// .
mm.SimulateNewMail();
// .
GC.Collect();
// , Fax .
mm.SimulateNewMail();
}
}
internal sealed class MailManager {
// .
private List<WeakReference> m_NewMailCallbacks = new List<WeakReference>();

20

( )

487

// , .
public event EventHandler NewMail {
add {
lock (m_NewMailCallbacks) {
// (WeakReference)
// .
m_NewMailCallbacks.Add(new WeakReference(value));
}
}
remove {
lock (m_NewMailCallbacks) {
//
// .
for (Int32 n = 0; n < m_NewMailCallbacks.Count; n++) {
// (WeakReference) .
WeakReference wr = m_NewMailCallbacks[n];
// .
EventHandler eh = (EventHandler) wr.Target;
if (eh == null) {
// .
// .
m_NewMailCallbacks.RemoveAt(n);
n;
// .
continue; // .
}
// .
// ?
if ((eh.Target == value.Target) && (eh.Method == value.Method)) {
// , . .
m_NewMailCallbacks.RemoveAt(n);
break;
}
}
}
}
}
// , .
public void SimulateNewMail() {
Console.WriteLine ("About to raise the NewMail event");
OnNewMail(EventArgs.Empty);
}
// NewMail.
private void OnNewMail(EventArgs e) {
lock (m_NewMailCallbacks) {

488

CLR

// .
for (Int32 n = 0; n < m_NewMailCallbacks.Count; n++) {
// WeakReference .
WeakReference wr = m_NewMailCallbacks[n];
// .
EventHandler eh = (EventHandler)wr.Target;
if (eh == null) {
// .
// .
m_NewMailCallbacks.RemoveAt(n);
n;0
// .
} else {
// .
// .
eh(this, e);
}
}
}
}
}
internal sealed class Fax {
//
// NewMail MailManager.
public Fax(MailManager mm) {
mm.NewMail += GotMail;
}
// NewMail.
public void GotMail(Object sender, EventArgs e) {
// , , .
Console.WriteLine("In Fax.GotMail");
}
}
.

About to raise the NewMail event


In Fax.GotMail
About to raise the NewMail event
! ,
, . 
: 
, , .
,
, , , ,

20

( )

489

, .
. ,
, ,
, .
, ,
. , 
, 0 , 
256 .
, , 
.
,

. ,
, , 
, ,
. CLR , 
.
Win32
GlobalMemoryStatusEx dwMemoryLoad 
MEMORYSTATUSEX. 80, 

, , 
.

: , , ,
, ,
Finalize, Finalize
. , : , ,
, . 
(resurrection).
Finalize 
. freachable,
. ,
Finalize . Finalize
,
, freachable,
.
, Finalize ,
, ?

internal sealed class SomeType {


~SomeType() {
Program.s_ObjHolder = this;
}
}

490

CLR

public static class Program {


public static Object s_ObjHolder;
...
}

// null.

Finalize SomeType
. 
, .
, , 
. , SomeType
, , ,
. ,
Finalize .
( ), ,
.
, 
. ,
. Finalize this
, .
Finalize
. , GC
ReRegisterForFinalize, .
, Finalize SomeType,
.

internal sealed class SomeType {


~SomeType() {
Program.s_ObjHolder = this;
GC.ReRegisterForFinalize(this);
}
}
Finalize ,
. ReRegisterForFinalize,
(this) . ,
( null),
freachable, 
Finalize . , , 
, ,
ReRegisterForFinalize, ,
!
, ,
, , .
Finalize , ,
.

20

( )

491

, ReRegisterFor
Finalize , Finalize
, ReRegisterFor
Finalize .
, 
freachable,
Finalize.

, 
CLR,
. (generational garbage collec
tor) [ (ephemeral garbage collec
tor), ] 
:
, ;
, ;
, .

, 
. 
.
. ,
0. ,
0 ,
. . 208 ,
().
.

. 208. :
0,
CLR 0, 
256 ( ).
0 ,
. , 256 . 
F . ,
E , D, 
B. , 0 256
 , 
(L2) ,

492

CLR

. , (, D), 1.
1 .
(. 209).

. 209. :
0 1, 0
0 . ,
0. . 2010 ,
FK. 
B, H J ,
.

. 2010. 0 , 1
, L
0 256 , .
, .
, CLR 
0. CLR 1, 2 .
, , 
1. 1 2 , 
0. , 
. 0, ,
, .
1,
.
, 1
. 
. 
, 
, .
, , .
, 
JIT,
. , (
) .
, ,
0.

20

( )

493

, Microsoft, ,
0 1 . Microsoft 
, , 
.
, ,
, . ,
1 . 
, 1,
. , 1
. 1 ,
. (. 2011).

. 2011. :
0 1 ( ),
0
, 0, ,
1. 1, , 
, ,
. 0 ,
. , 
LO. G, L
M, . (. 2012).

. 2012. 0 ,
1
, P 0
, .
1 2 , 
0,
1 (B G). (. 2013).

. 2013. :
0 1 ( );
0

494

CLR

. 2013 , 1 , . ,
1 , 
2 . (
) PS, 
0 (. 2014).

. 2014. 0, 1

, 0
. ,
, , . 
0 , 
1 ( ).
1 0. 
, . 2015.

. 2015. :
1 2,
0 1, 0
0 1,
1 2. ,
0 : .
2 , . 
, 1 , 

0.
: 0, 1 2. 3
. CLR
. , 0
256 , 1 2 . 2 
10 . , 
. , 
. ,
: , ;
, .
CLR , 
. ,
,

20

( )

495

0 .
0.
, 0
, 0 256 128 .
, 
, .
, 0 , 
NextObjPtr 
0, .
!
, 
, .
, , 
, .
,
Windows Forms, ASP.NET Web Forms Web XML.
ASP.NET , 
,
, . ,
, .
, ASP.NET
. 
, 
.
.
, 
. 
, 
. , ,
, , 
.
, 0
, , 
. 0, 
512 . ,
. ,
, , 
OutOfMemoryException.
,
0, 1 2.
,
.
, 
. ,
, !

496

CLR



, ,
, . 
. , 
, HBITMAP (4 8
). CLR 
( ). ,
, 
. GC
:

public static void AddMemoryPressure(Int64 bytesAllocated);


public static void RemoveMemoryPressure(Int64 bytesAllocated);
, 
,
. ,
, .
. Windows
.
, . , CLR 
( 
). , ,
, , 
. System.Runtime.InteropServices 
HandleCollector:

public sealed class HandleCollector {


public HandleCollector(String name, Int32 initialThreshold);
public HandleCollector(String name, Int32 initialThreshold,
Int32 maximumThreshold);
public void Add();
public void Remove();
public
public
public
public

Int32 Count { get; }


Int32 InitialThreshold { get; }
Int32 MaximumThreshold { get; }
String Name { get; }

}
, 
, , 
, . 
 ,
, .

20

( )

497

GC.AddMemoryPressure HandleCollector.Add 
GC.Collect 
0 . 
, 
.

. ,
. 
, .

HandleCollector.

using System;
using System.Runtime.InteropServices;
public static class Program {
public static void Main() {
// 0 .
MemoryPressureDemo(0);
// 10 .
MemoryPressureDemo(10 * 1024 * 1024);
// .
HandleCollectorDemo();
}
private static void MemoryPressureDemo(Int32 size) {
Console.WriteLine();
Console.WriteLine("MemoryPressureDemo, size={0}", size);
// .
for (Int32 count = 0; count < 15; count++) {
new BigNativeResource(size);
}
//
// .
GC.Collect();
GC.WaitForPendingFinalizers();
}
private sealed class BigNativeResource {
private Int32 m_size;
public BigNativeResource(Int32 size) {
m_size = size;
if (m_size > 0) {
// , .
GC.AddMemoryPressure(m_size);

498

CLR

}
Console.WriteLine("BigNativeResource create.");
}
~BigNativeResource() {
if (m_size > 0) {
// , .
GC.RemoveMemoryPressure(m_size);
}
Console.WriteLine("BigNativeResource destroy.");
}
}
private static void HandleCollectorDemo() {
Console.WriteLine();
Console.WriteLine("HandleCollectorDemo");
for (Int32 count = 0; count < 10; count++) {
new LimitedResource();
}
//
// .
GC.Collect();
GC.WaitForPendingFinalizers();
}
private sealed class LimitedResource {
// HandleCollector
// ,
// .
private static HandleCollector s_hc = new HandleCollector("LimitedResource", 2);
public LimitedResource() {
// HandleCollector,
// LimitedResource.
s_hc.Add();
Console.WriteLine("LimitedResource create. Count={0}", s_hc.Count);
}
~LimitedResource() {
// HandleCollector, LimitedResource
// .
s_hc.Remove();
Console.WriteLine("LimitedResource destroy. Count={0}", s_hc.Count);
}
}
}
:

MemoryPressureDemo, size=0
BigNativeResource create.

20

BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource

( )

create.
create.
create.
create.
create.
create.
create.
create.
create.
create.
create.
create.
create.
create.
destroy.
destroy.
destroy.
destroy.
destroy.
destroy.
destroy.
destroy.
destroy.
destroy.
destroy.
destroy.
destroy.
destroy.
destroy.

MemoryPressureDemo, size=10485760
BigNativeResource create.
BigNativeResource create.
BigNativeResource create.
BigNativeResource create.
BigNativeResource create.
BigNativeResource create.
BigNativeResource create.
BigNativeResource create.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource create.
BigNativeResource create.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource create.

499

500

BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource

CLR

create.
create.
destroy.
destroy.
create.
create.
destroy.
destroy.
destroy.
destroy.

HandleCollectorDemo
LimitedResource create.
LimitedResource create.
LimitedResource create.
LimitedResource destroy.
LimitedResource destroy.
LimitedResource destroy.
LimitedResource create.
LimitedResource create.
LimitedResource destroy.
LimitedResource create.
LimitedResource create.
LimitedResource destroy.
LimitedResource destroy.
LimitedResource destroy.
LimitedResource create.
LimitedResource create.
LimitedResource destroy.
LimitedResource create.
LimitedResource destroy.
LimitedResource destroy.

Count=1
Count=2
Count=3
Count=3
Count=2
Count=1
Count=1
Count=2
Count=2
Count=2
Count=3
Count=3
Count=2
Count=1
Count=1
Count=2
Count=2
Count=2
Count=1
Count=0

,

, 
, .
, CLR 
OutOfMemoryException. 
.
.
System.Runtime MemoryFailPoint,
,
:

public sealed class MemoryFailPoint : CriticalFinalizerObject, IDisposable {


public MemoryFailPoint(Int32 sizeInMegabytes);
~MemoryFailPoint();

20

( )

501

public void Dispose();


}
. 
, ( ), 
( , 
). ,
.
1. 
,
? , ,
MemoryFailPoint.
2. , ,
.
3.  , 
.
, InsufficientMemory
Exception.
4.  
, InsufficientMemoryException.
5. 
, 
, Memory
FailPoint. ,

, ( 
, ).
MemoryFailPoint InsufficientMemory
Exception,
( ), 
OutOfMemoryException . , 
InsufficientMemoryException OutOfMemoryException.
! MemoryFailPoint 
, 
, . , 
. , 

. MemoryFailPoint , 
, 
. 
.
Dispose 
MemoryFailPoint. Dispose ( 
) Memory
FailPoint. MemoryFailPoint.

502

CLR

using System;
using System.Runtime;
public static class Program {
public static void Main() {
try {
// 1,5 .
using (MemoryFailPoint mfp = new MemoryFailPoint(1500)) {
// , .
} // Dispose 1,5 .
}
catch (InsufficientMemoryException e) {
// .
Console.WriteLine(e);
}
}
}


System.GC .
, , 
, GC.MaxGeneration.
2.
,
:

void GC.Collect(Int32 Generation)


void GC.Collect()
( ), 
. 0 
GC.MaxGeneration . 0, 
0, 1 0 1, 2
0, 1 2. Collect, , 
, 
:

GC.Collect(GC.MaxGeneration);
Collect: 

, . 

CLR . 
.
, Collect, 
, .

20

( )

503

Collect , 
, , , .
, 

. Web 
Windows Form, 
. Collect, 
, Collect, .
GC WaitForPendingFinalizers,
, ,
freachable, , Finalize . 
, , ,
.

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
, , 
. , , 
, . Collect ,
Finalize.
WaitForPendingFinalizers
Finalize. WaitForPendingFinalizers ,
. Collect
, ,
.
, GC , ,
:

Int32 GetGeneration(Object obj)


Int32 GetGeneration(WeakReference wr)
GetGeneration ,
WeakReference.
0 GC.MaxGeneration .
, 
GC.

using System;
internal sealed class GenObj {
~GenObj() {
Console.WriteLine("In Finalize method");
}
}
public static class Program {
public static void Main() {
Console.WriteLine("Maximum generations: " + GC.MaxGeneration);

504

CLR

// GenObj .
Object o = new GenObj();
// , 0.
Console.WriteLine("Gen " + GC.GetGeneration(o)); // 0.
// .
GC.Collect();
Console.WriteLine("Gen " + GC.GetGeneration(o)); // 1.
GC.Collect();
Console.WriteLine("Gen " + GC.GetGeneration(o)); // 2.
GC.Collect();
Console.WriteLine("Gen " + GC.GetGeneration(o)); // 2 ( ).
o = null; // .
Console.WriteLine("Collecting Gen 0");
GC.Collect(0);
// 0.
GC.WaitForPendingFinalizers(); // Finalize .
Console.WriteLine("Collecting Gens 0, and 1");
GC.Collect(1);
// 0 1.
GC.WaitForPendingFinalizers(); // Finalize .
Console.WriteLine("Collecting Gens 0, 1, and 2");
GC.Collect(2);
// , Collect().
GC.WaitForPendingFinalizers(); // Finalize .
}
}
.

Maximum generations: 2
Gen 0
Gen 1
Gen 2
Gen 2
Collecting Gen 0
Collecting Gens 0, and 1
Collecting Gens 0, 1, and 2
In Finalize method



, ,
. ,


20

( )

505

. 
,
( ),
, .
, , ,
. CLR ,
, 
, 
. , 
Microsoft ,
. Microsoft ,
.
, CLR 
, ,
, , . CLR
, JIT
, , .
, 
, , (safe point), ,
. 
, CLR .
CLR ,
, CLR. 
.
, .
, ,
CLR
250 , 
. , . 
CLR , . , CLR 
, 
. CLR 
, .
, 
. ,
. , 
.
. CLR 
, , ,
, .
, ,
, . , 
, , ,
, Pinned.
,
.

506

CLR

, CLR , , 
JIT, , 
. , JIT
,
. , JIT, 
, ,
. ,
, , JIT,
, .
(, ) 
, 
.


0 
.
, .


 (, ASP.NET Microsoft SQL Server)
CLR 
. 
.
, 
. 
. , 
. ,
:
,
.
CLR ,
( . 2 3), gcServer
, .

<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
CLR, 
, IsServerGC GCSettings.

using System;
using System.Runtime; // GCSettings .
public static class Program {
public static void Main() {

20

( )

507

Console.WriteLine("Application is running with server GC=" +


GCSettings.IsServerGC);
}
}


, 
,
, 
. , 
0, , 
, . 
0 1, , ,
2, 0 , 
, .
,
.
, 
. 
, . 
, , 
. , 
, 
,
.
, , , .
, 
, . 
, ,
.
, , 

.

. , 
, , ,
, 
.
CLR , 
( . 2 3), gcConcurrent.
.

<configuration>
<runtime>
gcConcurrent enabled="false"/>
</runtime>
</configuration>

508

CLR


, .
85 . .
.
, ,
. ,
85 .
. , 
,
. 
, Pinned.
2,
, . 
2,
. ,
2.

using System;
public static class Program {
public static void Main() {
Object o = new Byte[85000];
Console.WriteLine(GC.GetGeneration(o)); // 2, 0.
}
}
. 
.
.


, 
. , GC , 

, .

Int64 GetTotalMemory(Boolean forceFullCollection);


Int32 CollectionCount(Int32 generation);
, ,
, .
, , ,
.
, , .
.NET Framework 
, 
CLR.
PerfMon.exe ActiveX System

20

( )

509

Monitor, Windows. 
System Monitor, PerfMon.exe +
, Add Counters (. 2016).

. 2016. .NET CLR PerfMon.exe


CLR 
.NET CLR Memory, . 
, Add,
Close. System Monitor 
. , ,
Explain.

CLR Profiler, ,
. API, 

.
, 
. , ,
CLR profiler. 
!

2 1

CLR
(AppDomains)

,  
Microsoft .NET Framework, CLR
(AppDomains). 
CLR,
.
, 
.
,
. Microsoft Windows DLL 
.
, 
. 
, 
. 
, 
, CLR 

.

. 
CLR .
, 
. ,
, .NET Framework
.

CLR
.NET Framework Microsoft Windows. , .NET Frame
work , Windows. ,
Windows

21

CLR (AppDomains)

511

PE (portable executable) Windows 


(DLL).
Microsoft CLR COM, DLL,
Microsoft CLR COM
COM 
(GUID). .NET Framework COM, CLR,
Windows, COM.
. C++ MSCorEE.h .NET Framework SDK 
GUID ICorRuntimeHost.
Windows CLR. 
COM CLR, CoCreateInstance,
CorBindToRuntimeEx 
( MSCorEE.h).
MSCorEE.dll, C:\Windows\System32.
(shim) COM CLR,
, CLR .
CLR,
MSCorEE.dll ( 
). 
MSCorEE.dll CLR,
MSCorEE.dll , CLR, 
.
64 Windows 
2.0 .NET Framework
MSCorEE.dll. 32 x86,
64 x64 IA64 ( 
).
CLR MSCorWks.dll, MSCorEE.dll.
1.0, 1.1 2.0 CLR, MSCorWks.dll 
:
1.0 C:\Windows\Microsoft.NET\Framework\v1.0.3705;
1.1 C:\Windows\Microsoft.NET\Framework\v1.0.4322;
2.0 C:\Windows\Microsoft.NET\Framework\v2.0.50727.
CorBindToRuntimeEx 
CLR, . 
 , 
(, CLR), Cor
BindToRuntimeEx CLR
CLR, .

CLR,
. , 
requiredRuntime supportedRuntime XML
(. 2 3).

512

CLR

CorBindToRuntimeEx
ICorRuntimeHost. ,  :
, CLR, 
, 
, . . 
, 
;
CLR, CLR 
. , , 
, ,
, ,
CLR ;
CLR;
;
CLR,
Windows.
CLR. 

CLR, .
, , 
, .
:
;
JIT ( )
;
, ;
;

. : , , 
, , .
CLR 
(Steven Pratschner) Customizing
the Microsoft .NET Framework Common Language Runtime (Microsoft Press, 2005).
, Windows
CLR 
. Windows CLR.
CorBindToRuntimeEx
ICLRRuntimeHost.
CLR Windows
AddRef Release ICLRRuntimeHost
. CLR 
, Windows ,
.

21

CLR (AppDomains)

513

C++ , 
, CLR .

#include <Windows.h>
#include <MSCorEE.h>
#include <stdio.h>
void main(int argc, WCHAR **argv) {
// CLR.
ICLRRuntimeHost *pClrHost;
HRESULT hr = CorBindToRuntimeEx(
NULL,
// CLR (NULL " ")
NULL,
// (NULL
// " ")
0,
//
CLSID_CLRRuntimeHost, // CLSID CLR
IID_ICLRRuntimeHost, // IID ICLRRuntimeHost
(PVOID*) &pClrHost); // COM
// ( )
// ( CLR)
// CLR.
pClrHost>Start();
// ,
// String Int32.
DWORD retVal;
hr = pClrHost>ExecuteInDefaultAppDomain(
L"SomeMgdAssem.dll",
L"Wintellect.SomeType", L"SomeMethod", L"Jeff", &retVal);
// , .
wprintf(L"Managed code returned %d", retVal);
// ( CLR).
}

. , 
SomeMgdAssem.dll, .
Wintellect.SomeType, ,
, SomeMethod. , ,
SomeMethod String, Int32.
C# , :

// C#  SomeMgdAssem.dll.
using System;
namespace Wintellect {
public sealed class SomeType {

514

CLR

public static Int32 SomeMethod(String s) {


Console.WriteLine("Managed assembly: {0}", s);
return s.Length;
}
}
}


COM CLR , AppDomain,
. AppDomain, 
, (default AppDomain),
Windows.
, , COM
, CLR 
. .
.
, AppDomain, 
, AppDomain 
. , 
. 
,
. 
, AppDomain
, . 
, .
CLR
. CLR AppDomain
, .

, 
, AppDomain.
, 
, .

.
, CLR AppDomain.
, ,
.
! Windows 
. ,

. 
, ,
Windows . , 

21

CLR (AppDomains)

515

Windows . Win32 Create


Process , 
.
, ,
,

Windows. 
, , 
.
. 211 Windows,
COM CLR, (, 
,
Windows).
, AppDomain
(. 4). ,
( ,
JIT).

. 211. Windows, CLR

, AppDomain . AppDomain (
) : MyApp.exe, TypeLib.dll System.dll,
: Wintellect.dll System.dll.
: System.dll AppDomain. 
System.dll, 
; ,

516

CLR

, . , 
, IL , JIT 
,
.

.
; CLR AppDomain
, .
.

. MSCorLib.dll, Microsoft.
System.Object, System.Int32 , .NET Framework.
CLR, 
. MSCorLib.dll 
, AppDomain. 

. , 
, , 
: , ,
. 
.

AppDomain
, AppDomain,
AppDomain. 
. 
AppDomainMarshalling 
, ,
. ,
, ,
. AppDomainMarshalling 
, , , ,
. ,
. ,
.

using
using
using
using

System;
System.Reflection;
System.Threading;
System.Runtime.Remoting;

public static class Program {


public static void Main() {
// AppDomain, .
AppDomain adCallingThreadDomain = Thread.GetDomain();
// AppDomain ,
// . AppDomain

21

CLR (AppDomains)

517

// .
String callingDomainName = adCallingThreadDomain.FriendlyName;
Console.WriteLine("Default AppDomains friendly name={0}", callingDomainName);
// AppDomain,
// Main.
String exeAssembly = Assembly.GetEntryAssembly().FullName;
Console.WriteLine("Main assembly={0}", exeAssembly);
// , AppDomain.
AppDomain ad2 = null;
// 1: AppDomain
// .
Console.WriteLine("{0}Demo #1: MarshalbyReference", Environment.NewLine);
// AppDomain (
// , AppDomain).
ad2 = AppDomain.CreateDomain("AD #2", null, null);
// AppDomain, ,
//
// ( ).
MarshalByRefType mbrt = (MarshalByRefType)
ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");
Type t = mbrt.GetType();
// , .
Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));
// , MarshalByRefType, .
// .
// AppDomain, ,
// .
mbrt.SomeMethod(callingDomainName);
// AppDomain.
AppDomain.Unload(ad2);
// mbrt ;
// AppDomain.
try {
//  .
// , .
mbrt.SomeMethod(callingDomainName);
Console.WriteLine("Successful call.");
}
catch (AppDomainUnloadedException) {
Console.WriteLine("Failed call.");
}

518

CLR

// 2: AppDomain
// .
Console.WriteLine("{0}Demo #2: MarshalbyValue", Environment.NewLine);
// AppDomain (
// , AppDomain).
ad2 = AppDomain.CreateDomain("AD #2", null, null);
// AppDomain, ,
//
// ( ).
MarshalByValType mbvt = (MarshalByValType)
ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByValType");
// , .
Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbvt));
// , MarshalByRefType,
// .
mbvt.SomeMethod(callingDomainName);
// AppDomain.
AppDomain.Unload(ad2);
// mbrt ;
// AppDomain .
try {
// ; .
mbvt.SomeMethod(callingDomainName);
Console.WriteLine("Successful call.");
}
catch (AppDomainUnloadedException) {
Console.WriteLine("Failed call.");
}
// 3: AppDomain
// , .
Console.WriteLine("{0}Demo #3: NonMarshalable Type", Environment.NewLine);
// AppDomain (
// , AppDomain).
ad2 = AppDomain.CreateDomain("AD #2", null, null);
// AppDomain, ,
// 
// .
NotMarshalableType nmt = (NotMarshalableType)
ad2.CreateInstanceAndUnwrap(exeAssembly, "NotMarshalableType");
// ...
}
}

21

CLR (AppDomains)

519

// .
public class MarshalByRefType : MarshalByRefObject {
DateTime creation = DateTime.Now;
public MarshalByRefType() {
Console.WriteLine("{0} ctor running in {1}",
this.GetType().ToString(), Thread.GetDomain().FriendlyName);
}
public void SomeMethod(String callingDomainName) {
Console.WriteLine("Calling from '{0}' to '{1}'.",
callingDomainName, Thread.GetDomain().FriendlyName);
}
}
// .
[Serializable]
public class MarshalByValType : Object {
DateTime creation = DateTime.Now;
public MarshalByValType() {
Console.WriteLine("{0} ctor running in {1}",
this.GetType().ToString(), Thread.GetDomain().FriendlyName);
}
public void SomeMethod(String callingDomainName) {
Console.WriteLine("Calling from '{0}' to '{1}'.",
callingDomainName, Thread.GetDomain().FriendlyName);
}
}
// .
// [Serializable]
public class NotMarshalableType : Object {
DateTime creation = DateTime.Now;
public NotMarshalableType() {
Console.WriteLine("{0} ctor running in {1}",
this.GetType().ToString(), Thread.GetDomain().FriendlyName);
}
public void SomeMethod(String callingDomainName) {
Console.WriteLine("Calling from '{0}' to '{1}'.",
callingDomainName, Thread.GetDomain().FriendlyName);
}
}
AppDomainMarshalling, 
:

Default AppDomains friendly name=AppDomainMarshalling.exe


Main assembly=AppDomainMarshalling, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

520

CLR

Demo #1: MarshalbyReference


MarshalByRefType ctor running in AD #2
Is proxy=True
Calling from 'AppDomainMarshalling.exe' to 'AD #2'.
Failed call.
Demo #2: MarshalbyValue
MarshalByValType ctor running in AD #2
Is proxy=False
Calling from 'AppDomainMarshalling.exe' to 'AppDomainMarshalling.exe'.
Calling from 'AppDomainMarshalling.exe' to 'AppDomainMarshalling.exe'.
Successful call.
Demo #3: NonMarshalable Type
NotMarshalableType ctor running in AD #2
Unhandled Exception: System.Runtime.Serialization.SerializationException:
Type 'NotMarshalableType' in assembly 'AppDomainMarshalling, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null' is not marked as serializable.
at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
at Program.Main() in C:\AppDomainMarshalling.cs:line 97
, CLR.
Main AppDomain,
,
. Windows 
.
 . ,
CLR; Windows .
Windows AppDomain,
. CLR
. 
CLR, AppDomain , 
GetDomain System.Threading.Thread. 
, Cur
rentDomain System.AppDomain.
AppDomain (friendly
name) String,
. .
CLR AppDomain  ,

. Main AppDomain
, FriendlyName System.
AppDomain.
, Main (
AppDomain), Main . 
: Program, MarshalByRefType, MarshalByValType NonMars
halableType. ,
.

21

CLR (AppDomains)

521

1: AppDomain

CreateDomain System.AppDomain , 
CLR AppDomain Windows. AppDomain
CreateDomain; 
, 
AppDomain. CreateDomain, 
, :
String, ,
AppDomain, AD #2;
System.Security.Policy.Evidence, , 
CLR AppDomain.
null, 
, AppDomain. , 
,
System.Security.PermissionSet,
( , IPermission), 
PermissionSet
CreateDomain, PermissionSet;
System.AppDomainSetup, , CLR
AppDomain. null,
AppDomain. 
, AppDomain , App
DomainSetup, , 
CreateDomain AppDomainSetup.
CreateDomain AppDomain. 
, 
. AppDomain , 
, , AppDomain. App
Domain CLR AppDomain;
AppDomain ,
.
, AppDomain,
, ,
. Create
InstanceAndUnwrap AppDomain. CreateInstanceAndUnwrap, 
: String, ,
AppDomain ( ad2),
String , . CreateInstanceAndUnwrap
AppDomain .
( CreateInstanceAndUnwrap)
AppDomain, 
(MarshalByRefType).
, MarshalByRefType.
, CreateInstanceAndUnwrap
MarshalByRefType.

522

CLR

CreateInstanceAndUnwrap, 
, .
, , , CLR
(), AppDomain, ,
. CreateInstanceAndUnwrap
, , 
AppDomains! , ,
CreateInstanceAndUnwrap .
: MarshalByRefType 
System.MarshalByRefObject. , CreateInstanceAndUnwrap
, MarshalByRefObject, CLR 
. , 
AppDomain (,
) AppDomain (,
CreateInstanceAndUnwrap).
 
AppDomain, CLR  .
,

(, ).
, . 
, .
, , 
. ( 
 GCHandle, .
GCHandle 20.)
AppDomain CreateInstance
AndUnwrap  ,
 , 
 . AppDomain
Marshalling mbrt. : , 
CreateInstanceAndUnwrap, MarshalBy
RefType. CLR 
. CLR ,
, . 
, GetType  , 
MarshalByRefType.
, , CreateInstanceAnd
Unwrap, . 
AppDomainMarshalling IsTransparent
Proxy System.Runtime.Remoting.RemotingService, 
, CreateInstanceAndUnwrap. IsTransparentProxy
true, , .
AppDomainMarshalling 
SomeMethod. mbrt , 

21

CLR (AppDomains)

523

. 
 
AppDomain.
. GC
Handle , AppDomain, 
SomeMethod .
,
. , SomeMethod Thread.GetDomain().
FriendlyName. AD #2 ( 
), AppDomain,
AppDomain.CreateDomain AD #2 
. ,
Call Stack, [AppDomain Transition]
(. 212).

. 212. Call Stack


SomeMethod , 
SomeMethod , , 
AppDomain.

, . ,

. ,
AppDomain.
, 

AppDomains.

524

CLR

AppDomainMarshalling
Unload AppDomain, CLR AppDomain,
,
AppDomain. 
mbrt AppDomain
;  
( ).
AppDomain , 
SomeMethod, 
. , AppDomain,
, , SomeMethod  
AppDomainUnloadedException,
.
! CLR Microsoft ,
,
, 
. , 
AppDomain
, 
.
, . , 
MarshalByRefObject, .
 . ,
, 
MarshalByRefObject, JIT , 
( ), 
FieldGetter FieldSetter System.Object. 
; ,
. 
, MarshalByRefObject, 
,
CLR . 
, , 
, .
, Marshal
ByRefObject 
, 
. 
, ,
. 
, 
AppDomain, ,
.

21

CLR (AppDomains)

525

2: AppDomain

. App
Domain. CreateInstanceAndUnwrap
AppDomain . 
MarshalByValType, System.MarshalByRefObject.
, CreateInstanceAndUnwrap
.
MarshalByValType System.MarshalByRefObject, Create
InstanceAndUnwrap  ;
.
, MarshalByValType [Seriali
zable], CreateInstanceAndUnwrap .
, App
Domain () AppDomain ( ).

AppDomain, CLR 
,  .
CLR . CLR
( ), 
. CLR
,
. , CLR 
AppDomain. Create
InstanceAndUnwrap ; 
.
! CLR 
AppDomain ( ,
AppBase 
). CLR 
. , 
,
.
 AppDomain 
, .
 , 
( AppDomainMarshalling),
.
, , CreateInstanceAndUnwrap,
, AppDomainMarshalling 
IsTransparentProxy System.Runtime.Remoting.
RemotingService, ,
CreateInstanceAndUnwrap. IsTransparentProxy false, 
, , .

526

CLR

SomeMethod.
mbvt ,

. , :
Thread.GetDomain().FriendlyName AppDomainMarshalling. ,
Call Stack [AppDomain Transition].
, 
, AppDomainMarshalling AppDomain,
SomeMethod. 1,
, AppDomain
, ,
, .
: 
, 
. MarshalByValType 
AppDomain,
, .
, 
AppDomain.

, 
. , 
, 
AppDomain.

3:

3 1 2. 
AppDomain, CreateInstanceAndUnwrap

. NonMarshalableType. , Create
InstanceAndUnwrap
. NonMarshalableType
System.MarshalByRefObject [Serializable],
CreateInstanceAndUnwrap 
,
! , Create
InstanceAndUnwrap SerializationException 
AppDomain.
, .



 SomeMethod String.
1 String, SomeMethod , 
SomeMethod . , CLR
, 

21

CLR (AppDomains)

527

. , , CLR
, MarshalByRefObject; 
.
, CLR , [Serializable].
, .
MarshalByRefObject [Seriali
zable], CLR 
.
, CLR 
. , 
, CLR
. ,
, , CLR

.
AppDomainMarshalling String 
. System.String 
MarshalByRefObject, .
, System.String [Serializable],
. CLR 
String. String
AppDomain CLR
String , .
 , String ,
String .
. 11.

AppDomain
CLR 
. AppDomain 
, CLR . AppDomain 
: Unload AppDomain ( 
AppDomainMarshalling). CLR 
AppDomain.
1. CLR , 
.
2. CLR ,
AppDomain
AppDomain. CLR 
, AppDomain, 
ThreadAbortException ( 
). finally, 
. ,
ThreadAbortException, CLR 

528

CLR

; , .
,
CLR .
! CLR ,
finally catch, ,
. CLR , 
, 
, , , CLR
, ,
. 
,
CLR Thread
AbortException.
3. AppDomain , . 2 CLR 
,
, AppDomain. 
, , , .
, ,
AppDomainUnloadedException.
4. CLR , ,
AppDomain. Finalize
, .
5. CLR . , AppDo
main.Unload, ; AppDomain.Unload 
.
AppDomainMarshalling . 
, AppDomain.Unload,
AppDomain , CLR
ThreadAbortException ( ThreadAbortException ).
, AppDomain.Unload, CLR 10 ( 
), AppDomain .
10 , , AppDomain.Unload, 
, CannotUnloadAppDomainException, AppDomain
( ) .
, AppDomain.Unload, 
AppDomain, CLR ,
AppDomain. Thread
AbortException ,
. App
Domain, . AppDomain
CannotUnloadAppDomainException,
, , 
.

21

CLR (AppDomains)

529

AppDomain
: CLR,
CLR AppDomain. ,
, CLR
. , ,
CLR .

Windows Forms
Windows Forms,
(shim) CLR .
CLR, 
. 
CLR. CLR CLR
, , (Main).
CLR , , .
. , 
, CLR
AppDomain, ,
. Main , Windows 
( ).
, Windows
, Exit Sys
tem.Environment. Exit
, Finalize 
, COM
, CLR, Win32
ExitProcess.
Windows Forms CLR

, AppDomainMarshalling.

Microsoft Internet Explorer


.NET Framework MIME (MSCorIE.dll),
Internet Explorer 5.01 .
, MIME application/octetstream
application/xmsdownload. , , MIME
CorBindToRuntimeEx CLR, Internet
Explorer CLR.
MIME CLR , Web
AppDomain. 

, , Web, 
, Web, 
Web.

530

CLR

Web- ASP.NET Web- XML


ASP.NET ISAPI ( ASPNet_ISAPI.dll).
URL, , ASP.NET
CLR. Web, ASP.NET ,
. , ASP.NET CLR
AppDomain Web ( Web 
). ASP.NET 
CLR AppDomain , Web
,
. , CLR
AppDomain Web .
Web, ASP.NET
AppDomain, Web
AppDomain .
JIT , 
.
Web, ASP.NET CLR
AppDomain. ,
. , Windows
Web,
. , Web,
AppDomain Web 
Web Web.
ASP.NET Web
, Web. Web
, ASP.NET , AppDomain,
( ),
AppDomain . ASP.NET 
AppDomain, (shadow copying).

Microsoft SQL Server 2005


Microsoft SQL Server 2005 ,
C++. SQL Server 2005
.
SQL Server CLR.
App
Domain, .
! , 

. , JIT ,
. 
FCL . 
, .
?

21

CLR (AppDomains)

531


,
,
. , 
CLR. , , ,
, AppDomain,
.


CLR. 

CLR. ,
(
Customizing the Microsoft .NET Framework Common Language Runtime,
).

CLR
System.AppDomainManager CLR 
, , . , 
. , , 
, System.AppDomainManager, 
.
GAC,
( GAC ).
Windows CLR
AppDomainManager .
, AppDomainManager. AppDomain,
, .
AppDomainManager Windows:
API ( )
.
CorBindToRuntimeEx ICLRControl 
SetAppDomainManagerType,
GAC , AppDomainManager.
( )
CLR Windows 
: APPDOMAIN_MANAGER_ASM ,
GAC, APPDOMAIN_MANAGER_TYPE , 
AppDomainManager. 
, 
;
.
( ) 
CLR HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFrame
work\ ( HKEY_CURRENT_USER\Software\Microsoft\.NETFramework\) 

532

CLR

: APPDOMAIN_MANAGER_ASM, , 
GAC, APPDOMAIN_MANAGER_TYPE, ,
AppDomainManager. , 
, ,
AppDomainManager . .

(, 
). , ?
, AppDomainManager.
, 
AppDomain. 
AppDomain, AppDomainManager
.
AppDomain
AppDomain. AppDomain, CLR 
, AppDomainManager. 
, 
, .

-
CLR, 
. (
):
CLR , 
. (
. .)
CLR AppDomain.
AppDomain, .
CLR .
, .
CLR Windows.
AppDomains ,
.
CLR AppDomain .
. 
, finally Finalize . 
, finally 
Finalize . ,
, ,
catch finally. , , 
(Critical Execution Region,
CER), .
, (escalation
policy), CLR, .
, SQL Server 2005 , CLR 

21

CLR (AppDomains)

533

CLR 
. , CLR
.
, CLR 
.
, . ,
, ,
, .
, ,
, Monitor.Enter, WaitOne Mutex 
AcquireReaderLock AcquireWriterLock ReaderWriterLock.
AutoResetEvent, ManualResetEvent Semaphore ,
, 
. , CLR , 
,
AppDomain. , .
,
, ,
,  AppDomain ;
.
,
, CLR
AppDomain 
. AppDomain , CLR 
AppDomain.


 
. . 
, 
. ,
, .
, , 
, . ,
AppDomain,
. 
 
AppDomain, ,
, .
, ?

, .
, .
,  , 
. , ?
( ),
.

534

CLR

,
. . 213 , 
 .
( ).
1. .
2. 
.
3. ,
, .
4. try App
Domain ( , MarshalByRefObject). AppDomain
(, ),
, .
;
.
5. . 
,
Abort Thread, CLR
ThreadAbortException.
6. , finally,
. App
Domain.  try,
catch, ThreadAbortException.
7. ThreadAbortException ResetAbort
Thread. , .
8. , ThreadAbortException,
, 
.

. 213.
. 
, Abort Thread . Abort

21

CLR (AppDomains)

535

AbortRequested . 
, , 
(safe place). , 
, ( )
. ,
, .
, (. 20). 
, 
, catch finally, 
.
, 
AbortRequested Thread
AbortException. , 
, finally .
, ThreadAbortException 
. 
, , 
.
ThreadAbortException, 
. 
: ThreadAbortException,
? CLR
ThreadAbortException. ThreadAbortException,
CLR . , catch
CLR ThreadAbortException.
CLR : CLR 
ThreadAbortException catch, 
, ?
catch ResetAbort Thread. 
CLR ThreadAbortException catch.
:
ThreadAbortException ResetAbort Thread?
: ResetAbort 
SecurityPermission ControlThread true. AppDomain
, , 
.
,  : 
ThreadAbortException,
catch finally,
, .
. 
, CLR 
, AppDomain,
CLR . ,
ThreadAbortException catch 
. , catch
CLR ThreadAbortException.

536

CLR

,

. catch finally
, ,  
.
.
, Thread Abort: ,
Object, . 
ThreadAbortException, Excep
tionState, , . 
, Abort, , 
ThreadAbortException. 
.

2 2

, 
, 
. ,
, ,
, ,
(addins),
. 
, , , 
, . 
.
CLR
AppDomain, 21.
AppDomain 
. 
, AppDomain, .
CLR, AppDomain, , 
, 
, .


, JIT IL , , 
IL. , JIT 
TypeRef AssemblyRef , ,
. AssemblyRef
. JIT
( ), ,
, AppDomain
( ). , 
( ,
).

538

CLR

CLR , Load
System.Reflection.Assembly. ,
AppDomain.
CLR Win32 LoadLibrary. , 
Load Assembly. 
:

public class Assembly {


public static Assembly Load(AssemblyName assemblyRef);
public static Assembly Load(String assemblyString);
// .
}
Load CLR
GAC, 
, 
, codeBase . Load 
, , CLR
GAC. , Load Assembly,
. , 
System.IO.FileNotFoundException.

, 
Microsoft Windows. 

. , GAC x86
, CLR (.
3). CLR , 
Load Assembly :

"SomeAssembly, Version=2.0.0.0, Culture=neutral,


PublicKeyToken=01234567890abcde, ProcessorArchitecture=MSIL"
CLR 
ProcessorArchitecture MSIL (Microsoft IL), x86,
IA64 AMD64.

! Load System.AppDomain.
Assembly 
, AppDomain.

.
, .
Load AppDomain , 
.
:
. , AppDomain 
, CLR. , 

22

539

CLR App
Domain, .
, Load AppDomain
. , System.Assembly System.
MarshalByRefObject, AppDomain
. CLR
AppDomain.
AppDomain
, FileNotFound
Exception. , 
Load System.AppDomain.
Load
AppDomain AppDomain,
, . 
( ILDasm.exe, PEVerify.exe, CorFlags.exe,
GACUtil.exe, SGen.exe, SN.exe XSD.exe), 
. ,
( ) .
LoadFrom Assembly:

public class Assembly {


public static Assembly LoadFrom(String path);
// .
}
LoadFrom GetAssemblyName System.Reflection.
AssemblyName, , 
AssemblyRef, 
System.Reflection.AssemblyName ( ). 
LoadFrom Load Assembly, Assembly
Name. CLR
. , Load
Assembly, ; 
LoadFrom. Load , LoadFrom ,
, LoadFrom. , ,
, LoadFrom 
Assembly, .
, LoadFrom URL :

private static void SomeMethod() {


Assembly a = Assembly.LoadFrom(@"http://Wintellect.com/SomeAssembly.dll");
}
 CLR , 
.
, . ,
Internet Explorer 
[. Work Offline ( ) File ()], 
.

540

CLR

! 
. LoadFrom 
Load, , CLR , ,
. 
; 

, , , LoadFrom . 
, 
, CLR  
, LoadFile Assembly.
, 
( ),
, ReflectionOnlyLoadFrom
, , ReflectionOnlyLoad Assembly.
:

public class Assembly {


public static Assembly ReflectionOnlyLoadFrom(String assemblyFile);
public static Assembly ReflectionOnlyLoad(String assemblyString);
// .
}
ReflectionOnlyLoadFrom , 
GAC  .
ReflectionOnlyLoad GAC, 
, , codeBase.
Load ,
, , .
,
AppDomain
ApplyPolicy.
ReflectionOnlyLoadFrom ReflectionOnlyLoad
CLR  ,
InvalidOperationException. 
, 
, , .
,
, 
ReflectionOnlyAssemblyResolve AppDomain, 
, ( 
ApplyPolicy AppDomain); CLR . 
, ReflectionOnlyLoad
From ReflectionOnlyLoad Assembly,
.

22

541

. 
, CLR .
, : 
. CLR
, 
. , 
AppDomain, .
. 21.
, , ReflectionOnlyLoadFrom
ReflectionOnlyLoad, , 
. CLR ,
, ,

, , .
 
, 
.



, .
, , . .
System.Reflection ,
( ) .

.
, ,
, 
, . 
System.Reflection , ,

. , ( . 17)
. ,
, IL. 
, ILDasm.exe Microsoft.
,
, 
CLR.
. FCL ,
, 
, ,
, .

542

CLR

. 
,
, . , FCL 
, , .

. Microsoft Visual Studio
, , 
Web Win
dows Forms .
, 

. ,
, , 
. 
Win32 LoadLibrary GetProcAddress.
, , 
(late binding). (early binding) , 
.


, 
, 
. .

, 
. , Type.
GetType(Jef);,
Jef , Jeff, ,
, ,
, .


, 
. ,
System.Reflection.
,


. 

, 
. CLR
, . , , CLR 
.

22

543

.
, ,
.
, .
, ,
( ) 
.
, . ,
, 
, ( ), 
, . 
, 
, .


. . 
.

,
, .
FCL . 
GetExportedTypes Assembly. , 

:

using System;
using System.Reflection;
public static class Program {
public static void Main() {
String dataAssembly = "System.Data, version=2.0.0.0, " +
"culture=neutral, PublicKeyToken=b77a5c561934e089";
LoadAssemAndShowPublicTypes(dataAssembly);
}
private static void LoadAssemAndShowPublicTypes(String assemId) {
// AppDomain.
Assembly a = Assembly.Load(assemId);
// ,
// .
foreach (Type t in a.GetExportedTypes()) {
// .
Console.WriteLine(t.FullName);
}
}
}

544

CLR

-
: System.
Type. System.Type .
, System.Reflection.MemberInfo ( Type
). FCL ,
System.Type, System.RuntimeType, System.ReflectionOnlyType, System.Reflection.TypeDele
gator , System.Reflection.Emit
(EnumBuilder, GenericTypeParameterBuilder TypeBuilder).
TypeDelegator 
Type Type,
Type
.
.
System.RuntimeType.
FCL,
. AppDomain CLR
RuntimeType .
, System.Object
GetType. , CLR
RuntimeType. AppDomain
RuntimeType, ,
, :

private static Boolean AreObjectsTheSameType(Object o1, Object o2) {


return o1.GetType() == o2.GetType();
}
GetType Object, FCL
Type:
System.Type 
GetType. String.
( ). : ,
( int, string, bool 
C#), , CLR. 
, , 
. , 
RuntimeType.
, ,
MSCorLib.dll.
, null System.TypeLoad
Exception , GetType
. FCL 
.
GetType ,
System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=

22

545

b77a5c561934e089. GetType 
( ).
System.Type ReflectionOnlyGetType.
, GetType, ,
, .
System.Type : GetNestedType Get
NestedTypes.
System.Reflection.Assembly :
GetType, GetTypes GetExportedTypes.
System.Reflection.Module : GetType,
GetTypes FindTypes.
Microsoft 
, 
, . 

, , 
.
FCL 
BackusNaur Form Grammar for Type Names.
,
Type . Type 
, , 
. C# typeof,
, 
( )
. :

private static void SomeMethod(Object o) {


// GetType
// typeof
if (o.GetType() == typeof(FileInfo))
{
if (o.GetType() == typeof(DirectoryInfo)) {
}

( ).
( ).
... }
... }

if ,
o FileInfo, , FileInfo. 
, , . 

is as C#.
Type, 
. , IsPublic, IsSealed,
IsAbstract, IsClass, IsValueType , , .
, Assembly, AssemblyQualifiedName, FullName, Module 
, , ,
. BaseType, .

546

CLR

FCL Type. 
. , Type 50 
. .
.

, Exception
 ExceptionTree (. )
, AppDomain 
,
System.Exception. , , , 
, 19.

using
using
using
using

System;
System.Text;
System.Reflection;
System.Collections.Generic;

public static class Program {


public static void Main() {
// , .
LoadAssemblies();
// .
Int32 totalPublicTypes = 0, totalExceptionTypes = 0;
List<String> exceptionTree = new List<String>();
// , AppDomain.
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) {
// , .
foreach (Type t in a.GetExportedTypes()) {
totalPublicTypes++;
// , .
if (!t.IsClass || !t.IsPublic) continue;
// .
StringBuilder typeHierarchy = new StringBuilder(t.FullName, 5000);
// , Exception.
Boolean derivedFromException = false;
// , System.Exception .
Type baseType = t.BaseType;
while ((baseType != null) && !derivedFromException) {
// .
typeHierarchy.Append("?" + baseType);
derivedFromException = (baseType == typeof(System.Exception));
baseType = baseType.BaseType;
}

22

// ,
// Exception; .
if (!derivedFromException) continue;
// ? Exception.
totalExceptionTypes++;
//
// ? Exception.
String[] h = typeHierarchy.ToString().Split('?');
Array.Reverse(h);
// ,
// .
// ? Exception.
exceptionTree.Add(String.Join("?", h, 1, h.Length ? 1));
}
}
// .
exceptionTree.Sort();
// .
foreach (String s in exceptionTree) {
// .
String[] x = s.Split('?');
//
// .
Console.WriteLine(new String(' ', 3 * x.Length) + x[x.Length ? 1]);
}
// .
Console.WriteLine("\n> Of {0} types, {1} are " +
"derived from System.Exception.",
totalPublicTypes, totalExceptionTypes);
}
private static void LoadAssemblies() {
String[] assemblies = {
"System,
PublicKeyToken={0}",
"System.Data,
PublicKeyToken={0}",
"System.Design,
PublicKeyToken={1}",
"System.DirectoryServices,
PublicKeyToken={1}",
"System.Drawing,
PublicKeyToken={1}",
"System.Drawing.Design,
PublicKeyToken={1}",
"System.Management,
PublicKeyToken={1}",
"System.Messaging,
PublicKeyToken={1}",
"System.Runtime.Remoting,
PublicKeyToken={0}",
"System.Security,
PublicKeyToken={1}",
"System.ServiceProcess,
PublicKeyToken={1}",

547

548

CLR

"System.Web,
"System.Web.RegularExpressions,
"System.Web.Services,
"System.Windows.Forms,
"System.Xml,

PublicKeyToken={1}",
PublicKeyToken={1}",
PublicKeyToken={1}",
PublicKeyToken={0}",
PublicKeyToken={0}",

};
String EcmaPublicKeyToken = "b77a5c561934e089";
String MSPublicKeyToken= "b03f5f7f11d50a3a";
// , System.Object.
// , .
Version version =
typeof(System.Object).Assembly.GetName().Version;
// , .
foreach (String a in assemblies) {
String AssemblyIdentity =
String.Format(a, EcmaPublicKeyToken, MSPublicKeyToken) +
", Culture=neutral, Version=" + version;
Assembly.Load(AssemblyIdentity);
}
}
}


, Type,
. FCL .
CreateInstance System.Activator
CreateInstance. 
Type String, 
, . ,
, : , 
.
CreateInstance, , .
, , , 
. ,
, . 
,
System.Runtime.Remoting.ObjectHandle ( System.MarshalByRefObject).
ObjectHandle , ,
AppDomain, AppDomain, AppDomain ,
. 
, Unwrap ObjectHandle.
, .
,  
. .

22

549

CreateInstanceFrom System.Activator Activator 


CreateInstanceFrom.
CreateInstance ,
, . 
AppDomain LoadFrom (
Load) Assembly. CreateInstanceFrom
Type, ObjectHandle, 
.
System.AppDomain AppDomain
( ), 
: CreateInstance, CreateInstanceAndUnwrap, CreateIntanceFrom
CreateInstanceFromAndUnwrap. Activator,
, AppDomain, 
. , Unwrap,
, .
InvokeMember System.Type
Type InvokeMember.
, , . 
AppDomain,
. .
Invoke System.Reflection.ConstructorInfo
Type 
ConstructorInfo,
Invoke. AppDomain, 
.
.
CLR , .
,
. CreateInstance
Activator ,
. ,
, CreateInstance,
Type, , Type
Boolean.
,
( , System.Array) ( System.Multi
castDelegate). , CreateInstance
Array ( ). 
CreateInstance Type, 
. CreateInstance 
.
CreateDelegate
Delegate ( ).
CreateDelegate Type, 
. , 

550

CLR

CreateDelegate 
.
,
, MakeGenericType
Type, , 
. Type
. .

using System;
using System.Reflection;
internal sealed class Dictionary<TKey, TValue> { }
public static class Program {
public static void Main() {
// ? .
Type openType = typeof(Dictionary<,>);
// , TKey=String, TValue=Int32.
Type closedType = openType.MakeGenericType(
new Type[] { typeof(String), typeof(Int32) });
// .
Object o = Activator.CreateInstance(closedType);
// , .
Console.WriteLine(o.GetType());
}
}
, :

Dictionary'2[System.String,System.Int32]



, 
. ,
,
(addin) . 
, , ,
.
.
, , 

. 
, ,

22

551

MSCorLib.dll. 
, . ,
(. 3)
.
, . ,
. ,
, . 
, 
(. 3).
, MSCorLib.dll, :
CLR MSCorLib.dll,
CLR. , 
MSCorLib.dll. , MSCorLib.dll
(. 3).
, .
, ,
. , 
. 
, : 
.
, . ,
, .
. 
,
, .
.
, .
,
. . ,
,
.
,
. , .

using System;
namespace Wintellect.HostSDK {
public interface IAddIn {
String DoSomething(Int32 x);
}
}
, AddInTypes.dll, 
, HostSDK.

552

CLR

using System;
using Wintellect.HostSDK;
public sealed class AddIn_A : IAddIn {
public AddIn_A() {
}
public String DoSomething(Int32 x) {
return "AddIn_A: " + x.ToString();
}
}
public sealed class AddIn_B : IAddIn {
public AddIn_B() {
}
public String DoSomething(Int32 x) {
return "AddIn_B: " + (x * 2).ToString();
}
}
, Host.exe, ( 
). HostSDK.dll.
, ,
,
.dll, , EXE . 
CLR
Microsoft 
CLR. , 
.

using
using
using
using
using

System;
System.IO;
System.Reflection;
System.Collections.Generic;
Wintellect.HostSDK;

public static class Program {


public static void Main() {
// , Host exe.
String AddInDir = Path.GetDirectoryName(
Assembly.GetEntryAssembly().Location);
// ,
// EXE? .
String[] AddInAssemblies = Directory.GetFiles(AddInDir, "*.dll");
// , .
List<Type> AddInTypes = new List<Type>();
// ;
// , .

22

553

foreach (String file in AddInAssemblies) {


Assembly AddInAssembly = Assembly.LoadFrom(file);
// .
foreach (Type t in AddInAssembly.GetExportedTypes()) {
// , IaddIn,
// , .
if (t.IsClass && typeof(IAddIn).IsAssignableFrom(t)) {
AddInTypes.Add(t);
}
}
}
// : .
// , .
foreach (Type t in AddInTypes) {
IAddIn ai = (IAddIn) Activator.CreateInstance(t);
Console.WriteLine(ai.DoSomething(5));
}
}
}
.
AppDomain 
. , ,
, .
AppDomain, 
, 
MarshalByRefObject. AppDomain 
MarshalByRefObject .
( AppDomain) (
AppDomain), 
.



,
,
.
, 
. 
( 
) , ;
.
,
.


554

CLR

, 

. ILDasm, FxCop
Windows Forms Web Forms, 
Visual Studio. 

. , 
, .


, , , , 
. FCL System.Reflection.MemberInfo, , 
, . MemberInfo
(. 221),
.

. 221.
,
.
, AppDomain.
GetMembers, ,
MemberInfo; , .
bf BindingFlags, GetMembers, ,
. ( BindingFlags .)
(, , , . .)
.

22

555

using System;
using System.Reflection;
public static class Program {
public static void Main() {
// , AppDomain.
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly a in assemblies) {
WriteLine(0, "Assembly: {0}", a);
// .
foreach (Type t in a.GetExportedTypes()) {
WriteLine(1, "Type: {0}", t);
// .
const BindingFlags bf = BindingFlags.DeclaredOnly |
BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Instance | BindingFlags.Static;
foreach (MemberInfo mi in t.GetMembers(bf)) {
String typeName = String.Empty;
if (mi is Type)
typeName =
else if (mi is FieldInfo)
typeName =
else if (mi is MethodInfo)
typeName =
else if (mi is ConstructorInfo) typeName =
else if (mi is PropertyInfo)
typeName =
else if (mi is EventInfo)
typeName =

"(Nested) Type";
"FieldInfo";
"MethodInfo";
"ConstructoInfo";
"PropertyInfo";
"EventInfo";

WriteLine(2, "{0}: {1}", typeName, mi);


}
}
}
}
private static void WriteLine(Int32 indent, String format,
params Object[] args) {
Console.WriteLine(new String(' ', 3 * indent) + format, args);
}
}
.
.

Assembly: mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089


Type: System.Object
MethodInfo: Boolean InternalEquals(System.Object, System.Object)
MethodInfo: Int32 InternalGetHashCode(System.Object)
MethodInfo: System.Type GetType()
MethodInfo: System.Object MemberwiseClone()
MethodInfo: System.String ToString()
MethodInfo: Boolean Equals(System.Object)
MethodInfo: Boolean Equals(System.Object, System.Object)

556

MethodInfo:
MethodInfo:
MethodInfo:
MethodInfo:

CLR

Boolean ReferenceEquals(System.Object, System.Object)


Int32 GetHashCode()
Void Finalize()
Void FieldSetter(System.String, System.String, System.Object)

MethodInfo: Void FieldGetter(System.String, System.String, System.Object ByRef)


MethodInfo: System.Reflection.FieldInfo GetFieldInfo(System.String,
System.String)
ConstructoInfo: Void .ctor()
Type: System.Collections.IEnumerable
MethodInfo: System.Collections.IEnumerator GetEnumerator()
Type: System.Collections.Generic.IComparer1[T]
MethodInfo: Int32 Compare(T, T)
Type: System.ValueType
MethodInfo: Int32 GetHashCode()
MethodInfo: Boolean CanCompareBits(System.Object)
MethodInfo: Boolean FastEqualsCheck(System.Object, System.Object)
MethodInfo: Boolean Equals(System.Object)
MethodInfo: System.String ToString()
ConstructoInfo: Void .ctor()
Type: System.IDisposable
MethodInfo: Void Dispose()
Type: System.Collections.Generic.IEnumerator1[T]
MethodInfo: T get_Current()
PropertyInfo: T Current
Type: System.ArraySegment1[T])
MethodInfo: T[] get_Array()
MethodInfo: Int32 get_Offset()
MethodInfo: Int32 get_Count()
MethodInfo: Int32 GetHashCode()
MethodInfo: Boolean Equals(System.Object)
MethodInfo: Boolean Equals(System.ArraySegment1[T])
MethodInfo: Boolean op_Equality(System.ArraySegment1[T],
System.ArraySegment1[T])
MethodInfo: Boolean op_Inequality(System.ArraySegment1[T],
System.ArraySegment1[T])
ConstructoInfo: Void .ctor(T[])
ConstructoInfo: Void .ctor(T[], Int32, Int32)
PropertyInfo: T[] Array
PropertyInfo: Int32 Offset
PropertyInfo: Int32 Count
FieldInfo: T[] _array
FieldInfo: Int32 _offset
FieldInfo: Int32 _count
MemberInfo , .
. 221 MemberInfo,
. , System.Type MemberInfo,
Type , . 221.

22

557

. 22-1. , ,
MemberInfo

Name

String

.
Name
, +

MemberType

()
MemberTypes

[, ,
, , ,
( )]

DeclaringType

Type

Type,

ReflectedType

Type

Type,

Module

Module

Module,

MetadataToken

Int32

(
),

GetCustomAttributes

, 
Object[]

,

, .

IsDefined

, 
Boolean

true,
( )

, . 221, . 
DeclaringType ReflectedType.
. :

public sealed class MyType {


public override String ToString() { return null; }
}
, ?

MemberInfo[] members = typeof(MyType).GetMembers();


members , 
, MyType 
, System.Object. DeclaringType
MemberInfo, ToString, MyType,
ToString MyType. ,
DeclaringType MemberInfo,
Equals, System.Object, Equals System.Object,
MyType. ReflectedType MyType,
GetMembers .
, GetMembers, 
( BindingFlags.DeclaredOnly).
GetMembers, , Type
, : GetNestedTypes, GetFields, Get
Constructors, GetMethods, GetProperties GetEvents. 

558

CLR

, Type, FieldInfo, Construc


torInfo, MethodInfo, PropertyInfo EventInfo .
. 222 , 
. AppDomain , 
, , ,
. 
( , , , ).
, 
. , 
,
Namespace.

. 222. ,

. ( 
, .) , , 
/ GetParameters, 
ParameterInfo, 
. ReturnParameter, 
ParameterInfo
. ,
GetGenericArguments. , 
, , 
GetCustomAttributes.

BindingFlags:
, Type GetMembers, Get
NestedTypes, GetFields, GetConstructors, GetMethods, GetProperties GetEvents. 

22

559

,
System.Reflection.BindingFlags. ,
(OR), ,
. , BindingFlags
. 222.

. 22-2. ,
BindingFlags

Default

0x00

. ,
,

IgnoreCase

0x01

DeclaredOnly

0x02

,
( )

Instance

0x04

Static

0x08

Public

0x10

NonPublic

0x20

FlattenHierarchy

0x40

, 
, . 
BindingFlags, . ,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.
Static.
: Type GetMember, GetNestedType, GetField,
GetConstructor, GetMethod, GetProperty GetEvent. ,
, . 
IgnoreCase BindingFlags.


, , Find
Interfaces, GetInterface GetInterfaces Type. Type,
. 
, , .
, , ,
. ,
IBookRetailer IMusicRetailer Purchase. 
MethodInfo , 
GetInterfaceMap Type, 
. System.Reflection.InterfaceMapping ( ).
InterfaceMapping (. 223).

560

CLR

. 22-3. InterfaceMapping

TargetType

Type

, GetInterfaceMapping

InterfaceType

Type

,
GetInterfaceMapping

InterfaceMethods

MethodInfo[]

TargetMethods

MethodInfo[]

,
,

InterfaceMethods TargetMethods , Interface


Methods[0] MethodInfo , TargetMethods[0] 
, .
, ,
, .

using System;
using System.Reflection;
// .
internal interface IBookRetailer : IDisposable {
void Purchase();
void ApplyDiscount();
}
internal interface IMusicRetailer {
void Purchase();
}
//
// ,
// .
internal sealed class MyRetailer : IBookRetailer, IMusicRetailer, IDisposable {
// IbookRetailer.
void IBookRetailer.Purchase() { }
public void ApplyDiscount() { }
// ImusicRetailer.
void IMusicRetailer.Purchase() { }
// IDisposable.
public void Dispose() { }
// MyRetailer ( ).
public void Purchase() { }
}
public static class Program {
public static void Main() {

22

561

// , MyRetailer,
// .
//
// , FindInterfaces.
Type t = typeof(MyRetailer);
Type[] interfaces = t.FindInterfaces(TypeFilter,
typeof(Program).Assembly);
Console.WriteLine("MyRetailer implements the following " +
"interfaces (defined in this assembly):");
// .
foreach (Type i in interfaces) {
Console.WriteLine("\nInterface: " + i);
// , .
InterfaceMapping map = t.GetInterfaceMap(i);
for (Int32 m = 0; m < map.InterfaceMethods.Length; m++) {
//
// , .
Console.WriteLine(" {0} is implemented by {1}",
map.InterfaceMethods[m], map.TargetMethods[m]);
}
}
}
// true, .
private static Boolean TypeFilter(Type t, Object filterCriteria) {
// true, ,
// filterCriteria.
return t.Assembly == filterCriteria;
}
}
, :

MyRetailer implements the following interfaces (defined in this assembly):


Interface: IBookRetailer
Void Purchase() is implemented by Void IBookRetailer.Purchase()
Void ApplyDiscount() is implemented by Void ApplyDiscount()
Interface: IMusicRetailer
Void Purchase() is implemented by Void IMusicRetailer.Purchase()
: IDisposable , 
EXE.


, , , ,
. ,

562

CLR

. FieldInfo , Construc
torInfo , Method
Info , ,
PropertyInfo get set , EventInfo
.
, 
. , . Type
InvokeMember, . 
InvokeMember, ; 
.

public abstract class Type : MemberInfo, ... {


public Object InvokeMember(
String name,
// .
BindingFlags invokeAttr, // .
Binder binder,
// .
Object target,
// , .
Object[] args,
// , .
CultureInfo culture);
// , .
...
}
InvokeMember, 
. , System.Missing
MethodException, System.MissingFieldException System.MissingMemberException,
, InvokeMember . InvokeMember 
, ; , Invoke
Member null. , Invo
keMember System.Reflection.TargetInvo
cationException, InnerException System.Reflection.TargetInvocation
Exception ,
. , , InvokeMember
, .
InvokeMember :
( ) ( 
). InvokeMember name
, .
.
, .
, InvokeMember  ,
. , InvokeMember ( target),
. .
binder , 
System.Reflection.Binder.  Binder ,
InvokeMember . Binder 
BindToField, BindToMethod, ChangeType,
ReorderArgumentArray, SelectMethod SelectProperty. InvokeMember
Binder, binder.

22

563

Microsoft () System.Default
Binder Binder. FCL, Microsoft , 
.
, Binder,
, , .
InvokeMember binder null, 
DefaultBinder.
(binder) , 
. , , ,
BindingFlags , .
BindingFlags: Default, IgnoreCase, DeclaredOnly,
Instance, Static, Public, NonPublic FlattenHierarchy (. 222). 
, .
, ,
args InvokeMember. 
. ,
. 
, , 
. , , 
Int64. InvokeMember,
args Int32, DefaultBinder
. InvokeMember Int32 Int64.
. 224 , DefaultBinder.

. 22-4. , DefaultBinder

Char

UInt16, UInt32, Int32, UInt64, Int64, Single, Double

Byte

Char, UInt16, Int16, UInt32, Int32, UInt64, Int64, Single, Double

SByte

Int16, Int32, Int64, Single, Double

UInt16

UInt32, Int32, UInt64, Int64, Single, Double

Int16

Int32, Int64, Single, Double

UInt32

UInt64, Int64, Single, Double

Int32

Int64, Single, Double

UInt64

Single, Double

Int64

Single, Double

Single

Double

BindingFlags, Default
Binder (. 225):

564

CLR

. 22-5. BindingFlags, DefaultBinder

ExactBinding

0x010000

OptionalParamBinding

0x040000

,

.
,
, 
. 
InvokeMember Type

InvokeMember, culture, 
. DefaultBinder . 
, culture 
. , String
1,23. 
, culture,
Single ( culture deDE)
( culture enUS).
InvokeMember, , 
target. ,
. Type,
null .
InvokeMember . (
), ( 
), . Invoke
Member, , Binding
Flags (. 226).

. 22-6. BindingFlags, InvokeMember

InvokeMethod

0x0100

InvokeMember

CreateInstance

0x0200

InvokeMember ,

GetField

0x0400

InvokeMember

SetField

0x0800

InvokeMember

GetProperty

0x1000

InvokeMember 
get

SetProperty

0x2000

InvokeMember 
set

: InvokeMember
. 
GetField GetProperty, InvokeMember ,
, .
SetField SetProperty. 

22

565

. BindingFlags.CreateInstance,
, .
! , 
,
,
.
.
,
, , , 
. , .
, 
System.Security.Permissions.ReflectionPermission, 
, TypeInformation System.Security.Permis
sions.ReflectionPermissionFlags. , 
, ,
System.Security.SecurityException.
, 
, .
MemberAccess ReflectionPermissionFlag.
, ,
SecurityException.
, ,
, 
. ,
 
,
.

,
InvokeMember Type (
). , InvokeMember
.
,
, , .
, , 
, , .
, , Type
GetFields, GetConstructors, GetMethods, GetProperties, GetEvents 
. ,
. , 
(. 227):

566

CLR

. 22-7.

FieldInfo

GetValue , SetValue,

ConstructorInfo

Invoke

MethodInfo

Invoke

PropertyInfo

GetValue get, SetValue


set

EventInfo

AddEventHandler add ,
RemoveEventHandler remove

PropertyInfo (. 9),
PropertyInfo CanRead, CanWrite
PropertyType. , ,
. PropertyInfo GetAccessors, 
MethodInfo get ( )
set ( ). GetGetMethod Get
SetMethod , Method
Info. GetValue SetValue PropertyInfo , 
MethodInfo .
EventInfo (. 10).
EventInfo EventHandlerType,
Type . EventInfo GetAddMethod
GetRemoveMethod, MethodInfo. 
AddEventHandler RemoveEventHandler ,
MethodInfo .
, . 227,
, .
, , ,
.
, , Invoke ConstructorInfo MethodInfo,
GetValue SetValue PropertyInfo
,  Binder Bin
dingFlags. , , .
 Binder 
, Int32 Int64, 
. BindingFlags, Binding
Flags.SuppressChangeType. , Default
Binder . , DefaultBinder 
. 
, ArgumentException.
, BindingFlags.ExactBinding,
BindingFlags.SuppressChangeType.
, , 
,
. , 

22

567

InvokeMethod MemberInfo,
, .

. ,
InvokeMember Type 
, .

using System;
using System.Reflection;
// .
// , , , .
internal sealed class SomeType {
private Int32 m_someField;
public SomeType(ref Int32 x) { x *= 2; }
public override String ToString() { return m_someField.ToString(); }
public Int32 SomeProp {
get { return m_someField; }
set {
if (value < 1)
throw new ArgumentOutOfRangeException(
"value", "value must be > 0");
m_someField = value;
}
}
public event EventHandler SomeEvent;
private void NoCompilerWarnings() {
SomeEvent.ToString();
}
}
public static class Program {
private const BindingFlags c_bf = BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance;
public static void Main() {
Type t = typeof(SomeType);
UsingInvokeMemberToBindAndInvokeTheMember(t);
Console.WriteLine();
BindingToMemberFirstAndThenInvokingTheMember(t);
}
private static void UsingInvokeMemberToBindAndInvokeTheMember(Type t) {
Console.WriteLine("UsingInvokeMemberToBindAndInvokeTheMember");
// Type.
Object[] args = new Object[] { 12 }; // .
Console.WriteLine("x before constructor called: " + args[0]);
Object obj = t.InvokeMember(null,

568

CLR

c_bf | BindingFlags.CreateInstance, null, null, args);


Console.WriteLine("Type: " + obj.GetType().ToString());
Console.WriteLine("x after constructor returns: " + args[0]);
// .
t.InvokeMember("m_someField",
c_bf | BindingFlags.SetField, null, obj, new Object[] { 5 });
Int32 v = (Int32)t.InvokeMember("m_someField",
c_bf | BindingFlags.GetField, null, obj, null);
Console.WriteLine("someField: " + v);
// .
String s = (String)t.InvokeMember("ToString",
c_bf | BindingFlags.InvokeMethod, null, obj, null);
Console.WriteLine("ToString: " + s);
// .
try {
t.InvokeMember("SomeProp",
c_bf | BindingFlags.SetProperty, null, obj, new Object[] { 0 });
}
catch (TargetInvocationException e) {
if (e.InnerException.GetType() !=
typeof(ArgumentOutOfRangeException)) throw;
Console.WriteLine("Property set catch.");
}
t.InvokeMember("SomeProp",
c_bf | BindingFlags.SetProperty, null, obj, new Object[] { 2 });
v = (Int32)t.InvokeMember("SomeProp",
c_bf | BindingFlags.GetProperty, null, obj, null);
Console.WriteLine("SomeProp: " + v);
// : InvokeMember .
}
private static void BindingToMemberFirstAndThenInvokingTheMember(Type t) {
Console.WriteLine("BindingToMemberFirstAndThenInvokingTheMember");
// .
ConstructorInfo ctor = t.GetConstructor(
new Type[] { Type.GetType("System.Int32&") });
Object[] args = new Object[] { 12 }; // .
Console.WriteLine("x before constructor called: " + args[0]);
Object obj = ctor.Invoke(args);
Console.WriteLine("Type: " + obj.GetType().ToString());
Console.WriteLine("x after constructor returns: " + args[0]);
// .
FieldInfo fi = obj.GetType().GetField("m_someField", c_bf);

22

fi.SetValue(obj, 33);
Console.WriteLine("someField: " + fi.GetValue(obj));
// .
MethodInfo mi = obj.GetType().GetMethod("ToString", c_bf);
String s = (String) mi.Invoke(obj, null);
Console.WriteLine("ToString: " + s);
// .
PropertyInfo pi =
obj.GetType().GetProperty("SomeProp", typeof(Int32));
foreach (MethodInfo m in pi.GetAccessors())
Console.WriteLine(m);
try {
pi.SetValue(obj, 0, null);
}
catch (TargetInvocationException e) {
if (e.InnerException.GetType() != typeof(ArgumentOutOfRangeException))
throw;
Console.WriteLine("Property set catch.");
}
pi.SetValue(obj, 2, null);
Console.WriteLine("SomeProp: " + pi.GetValue(obj, null));
// .
EventInfo ei = obj.GetType().GetEvent("SomeEvent", c_bf);
Console.WriteLine("AddMethod: "
+ ei.GetAddMethod());
Console.WriteLine("RemoveMethod: "
+ ei.GetRemoveMethod());
Console.WriteLine("EventHandlerType: " + ei.EventHandlerType);
EventHandler ts = new EventHandler(EventCallback);
ei.AddEventHandler(obj, ts);
ei.RemoveEventHandler(obj, ts);
}
private static void EventCallback(Object sender, EventArgs e) {}
}
, :

UsingInvokeMemberToBindAndInvokeTheMember
x before constructor called: 12
Type: SomeType
x after constructor returns: 24
someField: 5
ToString: 5
Property set catch.
SomeProp: 2
BindingToMemberFirstAndThenInvokingTheMember
x before constructor called: 12

569

570

CLR

Type: SomeType
x after constructor returns: 24
someField: 33
ToString: 33
Int32 get_SomeProp()
Void set_SomeProp(Int32)
Property set catch.
SomeProp: 2
AddMethod: Void add_SomeEvent(System.EventHandler)
RemoveMethod: Void remove_SomeEvent(System.EventHandler)
EventHandlerType: System.EventHandler
: SomeType
Int32. ,
Int32.
BindingToMemberFirstAndThenInvokingTheMember
GetType Type, System.Int32&.
(&) , .
 ,
. FCL.



( 
Type) ( MemberInfo), 
. 
. , : Type
 MemberInfo .
, ,
.
CLR 
. CLR ,
. CLR
. ,
Type  MemberInfo, , 
, . FCL
( System) Run
timeTypeHandle, RuntimeFieldHandle RuntimeMethodHandle.
IntPtr;
( ). IntPtr , ,
AppDomain. 
Type/MemberInfo 
. ,
.
Type RuntimeTypeHandle,
GetTypeHandle Type, Type.

22

571

RuntimeTypeHandle Type,
GetTypeFromHandle Type, RuntimeTypeHandle.
FieldInfo RuntimeFieldHandle, 
FieldHandle FieldInfo.
RuntimeTypeHandle FieldInfo,
GetTypeFromHandle FieldInfo.
MethodInfo RuntimeMethodHandle, 
MethodHandle MethodInfo.
RuntimeTypeHandle MethodInfo, 
GetMethodFromHandle MethodInfo.
MethodInfo,
RuntimeMethodHandle
.

using System;
using System.Reflection;
using System.Collections.Generic;
public sealed class Program {
private const BindingFlags c_bf = BindingFlags.FlattenHierarchy |
BindingFlags.Instance | BindingFlags.Static |
BindingFlags.Public | BindingFlags.NonPublic;
public static void Main() {
// .
Show("Before doing anything");
// MethodInfo MSCorlib.dll.
List<MethodBase> methodInfos = new List<MethodBase>();
foreach (Type t in typeof(Object).Assembly.GetExportedTypes()) {
// .
if (t.IsGenericTypeDefinition) continue;
MethodBase[] mb = t.GetMethods(c_bf);
methodInfos.AddRange(mb);
}
// .
Console.WriteLine("# of methods={0:###,###}", methodInfos.Count);
Show("After building cache of MethodInfo objects");
// RuntimeMethodHandles MethodInfo.
List<RuntimeMethodHandle> methodHandles =
methodInfos.ConvertAll<RuntimeMethodHandle>(
delegate(MethodBase mb) { return mb.MethodHandle; });
Show("Holding MethodInfo and RuntimeMethodHandle cache");
GC.KeepAlive(methodInfos); // .

572

CLR

methodInfos = null;
// .
Show("After freeing MethodInfo objects");
methodInfos = methodHandles.ConvertAll<MethodBase>(
delegate(RuntimeMethodHandle rmh) {
return MethodBase.GetMethodFromHandle(rmh); });
Show("Size of heap after re?creating MethodInfo objects");
GC.KeepAlive(methodHandles); // .
GC.KeepAlive(methodInfos);
// .
methodHandles = null;
// .
methodInfos = null;
// .
Show("After freeing MethodInfos and RuntimeMethodHandles");
}
private static void Show(String s) {
Console.WriteLine("Heap size={0,12:##,###,###} ? {1}",
GC.GetTotalMemory(true), s);
}
}
, :

Heap
# of
Heap
Heap
Heap
Heap
Heap

size=
150,756
methods=44,493
size=
3,367,084
size=
3,545,124
size=
368,936
size=
1,445,496
size=
191,036

? Before doing anything


?
?
?
?
?

After building cache of MethodInfo objects


Holding MethodInfo and RuntimeMethodHandle cache
After freeing MethodInfo objects
Size of heap after re?creating MethodInfo objects
After freeing MethodInfos and RuntimeMethodHandles

2 3


. , ,
. /
Microsoft Windows 
. 
,
/, 
.
, , Wintellect Power
Threading, 
. ,
Web http://Wintellect.com.

Windows CLR

CLR. CLR Windows ,
, ,
CLR. , ,
. , 
, , Programming
Applications for Microsoft Windows (Microsoft Press, 1999).
, CLR Windows,
CLR
Windows. , CLR CLR
Windows1 . , CLR 
, .
, , , 
1

(fiber) , ( 
). Windows .
, .
/ ,
, Windows 
.

574

CLR

. CLR
. Microsoft , , , 
CLR,
.
,
. , 
Windows, CLR, 
FCL. 
CLR.
(, Microsoft SQL Server 2005)
,
,
BeginThreadAffinity System.Threading.Thread. 
, 
, EndThreadAffinity Thread.



, 
. ,
. , 
,
. , 16 Windows:

. Win
dows NT 3.1 . 
,
.
, .
: ,
( ) 1
, 12
. , Windows 
DLL , DLL 
. : DLL
,
.

. Windows 
, .
, 20 . 

(context switch). 
, .

23

575

1. .
2. .
, 700
86, 1240 x64 2500 IA64.
3. , , ,
.
, , 
.
4. , 
.
5. .
, Windows
. , Microsoft
, 
.
: 
. ,
. ,
( ), , 
, .
,
. Windows 
: .
,
. .
, , , ,

. , Intel AMD,
, 

.

, 
, . 

. 
Hyperthreading
(multicore), Windows
( ) .
(, Intel Pentium Extreme), . ,
Windows Pentium Extreme !
, Intel Xeon Intel Pentium 4, Hyper
threading. .
( ), 
, .
( ,

576

CLR

),
. , 
Hyperthreading,
, .
, , 
. , Intel,
1030%.
, Intel Pentium AMD Athlon 64 X2,
. 
. . ,
, Hyperthreading, 
, 
. 
4, 8, 16 32 . !
, 
, .

.
, ; 
. 
, ,
 . , 
. ,
, .

CLR
, 
. ,

 ,

, . , CLR 
. , 
. 
, AppDomain .
CLR . 
.
, ,
. 
. , . ,
.
, .
, .
,
. ,
, , 

23

577

. ,
, .
, 
, .
2 ( CLR
) ,
. ,
,
.
:
, 
, 
Hyperthreading. , 
. 
, . 
.
: .
, 
(
). 
. , ,
, , , Web 
, APM (Asynchronous Programming Model).

APM .


CLR
 , CLR ,
. , 

. , .

.
: 1000 
, 1001 .
1000, 1001 , 1000 
. , 
, . 
,
? 
 .
, CLR,
,  . 
CLR 

578

CLR

,
. ,
CLR CLR 2.0
25 2 ,
 1000. , ,
. ,
, 
CLR. , API Win32
.
System.Threading.ThreadPool , 
. :

void GetMaxThreads(out Int32 workerThreads, out Int32 completionPortThreads);


Boolean SetMaxThreads(Int32 workerThreads, Int32 completionPortThreads);
void GetMinThreads(out Int32 workerThreads, out Int32 completionPortThreads);
Boolean SetMinThreads(Int32 workerThreads, Int32 completionPortThreads);
void GetAvailableThreads(out Int32 workerThreads, out Int32 completionPortThreads);
GetMaxThreads .
SetMaxThreads. 
.
, .
25 , ,
. ,
.
, CLR
500 .
, 
.
SetMinThreads .
,
,
500 . 
 1.
, , GetAvailableThreads
, .
. ,
, ,
, 
.
, .

ProcessorCount
System.Environment. .
Hyperthreading 2.

23

579



(, 

)
,
(, . .). 
, .
,

. , APM 
.

, ThreadPool:

static Boolean QueueUserWorkItem(WaitCallback callBack);


static Boolean QueueUserWorkItem(WaitCallback callBack, Object state);
static Boolean UnsafeQueueUserWorkItem(WaitCallback callBack, Object state);
(
) .
callback ,
. , 
state ( ). QueueUserWorkItem
state null .
,
. 
System.Threading.WaitCallback, :

delegate void WaitCallback(Object state);


, 
.

using System;
using System.Threading;
public static class Program {
public static void Main() {
Console.WriteLine("Main thread: queuing an asynchronous operation");
ThreadPool.QueueUserWorkItem(ComputeBoundOp, 5);
Console.WriteLine("Main thread: Doing other work here...");
Thread.Sleep(10000); // (10 ).
Console.WriteLine("Hit <Enter> to end this program...");
Console.ReadLine();
}
// WaitCallback.
private static void ComputeBoundOp(Object state) {
// .

580

CLR

Console.WriteLine("In ComputeBoundOp: state={0}", state);


Thread.Sleep(1000); // (1 ).
// ,
// .
}
}
, .

Main thread: queuing an asynchronous operation


Main thread: Doing other work here...
In ComputeBoundOp: state=5
:

Main thread: queuing an asynchronous operation


In ComputeBoundOp: state=5
Main thread: Doing other work here...
, 
.
, Windows ,
.

, CLR ( 
). . 19.
UnsafeQueueUserWorkItem ThreadPool 
QueueUserWorkItem. , . 
(, ) CLR 
(CAS), 
. 
CLR SecurityException. 
, , , , 
,  .
,
, .
, , 
.
. ,
QueueUserWorkItem
, , 
. , 
, , QueueUserWorkItem.

.
, QueueUserWorkItem
UnsafeQueueUserWorkItem, 
.

23

581

, QueueUserWorkItem, 
. UnsafeQueueUserWorkItem ,
, ,
, 
. , , Unsafe
QueueUserWorkItem, ControlPolicy ControlEvidence
SecurityPermission 
.

( ) .




, . ,
.
,
, . , 
(
, ). 
, ,
(foreground) ( 
). , 
. 
, . 
. , ,
, ,
Abort Thread (. 21).
System.
Threading.Thread .
.

public sealed class Thread : CriticalFinalizerObject, ... {


public Thread(ParameterizedThreadStart start);
// , , .
}
start , .
ParameterizedThreadStart:

delegate void ParameterizedThreadStart(Object obj);


, ParameterizedThreadStart WaitCallback ( 
) . ,
, .
Thread ,
.
,

582

CLR

Start Thread (),


.
.

using System;
using System.Threading;
public static class Program {
public static void Main() {
Console.WriteLine("Main thread: starting a dedicated thread " +
"to do an asynchronous operation");
Thread dedicatedThread = new Thread(ComputeBoundOp);
dedicatedThread.Start(5);
Console.WriteLine("Main thread: Doing other work here...");
Thread.Sleep(10000);
// (10 ).
dedicatedThread.Join();
// .
Console.WriteLine("Hit <Enter> to end this program...");
Console.ReadLine();
}
// ParameterizedThreadStart
private static void ComputeBoundOp(Object state) {
// .
Console.WriteLine("In ComputeBoundOp: state={0}", state);
Thread.Sleep(1000); // (1 ).
// ,
// .
}
}
, :

Main thread: starting a dedicated thread to do an asynchronous operation


Main thread: Doing other work here...
In ComputeBoundOp: state=5
, , ( 
):

Main thread: starting a dedicated thread to do an asynchronous operation


In ComputeBoundOp: state=5
Main thread: Doing other work here...
, , , 
ComputeBoundOp, Main Join.
, , 
dedicatedThread, .
QueueUserWorkItem

23

583

ThreadPool CLR .
Join. ,
QueueUserWorkItem,
, .
APM ( ).

System.Threading Timer,
CLR. Timer
CLR .
Timer .

public sealed class Timer : MarshalByRefObject, IDisposable {


public Timer(TimerCallback callback, Object state,
Int32 dueTime, Int32 period);
public Timer(TimerCallback callback, Object state,
UInt32 dueTime, UInt32 period);
public Timer(TimerCallback callback, Object state,
Int64 dueTime, Int64 period);
public Timer(TimerCallback callback, Object state,
Timespan dueTime, TimeSpan period);
}
Timer. callback
, .
, 
System.Threading.TimerCallback:

delegate void TimerCallback(Object state);


state
null, . dueTime 
CLR ( ) 
. 32 , 64
TimeSpan.
, dueTime 0.
, period, ( ) 
. Timeout.Infinite ( 1),
.
CLR , Timer,
Timer. 
Timer, CLR QueueUserWorkItem
ThreadPool,
. , 
. ,

584

CLR

. :
, 
, .
Timer ,
CLR . , 
Change Dispose ( ):

public sealed class Timer : MarshalByRefObject, IDisposable {


public Boolean Change(Int32
dueTime, Int32
period);
public Boolean Change(UInt32
dueTime, UInt32
period);
public Boolean Change(Int64
dueTime, Int64
period);
public Boolean Change(TimeSpan dueTime, TimeSpan period);
public Boolean Dispose();
public Boolean Dispose(WaitHandle notifyObject);
}
Change Timer, 
Dispose , 
notifyObject, 
.
! Timer CLR 
, . 
Timer , , 
,
(. 20).
, , 
, .

using System;
using System.Threading;
public static class Program {
public static void Main() {
Console.WriteLine("Main thread: starting a timer");
Timer t = new Timer(ComputeBoundOp, 5, 0, 2000);
Console.WriteLine("Main thread: Doing other work here...");
Thread.Sleep(10000); // (10 ).
t.Dispose();
// .
}
// TimerCallback.
private static void ComputeBoundOp(Object state) {
// .
Console.WriteLine("In ComputeBoundOp: state={0}", state);
Thread.Sleep(1000); // (1 ).

23

585

// ,
// .
}
}


FCL , 
, . .
Timer System.Threading 
.
.
Timer System.Windows.Forms 
Windows
(. Win32 SetTimer). 
, Windows (WM_
TIMER). , 
. 
: 
. 
.
Timer System.Timers , , 
Timer System.Threading.
CLR .
System.Timers.Timer Component System.
ComponentModel,  
Microsoft Visual Studio. 
. FCL , Microsoft
. , 
, System.Threading. Timer.
System.Timers.Timer , 
, .


, 
, , 
. 
.
, CLR ,
. 
(APM).
, 
, 
. , 
FCL. .

586

CLR

System.IO.Stream , 
( FileStream NetworkStream), 
BeginRead BeginWrite. : , Stream,
( 
BufferedStream, MemoryStream CryptoStream), 
APM.
, ,
.
System.Net.Dns BeginGetHostAddresses, BeginGetHostBy
Name, BeginGetHostEntry BeginResolve.
System.Net.Sockets.Socket BeginAccept, BeginConnect,
BeginDisconnect, BeginReceive, BeginReceiveFrom, BeginReceiveMessageFrom, Begin
Send, BeginSendFile BeginSendTo.
, System.Net.WebRequest ( FileWebRequest,
FtpWebRequest HttpWebRequest), BeginGetRequestStream
BeginGetResponse.
System.IO.Ports.SerialPort
BaseStream, Stream, , ,
BeginRead BeginWrite.
System.Data.SqlClient.SqlCommand BeginExecuteNon
Query, BeginExecuteReader BeginExecuteXmlReader.
,  BeginInvoke,
APM. ,  Web
( WSDL.exe SvcUtil.exe) 
, Begin, APM. 
, ,
End. , APM FCL.
APM .
: QueueUserWorkItem ThreadPool 

. , 
, 
. , APM , 
, .

APM
-
, 
APM. System.IO.FileStream,
, System.IO.FileOptions.
FileOptions.Asynchronous, 
FileStream, .
FileStream,
Read. :

public Int32 Read(Byte[] array, Int32 offset, Int32 count)

23

587

Read Byte[],
. count , .
array offset (offset + count 1). 
Read , .
. ,
,
.  ,
, 
, 
.
Windows ,
. , Windows
, .
, ,
( ) . , ,
Read, ,
.
Read , , .
, BeginRead
FileStream:

IAsyncResult BeginRead(Byte[] array, Int32 offset, Int32 numBytes,


AsyncCallback userCallback, Object stateObject)
: BeginRead Read .
BeginRead userCallback stateObject. .
BeginRead Windows 
. , BeginRead
. 
,
. !

, ,  
. , NetworkStream 
Windows 
.  
(, DNS, Web 
) 
. 

.
BeginRead , 
System.IAsyncResult. BeginRead ,
, 
Windows, IAsyncResult.
. BeginRead

588

CLR

,  ,
.
.
, ,

BeginRead .
. , ,
, . 
, ,
. (rendezvousing) 
. , APM .
.
FileStream 
( 
) FileOptions.Asynchronous ( 
Win32 CreateFile FILE_FLAG_OVERLAPPED).
, Windows
. , BeginRead FileStream
, ,
FileStream 
.
.
, FileStream, File
Options.Asynchronous. Read FileStream
. FileStream
: 

. , , BeginRead
FileStream, FileOptions.Asynchronous.
: FileStream ,
 (
), ( ) File
Options.Asynchronous.
BeginRead, Read. 
. c FileStream 
, 
FileOptions.Asynchronous.

APM
APM : ,
. .

23

589


, 
Begin (BeginXxx).
IAsyncResult, . 
EndXxx, 
IAsyncResult. , EndXxx 
IAsyncResult. , EndXxx CLR 
,
IAsyncResult ( BeginXxx).
, EndXxx 
, . EndXxx
, .
FileStream. FileStream
EndRead:

Int32 EndRead(IAsyncResult asyncResult)


: IAsyncResult, , ,
(Int32) Read.
EndRead , FileStream.
.

using System;
using System.IO;
using System.Threading;
public static class Program {
public static void Main() {
// -.
FileStream fs = new FileStream(@"C:\Boot.ini", FileMode.Open,
FileAccess.Read, FileShare.Read, 1024,
FileOptions.Asynchronous);
Byte[] data = new Byte[100];
// FileStream.
IAsyncResult ar = fs.BeginRead(data, 0, data.Length, null, null);
//
//
// .
Int32 bytesRead = fs.EndRead(ar);
// . .
fs.Close();
// .
Console.WriteLine("Number of bytes read={0}", bytesRead);

590

CLR

Console.WriteLine(BitConverter.ToString(data, 0, bytesRead));
}
}
,
( , 
):

Number of bytes read=100


5B-62-6F-6F-74-20-6C-6F-61-64-65-72-5D-0D-0A-74-69-6D-65-6F75-74-3D-33-30-0D-0A-64-65-66-61-75-6C-74-3D-6D-75-6C-74-6928-30-29-64-69-73-6B-28-30-29-72-64-69-73-6B-28-30-29-70-6172-74-69-74-69-6F-6E-28-31-29-5C-57-49-4E-44-4F-57-53-0D-0A5B-6F-70-65-72-61-74-69-6E-67-20-73-79-73-74-65-6D-73-5D-0D
APM . 
BeginXxx, EndXxx, 
. 
Read,
.
, BeginRead EndRead ,
APM :
. , .
. 
FileStream, ,
Stream
, .
AsyncStreamRead 
.

private static void ReadMultipleFiles(params String[] pathnames) {


AsyncStreamRead[] asrs = new AsyncStreamRead[pathnames.Length];
for (Int32 n = 0; n < pathnames.Length; n++) {
// -.
Stream stream = new FileStream(pathnames[n], FileMode.Open,
FileAccess.Read, FileShare.Read, 1024,
FileOptions.Asynchronous);
// Stream.
asrs[n] = new AsyncStreamRead(stream, 100);
}
// Stream ,
// .
// !
// .
for (Int32 n = 0; n < asrs.Length; n++) {
Byte[] bytesRead = asrs[n].EndRead();

23

591

// .
Console.WriteLine("Number of bytes read={0}", bytesRead.Length);
Console.WriteLine(BitConverter.ToString(bytesRead));
}
}
private sealed class AsyncStreamRead {
private Stream
m_stream;
private IAsyncResult m_ar;
private Byte[]
m_data;
public AsyncStreamRead(Stream stream, Int32 numBytes) {
m_stream = stream;
m_data = new Byte[numBytes];
// Stream.
m_ar = stream.BeginRead(m_data, 0, numBytes, null, null);
}
public Byte[] EndRead() {
//
// .
Int32 numBytesRead = m_stream.EndRead(m_ar);
// , .
m_stream.Close();
// .
Array.Resize(ref m_data, numBytesRead);
// .
return m_data;
}
}
,
.
ReadMultipleFiles , 
EndRead
. , 
. ,
.
, , , 
. APM , 
, , .

592

CLR


IAsyncResult :

public interface IAsyncResult {


Object
AsyncState
WaitHandle
AsyncWaitHandle
Boolean
IsCompleted
Boolean
CompletedSynchronously
}

{
{
{
{

get;
get;
get;
get;

}
}
}
}

AsyncState. AsyncWaitHandle IsCompleted


, .
CompletedSynchronously , 
BeginXxx EndXxx ( ).
, 
, . ,
, CLR, 
. . , 
, 
. .

public static void PollingWithIsCompleted() {


// -.
FileStream fs = new FileStream(@"C:\Boot.ini", FileMode.Open,
FileAccess.Read, FileShare.Read, 1024,
FileOptions.Asynchronous);
Byte[] data = new Byte[100];
// FileStream.
IAsyncResult ar = fs.BeginRead(data, 0, data.Length, null, null);
while (!ar.IsCompleted) {
Console.WriteLine("Operation not completed; still waiting.");
Thread.Sleep(10);
}
// .
// : EndRead .
Int32 bytesRead = fs.EndRead(ar);
// . .
fs.Close();
// .
Console.WriteLine("Number of bytes read={0}", bytesRead);
Console.WriteLine(BitConverter.ToString(data, 0, bytesRead));
}

23

593

BeginRead ,
IsCompleted IasyncResult, false, 
, true. 
, : Operation not
completed; still waiting. ( . .)
Sleep, ,
, . 
, Is
Completed, true .
, IsCompleted
true, . EndRead 
. , EndRead 
.
, 
AsyncWaitHandle IAsyncResult.

public static void PollingWithAsyncWaitHandle() {


// -.
FileStream fs = new FileStream(@"C:\Boot.ini", FileMode.Open,
FileAccess.Read, FileShare.Read, 1024,
FileOptions.Asynchronous);
Byte[] data = new Byte[100];
// FileStream.
IAsyncResult ar = fs.BeginRead(data, 0, data.Length, null, null);
while (!ar.AsyncWaitHandle.WaitOne(10, false)) {
Console.WriteLine("Operation not completed; still waiting.");
}
// . : EndRead .
Int32 bytesRead = fs.EndRead(ar);
// . .
fs.Close();
// .
Console.WriteLine("Number of bytes read={0}", bytesRead);
Console.WriteLine(BitConverter.ToString(data, 0, bytesRead));
}
AsyncWaitHandle IAsyncResult ,
WaitHandle, System.Threading.ManualResetEvent.
24 WaitHandle .
,
Sleep , WaitOne 
10 .

594

CLR


APM
.
, 
( ) 
, 
( 
).
. 
, .
 , Windows
CLR.

. ,

EndXxx, 
. ,
(, 
, ).
, .
BeginRead FileStream:

IAsyncResult BeginRead(Byte[] array, Int32 offset, Int32 numBytes,


AsyncCallback userCallback, Object stateObject)
BeginRead, BeginXxx 
System.AsyncCallback Object.AsyncCallback. 
, :

delegate void AsyncCallback(IAsyncResult ar);


,
. stateObject BeginXxx
. 
, , , 
.
IAsyncResult, ,
AsyncState IAsyncResult. 
.

using System;
using System.IO;
using System.Threading;
public static class Program {
// , Main
// ReadIsDone.
private static Byte[] s_data = new Byte[100];

23

595

public static void Main() {


// , Main.
Console.WriteLine("Main thread ID={0}",
Thread.CurrentThread.ManagedThreadId);
// -.
FileStream fs = new FileStream(@"C:\Boot.ini", FileMode.Open,
FileAccess.Read, FileShare.Read, 1024,
FileOptions.Asynchronous);
// FileStream.
// FileStream (fs) (ReadIsDone).
fs.BeginRead(s_data, 0, s_data.Length, ReadIsDone, fs);
// .
// .
Console.ReadLine();
}
private static void ReadIsDone(IAsyncResult ar) {
// , ReadIsDone.
Console.WriteLine("ReadIsDone thread ID={0}",
Thread.CurrentThread.ManagedThreadId);
// FileStream (state) IAsyncResult.
FileStream fs = (FileStream) ar.AsyncState;
// .
Int32 bytesRead = fs.EndRead(ar);
// . .
fs.Close();
// .
Console.WriteLine("Number of bytes read={0}", bytesRead);
Console.WriteLine(BitConverter.ToString(s_data, 0, bytesRead));
}
}
,
( ,
):

Main thread ID=1


ReadIsDone thread ID=4
Number of bytes read=100
5B-62-6F-6F-74-20-6C-6F-61-64-65-72-5D-0D-0A-74-69-6D-65-6F75-74-3D-33-30-0D-0A-64-65-66-61-75-6C-74-3D-6D-75-6C-74-6928-30-29-64-69-73-6B-28-30-29-72-64-69-73-6B-28-30-29-70-6172-74-69-74-69-6F-6E-28-31-29-5C-57-49-4E-44-4F-57-53-0D-0A5B-6F-70-65-72-61-74-69-6E-67-20-73-79-73-74-65-6D-73-5D-0D

596

CLR

, Main 
1, ReadIsDone 4.
, 
. , IAsyncResult, BeginRead,
Main. , CLR
IAsyncResult . ,
BeginRead. , 
fs BeginRead. FileStream
. FileStream, 
AsyncState IAsyncResult.
:
Byte[] ( s_data) ,
Main ReadIsDone. ,
, 
. 
 Byte[] 
. .
, Byte[] FileStream,
,
BeginRead.
.
C# (. 15), 
C# .
C#:

public static void Main() {


// , Main.
Console.WriteLine("Main thread ID={0}",
Thread.CurrentThread.ManagedThreadId);
// -.
FileStream fs = new FileStream(@"C:\Boot.ini", FileMode.Open,
FileAccess.Read, FileShare.Read, 1024,
FileOptions.Asynchronous);
Byte[] data = new Byte[100];
// FileStream.
// FileStream (fs) (ReadIsDone).
fs.BeginRead(data, 0, data.Length,
delegate(IAsyncResult ar)
{
// , ReadIsDone.
Console.WriteLine("ReadIsDone thread ID={0}",
Thread.CurrentThread.ManagedThreadId);
// .
Int32 bytesRead = fs.EndRead(ar);

23

597

// , .
fs.Close();
// .
Console.WriteLine("Number of bytes read={0}", bytesRead);
Console.WriteLine(BitConverter.ToString(data, 0, bytesRead));
}, null);
// .
//
// .
Console.ReadLine();
}
null 
BeginRead.  , 
( data fs), 
Main. , :

.

Main .
ReadLine Console, Main
, ,
.

, .
, .


, .

.
?

.

ReadMultipleFiles, .
, 
, . ,
. , 
, 
APM .

598

CLR

private static void ReadMultipleFiles(params String[] pathnames) {


for (Int32 n = 0; n < pathnames.Length; n++) {
// -.
Stream stream = new FileStream(pathnames[n], FileMode.Open,
FileAccess.Read, FileShare.Read, 1024,
FileOptions.Asynchronous);
// Stream.
new AsyncStreamRead(stream, 100,
delegate(Byte[] data)
{
// .
Console.WriteLine("Number of bytes read={0}", data.Length);
Console.WriteLine(BitConverter.ToString(data));
});
}
// , .
// .
//
// .
Console.WriteLine("Hit <Enter> to end this program...");
Console.ReadLine();
}
private delegate void StreamBytesRead(Byte[] streamData);
private sealed class AsyncStreamRead {
private Stream m_stream;
private Byte[] m_data;
StreamBytesRead m_callback;
public AsyncStreamRead(Stream stream, Int32 numBytes,
StreamBytesRead callback) {
m_stream = stream;
m_data = new Byte[numBytes];
m_callback = callback;
// Stream.
stream.BeginRead(m_data, 0, numBytes, ReadIsDone, null);
}
// -.
private void ReadIsDone(IAsyncResult ar) {
Int32 numBytesRead = m_stream.EndRead(ar);
// , .
m_stream.Close();

23

599

// .
Array.Resize(ref m_data, numBytesRead);
// .
m_callback(m_data);
}
}

APM

APM
. 
: .
. 
, 
. , 
.
APM, , 
, . ,
, 1 n. (
) , n 3 .
Sum:

private static UInt64 Sum(UInt64 n) {


UInt64 sum = 0;
for (UInt64 i = 1; i <= n; i++) {
checked {
// checked, ,
// UInt65, OverflowExcept.
sum += i;
}
}
return sum;
}
n , Sum .

, .
, ,
(Sum):

internal delegate UInt64 SumDelegate(UInt64 n);


15, : C# 
, :
3

, n(n+1)/2 n.
,
.

600

CLR

internal sealed class SumDelegate : MulticastDelegate {


public SumDelegate(Object object, IntPtr method);
public UInt64 Invoke(UInt64 n);
public IAsyncResult BeginInvoke(UInt64 n,
AsyncCallback callback, Object object);
public UInt64 EndInvoke(IAsyncResult result);
}
C# 
, BeginInvoke EndInvoke. 
, ,
AsyncCallback Object. BeginInvoke IAsyncResult.
EndInvoke ; IAsyncResult; EndInvoke 
.
,
, APM.

: , 
. 
Sum .

public static void Main() {


// ,
// , .
SumDelegate sumDelegate = Sum;
// .
sumDelegate.BeginInvoke(1000000000, SumIsDone, sumDelegate);
//
// .
Console.ReadLine();
}
sumDelegate , 
.
BeginInvoke. CLR IAsyncResult, 
. , 
Windows. BeginInvoke
CLR,
QueueUserWorkItem ThreadPool. , , BeginInvoke
IAsyncResult . ,
.
BeginInvoke
CLR, ,
(, Sum). , 
, . Begin
Invoke Sum
IsDone. , Sum ,

23

601

, SumIsDone. , 
,
. SumIsDone :

private static void SumIsDone(IAsyncResult ar) {


// SumDelegate (state) IAsyncResult.
SumDelegate sumDelegate = (SumDelegate) ar.AsyncState;
// .
UInt64 sum = sumDelegate.EndInvoke(ar);
// .
Console.WriteLine("Sum={0}", sum);
}

APM
BeginXxx ,
, 
.

Windows , Windows 
. , Windows
. ,
.
Windows CLR.
, EndXxx. EndXxx 
, , , EndXxx
. .
, APM
( ) 
, . 
, CLR . 

. EndInvoke
.
, CLR (
).
.
SumIsDone ( ) :
OverflowException 
.

private static void SumIsDone(IAsyncResult ar) {


// SumDelegate (state) IAsyncResult.
SumDelegate sumDelegate = (SumDelegate)ar.AsyncState;
try {
// . OverflowException.
UInt64 sum = sumDelegate.EndInvoke(ar);

602

CLR

// .
Console.WriteLine("Sum={0}", sum);
}
catch (OverflowException) {
// EndInvoke OverflowException.
// .
Console.WriteLine("Sum cant be shown: number is too big.");
}
}

APM
APM, , 
. , Microsoft
, . .
, EndXxx.
, BeginXxx 
; ,
EndXxx. . 
, CLR 
. CLR
EndXxx. , 
. , 
. , EndXxx
.
EndXxx .
EndXxx , 
. EndXxx
. EndXxx
: , ,
IAsyncResult. Microsoft 
, . ,
EndXxx .
BeginXxx EndXxx . ,
BeginInvoke,
( , /) 
EndInvoke. ,
( ), ,
IAsyncResult ,
BeginInvoke, , EndInvoke
InvalidOperationExcept : The IAsyncResult object provided does
not match this delegate ( IAsyncResult
). , BeginInvoke
EndInvoke , 
.
BeginXxx EndXxx 
, ,  

23

603

 out/ref ,
params. , 
, . ,
.

. ,
. 1000 , 
, . 
, . 
: 
. ? 
,
. BeginXxx
, IAsyncResult, 
. .
BeginXxx ,
.
BeginXxx ,
IAsyncResult. ,
.
, . 
. , ,
 , 
. ( ) ,
APM 
, 
. , Microsoft  CLR, 
.
Win32 API , , , 
 . , 
CreateFile ( FileStream) .
/ CreateFile 

. ,
Win32, / 
, . ,
Win32 , CreateFile, . 
FCL .
BeginInvoke 
, . ,
.
FileStream ,
FileStream. Windows
, , ,
/. .

604

CLR

Windows ,
. , 16 Windows
32 64

, WM_MOVE, WM_SIZE, WM_PAINT, WM_CLOSE .
Windows Forms , 
. Windows Forms Windows, 
, 
, System.Windows.Forms.Control.
, System.Windows.Forms.Control Invoke, Begin
Invoke EndInvoke, (
), ,
. Invoke Control Win32 SendMessage,
. BeginInvoke Control
Win32 PostMessage, . 
, ,
EndInvoke Control. ,
, EndInvoke .


,
:
( , 
IPermission, Principal Thread Windows);
( CurrentCulture CurrentUICulture 
Thread Windows);
( Current System.Trans
actions.Transaction).
, 
. , 
() 
, 
. , , ,
,
, .
CLR
. ,
, 
. 
, CLR 
 .
ExecutionContext System.Threading 
.
, 
. Execution

23

605

Context , SecurityPermission
SecurityPermissionFlag.Infrastructure. ,
,

. , ,
,
(, ).
Exection
Context
. 
, .
, CLR. 
, , 
( ),

. (
ReadME.txt C:.)

using
using
using
using
using

System;
System.IO;
System.Security;
System.Threading;
System.Security.Permissions;

public static class Program {


public static void Main() {
// , , .
AttemptAccess("Default context");
// ,
// .
new FileIOPermission(PermissionState.Unrestricted).Deny();
// ,
// - .
AttemptAccess("No file permissions");
ECFlowing();
ECFlowingSuppressed();
// .
ExecutionContext ec = ExecutionContext.Capture();
// ,
// .
SecurityPermission.RevertDeny();
// .
AttemptAccess("Default context again");

606

CLR

ECCaptureAndRun(ec);
}
private static void ECFlowing() {
//
// .
WaitCallback wc = AttemptAccess;
// .
// EndInvoke ,
// .
wc.EndInvoke(wc.BeginInvoke("ECFlowing", null, null));
}
private static void ECFlowingSuppressed() {
// ,
// .
WaitCallback wc = AttemptAccess;
//
// .
using (AsyncFlowControl afc = ExecutionContext.SuppressFlow()) {
wc.EndInvoke(wc.BeginInvoke("ECFlowingSuppressed", null, null));
}
}
private static void ECCaptureAndRun(ExecutionContext ec) {
// AttemptAccess
// .
ExecutionContext.Run(ec, AttemptAccess,
"ECCaptureAndRun with Run");
}
private static void AttemptAccess(Object test) {
// , .
Boolean success = false;
try {
// .
File.GetAttributes(@"C:\ReadMe.txt");
// , .
success = true;
}
catch (SecurityException) {
// -
// .
}
// : .
Console.WriteLine("{0}: {1}", test, success);
}
}

23

, :

Default context: True


No file permissions: False
ECFlowing: False
ECFlowingSuppressed: True
Default context again: True
ECCaptureAndRun with Run: False

607

2 4

23, 
, . 
, , 
,  . 
, , 
.
: , 
, , . 
, ,
, . ,
.
, , 
. ,
 . ,
.

, .
Windows CLR ,
. . 
,
. ,
, ,
Concurrent Affairs MSDN (, http://msdn.microsoft.com/
msdnmag/issues/05/10/ConcurrentAffairs/). 
Power Threading Library ( http://wintellect.com), 
. 
.
CLR
 , 
Win32. , CLR 
Windows, , Windows
. Windows 1992
, . ( Prog
ramming Applications for Microsoft Windows (Microsoft Press, 2000) 

24

609

.) 
.

, 
, 

.
, . 

,
.
, Load

. 
, 
. , AppDomain
. CLR 
,
Assembly
( , ).
,

. ,
, 
;
. , ,
,
 . , 
, 
, , 
, , .
, Microsoft .
Framework Class Library
, , 
.

,
volatile-

.
,
.
, 
. ,

610

CLR

, 
( ),
, .
, ;
,
. ,

. .
, .
(
Hyperthreading),
, .
.
Hyperthreading,
, .
,
, 
, .
, ,
.
, .
:

internal sealed class CacheCoherencyProblem {


private Byte m_initialized = 0;
private Int32 m_value = 0;
// .
public void Thread1() {
m_value = 5;
m_initialized = 1;
}
// .
public void Thread2() {
if (m_initialized == 1) {
// 0.
Console.WriteLine(m_value);
}
}
}
, 
. Thread1, 
Thread2. , .
, 
m_value .
, , m_value 

24

611

. ,
, .
Thread1,
m_value 5,
. ,
. ,
, .
Thread1
m_initialized 1. 
, m_initialized , 
.
Thread2,
m_initialized.
, .
m_initialized 1,
if .
Thread2,
m_value.
, ,
, m_value 0!
, , . : 
, , 
.
,
, .
,
. , ,
, 
. , 
, ,
, , .
,
, .
, .
, C# JIT 

, .
.
C# JIT , 
, , 
(
),
.
, , ,
 ,

612

CLR

. , , ,
Hyper
threading.
. , 
 . ,
x86 .
x64 x86, x64
. , Cache
CoherencyProblem x86 x64, 
. Thread2 , 5.
(, IA64)
,
,
. IA64

. ,
, , 
. 
(volatile read) (read
with acquire semantics). IA64
,
, ,
, .
(volatile write) (write with release seman
tics). , IA64
(memory fence), ,
.


,
, 
. , CLR
. ,
CLR , 
,  
.
.
System.Threading.Thread ,
:

static
static
static
static
static
static
static

Object
Byte
SByte
Int16
UInt16
Int32
UInt32

VolatileRead(ref
VolatileRead(ref
VolatileRead(ref
VolatileRead(ref
VolatileRead(ref
VolatileRead(ref
VolatileRead(ref

Object address);
Byte address);
SBbyte address);
Int16 address);
UInt16 address);
Int32 address);
UInt32 address);

24

static
static
static
static
static
static

Int64
UInt64
IntPtr
UIntPtr
Single
Double

static
static
static
static
static
static
static
static
static
static
static
static
static

void
void
void
void
void
void
void
void
void
void
void
void
void

VolatileRead(ref
VolatileRead(ref
VolatileRead(ref
VolatileRead(ref
VolatileRead(ref
VolatileRead(ref

VolatileWrite(ref
VolatileWrite(ref
VolatileWrite(ref
VolatileWrite(ref
VolatileWrite(ref
VolatileWrite(ref
VolatileWrite(ref
VolatileWrite(ref
VolatileWrite(ref
VolatileWrite(ref
VolatileWrite(ref
VolatileWrite(ref
VolatileWrite(ref

613

Int64 address);
UInt64 address);
IntPtr address);
UIntPtr address);
Single address);
Double address);

Object address, Object value);


Byte address, Byte value);
SByte address, SByte value);
Int16 address, Int16 value);
UInt16 address, UInt16 value);
Int32 address, Int32 value);
UInt32 address, UInt32 value);
Int64 address, Int64 value);
UInt64 address, UInt64 value);
IntPtr address, IntPtr value);
UIntPtr address, UIntPtr value);
Single address, float value);
Double address, Double value);

static void MemoryBarrier();


VolatileRead ; 
, address, 
. VolatileWrite
; , 
, address, value.
MemoryBarrier 
, .
CacheCoherencyProblem
VolatileMethod:

internal sealed class VolatileMethod {


private Byte m_initialized = 0;
private Int32 m_value = 0;
// .
public void Thread1() {
m_value = 5;
Thread.VolatileWrite(ref m_initialized, 1);
}
// .
public void Thread2() {
if (Thread.VolatileRead(ref m_initialized) == 1) {
// , 5.
Console.WriteLine(m_value);
}
}
}

614

CLR

!
,
.
. 
.

volatile- C#
, VolatileRead
VolatileWrite . 
, , 
. C# volatile, 
: Byte,
SByte, Int16, UInt16, Int32, UInt32, Char, Single Boolean.
, 
Byte, SByte, Int16, UInt16, Int32, UInt32, Single
Boolean. JIT , volatile
, 
 VolatileXxx. ,
volatile C# JIT, 
,
, .1
volatile VolatileMethod
VolatileField:

internal sealed class VolatileField {


private volatile Byte m_initialized = 0;
private Int32 m_value = 0;
// .
public void Thread1() {
m_value = 5;
m_initialized = 1;
}
// .
public void Thread2() {
if (m_initialized == 1) {
// , 5.
Console.WriteLine(m_value);
}
}
}
C# ( )
volatile ,
1

, volatile
C/C++ .

24

615

. ,
,
, , , 
. , 
. , , 
, :

m_amount = m_amount + m_amount; // m_amount  .


m_amount *= m_amount
, C# volatile .
, m_amount volatile Int32, 
TryParse Int32 :

Boolean success = Int32.TryParse("123", out m_amount);


// C# :
// CS0420: a reference to a volatile field will not be treated as volatile
// (CS0420: volatile ).
JIT IA64, CLR ,
( ) ,
()
. , JIT IA64
, ,
. 
, x86, IA64.
, ,
. JIT IA64 
, . 
, VolatileRead
volatile. 
, .
Microsoft , JIT 
,
, .
, . , 
.
1, ECMA 
CLR, Common Language Infrastructure (CLI).
ECMA , 
CLI . 

, VolatileRead
VolatileWrite volatile. 
, FCL VolatileWrite, 
, CLR, Microsoft.
Microsoft ECMA ,
CLI ( CLR), 

616

CLR

, 
. 
CLR Microsoft ,
, ECMA, CLR
Microsoft.
, ,

CLR Microsoft. ,
CLI . ,
ECMA 
. Microsoft , 
ECMA , 
CLR.
, , , Interlocked
(. ),
. Interlocked
. ,
(Monitor, ReaderWriterLock, Mutex, Semaphore, AutoResetEvent,
ManualResetEvent ) Interlocked,
.
! , 
VolatileRead VolatileWrite, volatile.
Interlocked 
. ,
.

Interlocked-
, 
. Interlocked
. ( 
) . :
. System.Threading.Interlocked 
, 
. , Int32, 
:

public static class Interlocked {


// (location++).
public static Int32 Increment(ref Int32 location);
// (location).
public static Int32 Decrement(ref Int32 location);
// (location1 += value).
// : ,

24

617

// .
public static Int32 Add(ref Int32 location1, Int32 value);
// (location1 = value).
public static Int32 Exchange(ref Int32 location1, Int32 value);
// :
// if (location1 == comparand) location1 = value
public static Int32 CompareExchange(ref Int32 location1,
Int32 value, Int32 comparand);
...
}
, Interlocked Exchange CompareExchange,
Object, IntPtr, Single Double.
, class ( ). Inter
locked ,
, DataMisalignedException. , CLR
, [StructLayout(LayoutKind.
Explicit)] , [FieldOffcet()]
.
! Interlocked , 
Int64. , 
CLR .
Concurrent Affairs MSDN
, Interlocked.
http://MSDN.Microsoft.com/MSDNMag/Issues/
05/10/ConcurrentAffairs/Default.aspx.

Monitor
Win32 API CRITICAL_SECTION

, 
. ,
, . CLR 
CRITICAL_SECTION, , 

. , System.Threading.
Monitor .
, 
CLR. , , Monitor 
. 
, , .

618

CLR


CLR  . , 
, , .
, , ,
. CLR 
Microsoft ,
.
: (
CRITICAL_SECTION Win32),
. FCL (Framework Class Library) 
, .

.
Win32 C++
:

class SomeType {
private:
// CRITICAL_SECTION, .
CRITICAL_SECTION m_csObject;
public:
SomeType() {
// CRITICAL_SECTION .
InitializeCriticalSection(&m_csObject);
}
~SomeType() {
// CRITICAL_SECTION .
DeleteCriticalSection(&m_csObject);
}
void SomeMethod() {
// CRITICAL_SECTION
// .
EnterCriticalSection(&m_csObject);
// , .
LeaveCriticalSection(&m_csObject);
}
void AnotherMethod() {
// CRITICAL_SECTION
// .
EnterCriticalSection(&m_csObject);
// ...
LeaveCriticalSection(&m_csObject);
}
};

24

619

, CLR
CRITICAL_SECTION
. , ,
, .


, CRITICAL_SECTION (
24 32 40 64)
,
. ,
CLR
. : 
CLR . 
, .
, Win32 CRITICAL_SECTION.
, , 
. , ,
,  . 
, ,
.

, , ,
. , 
, CLR 
, 
. ,
. 
, 
, , .
. 241 .

, .

, , .
. , 
,
, , 
.

620

CLR

. 241. (
) CLR

Monitor

, 
. /
, ,
System.Threading.Monitor. , ,
:

static void Enter(Object obj);


,
; ,
. , CLR 

.
Monitor.Enter
. , .
, 
, .
, Monitor.Enter
Monitor.TryEnter ( ):

static Boolean TryEnter(Object obj);


static Boolean TryEnter(object obj, Int32 millisecondsTimeout);
static Boolean TryEnter(Object obj, TimeSpan timeout);

24

621

,
true.

. false,
.
,
, 
.
Monitor.Exit:

static void Exit(Object obj);


, Monitor.Exit, 
, SynchronizationLockException. ,
,
Monitor.Enter Monitor.TryEnter
Monitor.Exit .

, Microsoft
, , Microsoft
Monitor :

internal sealed class Transaction {


// , .
private DateTime timeOfLastTransaction;
public void PerformTransaction() {
Monitor.Enter(this); // Enter this objects lock
// ...
// .
timeOfLastTransaction = DateTime.Now;
Monitor.Exit(this); // .
}
// , .
public DateTime LastTransaction {
get {
Monitor.Enter(this); // .
//
// .
DateTime dt = timeOfLastTransaction;
Monitor.Exit(this); // .
return dt; // .
}
}
}

622

CLR

, Enter Exit Monitor


. : 
Enter Exit 
dt. 
, PerformTrans
action .
! ,
Microsoft
. 
, 
. , , 
.

C# lock
Monitor.Enter 
Monitor.Exit , C#
.
:

private void SomeMethod() {


lock (this) {

// ...
}

private void SomeMethod() {


Object temp = this;
Monitor.Enter(temp);
try {
// ...
}
finally {
Monitor.Exit(temp);
}
}

}
lock Transaction. , 
LastTransaction; .

internal sealed class Transaction {


// , .
private DateTime timeOfLastTransaction;
public void PerformTransaction() {
lock (this) { // Enter this objects lock
// ...

}
}

// .
timeOfLastTransaction = DateTime.Now;
// .

24

623

// , .
public DateTime LastTransaction {
get {
lock (this) { // .
return timeOfLastTransaction; // .
} // .
}
}
}
, , lock
Monitor.Exit, , ,
lock .

. lock C# ,
.
! , 
, Microsoft
. 
, .

,
Microsoft
Transaction ,
. , 
, ? 
, , , 
, , Enter Exit
Monitor.
. 241 , A, B C 
TypeT (). ,
. 4,  ,
, :
. ,
,  Monitor, Enter,
TryEnter Exit. Transaction
, PerformTransaction LastTransaction 
, Microsoft 
.

internal static class Transaction {


// , .
private static DateTime timeOfLastTransaction;
public static void PerformTransaction() {
lock (typeof(Transaction)) { // Enter the type objects lock
// ...

624

CLR

// .
timeOfLastTransaction = DateTime.Now;
// .

}
// , .
public static DateTime LastTransaction {
get {
lock (typeof(Transaction)) { // .
return timeOfLastTransaction; // .
} // .
}
}
}
get
this, . 
lock  ( 
typeof C#).
! , 
, Microsoft
. 
, .
, 
.



, . Microsoft
CLR.
. , C++,
? ,
CRTICAL_SECTION ? , , ! 
CRTICAL_SECTION. 
, 
.

, ! ,
, Enter
Exit . ,
 .
String, 
. , 
MarshalByRefObject ,
,  ( ).
, Microsoft
.

24

625

, ,
. Main SomeType
.  
( ),
Finalize SomeType, 
. CLR 
, .
CLR (
AppDomain ) , 
, !

using System;
using System.Threading;
public sealed class SomeType {
// Finalize SomeType.
~SomeType() {
// CLR
// .
// : Main,
// !
Monitor.Enter(this);
}
}
public static class Program {
public static void Main() {
// SomeType.
SomeType st = new SomeType();
//
// .
Monitor.Enter(st);
//
// .
st = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("We never get here, both threads are deadlocked!");
}
}
, CLR, FCL ,
. 10 
. CLR
.
System.Runtime.CompilerServices 
MethodImplAttribute. , 

626

CLR

MethodImplOptions.Synchronized. ,
JIT lock(this).
, lock(typeof(<_>)),
<_> . ,
MethodImplAttribute MethodImpl
Options.Synchronized.
CLR, FCL C#, 
, 
.
System.Object , , 
lock. Transaction,
:

internal sealed class TransactionWithLockObject {


// , .
private Object m_lock = new Object();
// , .
private DateTime timeOfLastTransaction;
public void PerformTransaction() {
lock (m_lock)
{ // .
// ...

// .
timeOfLastTransaction = DateTime.Now;
// .

}
// , .
public DateTime LastTransaction {
get {
lock (m_lock){ // .
return timeOfLastTransaction; // .
} // .
}
}
}
! , , 
. 
.
, , 
.
Monitor System.Object 
. , Microsoft Monitor 
. , 
Monitor.

24

627

,
System.Object
Monitor. 
. , 
static.
 , 
,
Monitor. , 
System.Object. 
;
lock(this). , , 
.
! 
Monitor.Enter lock C#. 
,
. 
Monitor.Enter, 
C# . 
Monitor.Exit, . 
, ,
.
lock,
: error CS0185: valuetype is not a reference
type as required by the lock statement ( CS0185:
, lock).
, Mo
nitor.Enter Monitor.Exit .


, (doublecheck
locking). , singleton
, [
(lazy initialization)]. ,
, .
, 
singleton.  
, singleton .
,
. Java, 
, Java . 
, , http://
www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html.
CLR , Microsoft ,
. Microsoft ,
CLR , 

628

CLR

volatile. 
. , , 
C#:

public sealed class Singleton {


// s_lock .
// , singleton
// , System.Object,
// .
// singleton .
private static Object s_lock = new Object();
// CLR ,
// ECMA. , .
private static volatile Singleton s_value;
// ,
// .
private Singleton() { }
// ,
// singleton ( ).
public static Singleton Value {
get {
// singleton?
if (s_value == null) {
// , .
lock (s_lock) {
// ?
if (s_value == null) {
// , , .
// , singleton
// ( ) ,
// .
s_value = new Singleton();
}
}
}
// singleton.
return s_value;
}
}
}
,
 get s_value, ,
, , . ,
, 
. , , 

24

629

value, , , 
,
singleton. ,
, singleton.
, JIT s_value
 get 
if. JIT
, if true
singleton . ,
. JIT , ,
volatile, . , JIT 
, ,
(, Monitor.Enter Monitor.Exit).2
, 
. , 
, . 
. Singleton, 
, , 
.

public sealed class Singleton {


private static Singleton s_value = new Singleton();
// 
// .
private Singleton() { }
// , singleton.
public static Singleton Value {
get {
return s_value; // singleton.
}
}
}
CLR
, , 
 get Value Singleton, CLR 
2

JIT , Monitor.Enter ( 
) . , JIT 
. 
, , , 
, JIT .
, ,
.
JIT ,
, 
. , JIT
, 
.

630

CLR

, . , CLR

8.
, 
,
( )
. ,
singleton, 
. , , singleton
, , 
.

ReaderWriterLock
, 
(multiplereader/singlewriter).
,
. () 
, () .
:
, ;
, ;
, ;
, .
FCL ReaderWriterLock, 
.
. ReaderWriterLock ,
. , , 
, , 
, .
, .
, 
. ,
. , 
ReaderWriterLock ,
Monitor.
, , 
,
. ReaderWriterLock 
, , . 
, ,
, , 
, (
Monitor).
ReaderWriterLock ,
. , 

24

631

ReaderWriterLock,  , 
,
.
, ReaderWriterLock .

. 
. , 
,  , 
.
, 23.
, , ReaderWriterLock Monitor,
.
/ 
, 
Power Threading ( http://Wintellect.com). 
/ OneManyResourceLock 
, Monitor. 
, , .

Windows

Windows
: , . 
CLR. ,
,
, Programming
Applications for Microsoft Windows, 4 Edition, Microsoft Press, 1999 (Windows
: Win32 
64 Windows, 4 ., .: , .: 
, 2001).
Monitor ReaderWriterLock 
AppDomain,
AppDomain . 
, ,
. ,
, 
. 
. ,
ReaderWriterLock. ,
33 Monitor.
System.Threading WaitHandle.
,
. FCL , WaitHandle.
System.Threading
MSCorLib.dll. Semaphore,
System.dll. :

632

CLR

WaitHandle
Mutex
Semaphore
EventWaitHandle
AutoResetEvent
ManualResetEvent
WaitHandle , Win32
. ,
WaitHandle. , WaitHandle , 
. 
WaitHandle
( ):

public abstract class WaitHandle : MarshalByRefObject, IDisposable {


// Close Win32 CloseHandle.
public virtual void Close();
// WaitOne Win32 WaitForSingleObjectEx.
public virtual Boolean WaitOne();
public virtual Boolean WaitOne(
Int32 millisecondsTimeout, Boolean exitContext);
// WaitAny Win32 WaitForMultipleObjectsEx.
public static Int32 WaitAny(WaitHandle[] waitHandles);
public static Int32 WaitAny(WaitHandle[] waitHandles,
Int32 millisecondsTimeout, Boolean exitContext);
// WaitAll Win32 WaitForMultipleObjectsEx.
public static Boolean WaitAll(WaitHandle[] waitHandles);
public static Boolean WaitAll(WaitHandle[] waitHandles,
Int32 millisecondsTimeout, Boolean exitContext);
//
public static
WaitHandle
public static
WaitHandle

SignalAndWait Win32 SignalObjectAndWait.


Boolean SignalAndWait(WaitHandle toSignal,
toWaitOn);
Boolean SignalAndWait(WaitHandle toSignal,
toWaitOn, Int32 millisecondsTimeout, Boolean exitContext);

public const Int32 WaitTimeout = 0x102;


}
:
Close WaitHandle (
Dispose IDisposable), 
. Win32 Close
Handle.
WaitOne WaitHandle,
. 
Win32 WaitForSingleObjectEx. , 
true.  false.

24

633

WaitAny WaitHandle,
, Wait
Handle[]. Int32 ,
WaitHandle.WaitTimeout,
 .
Win32 WaitForMultipleObjectsEx,
bWaitAll false.
WaitAll WaitHandle,
, Wait
Handle[]. ,
true, ( ) false.
Win32 WaitForMultipleObjectsEx, 
bWaitAll true.
SignalAndWait WaitHandle ,
.
, true.  
false. Win32 SignalObjectAndWait.
WaitOne, WaitAll SignalAndWait, 
, void, Boolean. 
true, 
. 
.
WaitOne, WaitAll, WaitAny SignalAndWait,
exitContext, false. CLR 
, System.Runtime.
Remotin.Contexts.ContextAttribute System.Runtime.Remoting.Contexts.Synchronization
Attribute.  AppDomain 
.
, .
WaitHandle, exit
Context, false.
Mutex, Semaphore, AutoResetEvent ManualResetEvent 
WaitHandle, .
,
.
, Win32
CreateMutex, CreateSemaphore, CreateEvent ( false bManualReset)
CreateEvent ( true bManualReset).
,
WaitHandle.
, Mutex, Semaphore EventWaitHandle
OpenExisting, Win32 OpenMutex,
OpenSemaphore OpenEvent, string,
.
, OpenExisting.

634

CLR

,
WaitHandleCannotBeOpenedException.
, Mutex Semaphore,
ReleaseMutex Mutex Release Semaphore. 

, ( EventWaitHandle) Set Reset
AutoResetEvent ManualResetEvent. : Set
Reset EventWaitHandle Boolean,
true, ,
.


, Microsoft ,
,
. 
, . 
, 
. . ,
, ,

.

, RegisterWaitFor
SingleObject System.Threading.ThreadPool.
, .
:

public static RegisterWaitHandle RegisterWaitForSingleObject(


WaitHandle waitObject, WaitOrTimerCallback callback, Object state,
Int32 millisecondsTimeoutInterval, Boolean executeOnlyOnce);
waitObject , 
. 
WaitHandle,
. , Semaphore, Mutex, AutoReset
Event ManualResetEvent. , callback, ,
. 
System.Threading.WaitOrTimerCallback, 
:

public delegate void WaitOrTimerCallback(Object state, Boolean timedOut);


RegisterWaitForSingleObject, state,
, 
, . , null.
, millisecondsTimeoutInterval, ,
. 
, Timeout.Infinite 1. , execute
OnlyOnce, true, .

24

635

executeOnlyOnce false, 
.
AutoResetEvent.

timedOut. timedOut false, ,
. timedOut true, ,
, .
, 
, timedOut.
RegisterWaitForSingleObject RegisteredWait
Handle. ,
.  ,
,
Unregister RegisteredWaitHandle:

public Boolean Unregister(WaitHandle waitObject);


waitObject ,

. , null.
, WaitHandle,
.
, 
, AutoResetEvent:

using System;
using System.Threading;
public static class Program {
public static void Main() {
// AutoResetEvent ( ).
AutoResetEvent are = new AutoResetEvent(false);
// , AutoResetEvent.
RegisteredWaitHandle rwh = ThreadPool.RegisterWaitForSingleObject(
are,
// AutoResetEvent.
EventOperation,
// .
null,
// null EventOperation.
5000,
// 5 .
false);
// EventOperation .
// .
Char operation;
do {
Console.WriteLine("S=Signal, Q=Quit?");
operation = Char.ToUpper(Console.ReadKey(true).KeyChar);
if (operation == 'S') {
// ; .
are.Set();

636

CLR

}
} while (operation != 'Q');
// , .
rwh.Unregister(null);
}
//
// 5 /.
private static void EventOperation(Object state, Boolean timedOut) {
if (timedOut) {
Console.WriteLine("Timedout while waiting for the AutoResetEvent.");
} else {
Console.WriteLine("The AutoResetEvent became signaled.");
}
}
}

Вам также может понравиться