Академический Документы
Профессиональный Документы
Культура Документы
1
004.43
55
.
55 CLR via C#. Microsoft .NET Framework 4.5
C#. 4- . .: , 2013. 896 .: . ( -).
ISBN 978-5-496-00433-6
,
, (CLR) Microsoft .NET Framework 4.5. ,
.NET Framework Microsoft,
- ,
Microsoft Silverlight, ASP.NET, Windows Presentation Foundation . .
.NET Framework 4.5, Visual Studio 2012 C# 5.0.
12+ ( 12 . 29 2010 .
436-.)
32.973.2-018.1
004.43
Microsoft Press. .
.
, , , . , , ,
.
ISBN 978-0735667457 .
Authorized Russian translation of the English edition of titled CLR via C#,
4 edition 2012 Jeffrey Richter (ISBN 9780735667457). This translation
is published and sold by permission of OReilly Media, Inc., which owns or
controls all rights to publish and sell the same.
ISBN 978-5-496-00433-6
, 2013
, , 2013
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 22
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 24
I. CLR
1. CLR . .. .. .. .. .. .. .. .. .. .. 28
2. , ,
. .. .. .. .. .. .. .. .. .. .. .. .. . 58
3.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 94
II.
4. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 122
5. , . .. .. .. .. .. 142
6. . .. .. .. .. .. .. .. .. .. .. 186
7. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..210
8. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 215
9. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 245
10. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..263
11. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 286
12. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 302
13. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 333
III.
14. , . .. .. .. .. .. .. .. .. .. 356
15. . .. .. .. .. .. .. .. .. .. 403
16. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..416
17. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 434
18. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 464
19. Null- . .. .. .. .. .. .. .. .. .. .. ..485
IV.
20. . .. .. .. .. .. .. .. ..496
21.
(). .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 554
22. CLR . .. .. .. .. .. .. .. .. .. .. 606
23. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. 636
24. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 666
25. WinRT . .. .. .. .. .. .. ..698
V.
26. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..724
27. . .. .. .. .. .. .. .747
28. - . .. .. .. .. .. .. .. .. 787
29.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 820
30. . .. 854
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..893
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 22
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 24
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 26
I. CLR
1. CLR . .. .. .. .. .. .. .. .. .. .. 28
. .. .. .. .. .. .. .. .. .. .. 28
. .. .. .. .. .. .. .. .. .. .. .. .. .. . 32
CLR. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 34
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 37
IL- . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 44
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 45
IL . .. .. .. .. .. .. .. .. .. .. .. .. . 46
NGen.exe. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
FCL . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
CTS. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
CLS . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .
47
47
49
52
57
2. , ,
. .. .. .. .. .. .. .. .. .. .. .. .. . 58
.NET Framework. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 58
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 60
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 61
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 64
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .
Visual Studio . .. .. .. .. .. .. .. .. .. ..
Assembly Linker. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .
71
78
79
81
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 82
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 86
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
(.
). .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
( ). .. ..
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .
87
88
90
92
3.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 94
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 95
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 96
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 102
, . .. ..104
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..106
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 107
. .. .. .. .. .. .. .. 110
. .. .. .. .. .. .. .. .. .. 111
.
( ). .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..115
. .. .. .. .. .. .. .. 117
II.
4. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 122
System.Object . .. .. .. .. .. .. .. .. .. .. .. .. .. .. 122
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..124
C# is as. .. .. .. .. .. .. ..126
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 128
. .. .. .. .. .. .. .. .. .. .. .. 132
. .. .. 133
5. , . .. .. .. .. .. 142
. .. .. .. .. .. .. .. .. .. .. .. 142
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..146
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 150
CLR . .. .. .. .. .. .. .. .. .. ..155
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .156
( ). .. .. .. .. .. .. .. .. .. ..169
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..172
- . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 175
dynamic . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 177
6. . .. .. .. .. .. .. .. .. .. .. 186
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..186
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 189
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..189
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..191
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 193
, . .. .. .. .. .. .. .. .. .. .. .. .. .. .. 194
, . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 196
, CLR. .. .. .. .. .. .. ..198
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 202
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 205
7. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..210
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 210
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..212
8. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 215
( ) . .. .. .. .. .. .. .. 215
( ) . .. .. .. .. .. .. 219
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..222
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 226
. .. .. .. .. ..229
10
Microsoft,.
. .. .. .. .. .. .. .. .. .. .. .. ..229
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 230
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..234
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..237
. .. .. .. .. .. .. .. .. ..238
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 240
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..241
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..244
9. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 245
. .. .. .. .. .. .. .. .. .. .. .. .. .. ..245
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 246
DefaultParameterValue . .. .. .. ..248
. .. .. .. .. .. .. .. .. .. .. ..248
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 251
. .. .. .. .. .. .. .. .. .. .. .. ..257
. .. .. .. .. .. .. .. .. .. .. .. .. .. 259
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 261
10. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..263
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..263
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 267
. .. .. .. .. .. .. .. .. .. .. .. .. 268
Visual Studio . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 270
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..271
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..273
System.Tuple. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..276
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 279
. .. .. .. .. .. .. .. .. .. .. .. .. .. ..283
. .. .. .. .. .. .. .. .. .. .. 284
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..285
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..285
11. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 286
, . .. .. .. .. .. .. .. .. .. .. .. .. ..287
11
1.
, .
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 288
2. -. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 289
3. ,
. .. .. .. .. .. .. .. .. .. .. .. .. ..290
4. , .
. .. .. .. .. .. .. .. .. .. .. .. ..292
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 293
, . .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..295
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..298
12. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 302
FCL. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..307
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 308
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..309
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .311
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 313
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..314
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..315
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 316
-.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..317
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .319
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 320
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..322
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 322
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..325
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 327
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..328
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 329
13. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 333
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 333
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..334
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 335
12
. .. .. .. .. .. .. .. .. .. .. .. .. ..338
.
( ). .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..339
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..341
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 344
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 345
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 346
. .. .. .. .. .. .. .. .. 348
: ? . .. .. .. .. .. .. ..351
III.
14. , . .. .. .. .. .. .. .. .. .. 356
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 356
System.String. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..359
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 359
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 362
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 362
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 369
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..372
. .. .. .. .. .. .. 372
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..375
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..375
StringBuilder. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 376
StringBuilder . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 377
. .. .. .. .. ..
. .. .. .. .. .. .. .. .. ..
.
. ..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
379
380
384
386
. .. .. .. .. .. .. .. .. .. .. ..389
: . .. .. .. .. .. ..391
. .. .. .. ..397
Base-64 . .. .. .. .. 398
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..399
13
15. . .. .. .. .. .. .. .. .. .. 403
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..403
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..409
. .. .. .. .. .. .. .. .. .. .. .. .. .. 413
16. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..416
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 418
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 421
System.Array. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..423
IEnumerable, ICollection IList . .. .. .. .. .. .. .. 424
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..425
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 426
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 427
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..432
17. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 434
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..434
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..437
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..438
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..439
( ). .. .. .. .. .. ..443
C#. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 448
. .. .. ..448
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 451
. .. .. .. .. .. .. .. .. .. .. .. .. ..452
1: . .. .. .. .. .. .. .. .. .. .. .. .. .. 452
2: . .. .. .. .. .. .. .. 453
3: .
. .. .. .. .. .. .. .. .. .. .. .. .. 457
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..460
18. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 464
. .. .. .. .. .. .. .. .. .. .. .. .. .. 464
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..468
14
. .. .. .. .. .. .. .. .. 471
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 473
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 477
,
Attribute. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..480
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 484
IV.
20. . .. .. .. .. .. .. .. ..496
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..496
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..498
try. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..499
catch. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 499
finally. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 501
CLS- CLS- . .. .. .. .. .. .. ..503
System.Exception . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 505
, FCL . .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..509
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..511
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 513
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..515
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..524
finally . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 525
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..526
. .. .. .. .. .. .. .. .. .. .. .. 528
15
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..529
. .. .. .. .. ..530
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..533
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..537
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..540
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..543
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..546
21.
(). .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 554
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.
. .. .. .. .. .. .. .. .. .. ..
. .. .. .. .. .. .. .. .. .. ..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
554
555
557
560
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 562
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..568
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 569
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..570
. .. .. .. .. .. .. .. .. .. .. .. 573
. .. .. .. .. .. .. .. .. ..574
. .. .. ..576
, . .. .. .. .. .. .. .. .. .. .. .. .. .. ..583
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 588
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..590
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..594
. .. .. .. .. .. .. .. .. .. .. ..597
16
. .. .. .. .. .. ..627
. .. .. .. .. .. .. .. .. .. .. .. .. .628
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 628
- Silverlight. .. .. .. .. .. ..629
Microsoft ASP.NET - XML. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..629
Microsoft SQL Server. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..630
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 630
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..631
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..631
-. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..631
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..633
23. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. 636
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 637
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..641
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 642
, . .. .. .. .. .. .. .. .. .. .. .. .. ..644
Type . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 644
, Exception . .. .. .. .. .. .. .. 646
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..648
. .. 650
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..653
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 654
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..658
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..663
24. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 666
/. .. .. .. .. .. .. .. ..667
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 672
. .. .. .. .. .. .. .. .. .. .. .. .. 673
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..677
. .. .. 679
, ISerializable,.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..684
17
- . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
..
..
..
..
..
..
..
..
..
..
..
..
686
688
691
694
/ . ..695
V.
26. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..724
Windows ? . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 724
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 725
!. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..729
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 732
CLR- Windows- . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 733
. .. .. .. .. .. .. .. .. .. 734
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..736
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 739
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..744
? . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 746
27. . .. .. .. .. .. .. .747
CLR . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 747
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 748
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..750
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..752
18
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..757
. .. .. .. .. .. .. .. .. .. .. .. ..758
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..760
. .. .. 762
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..764
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 765
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 767
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..769
For, ForEach Invoke Parallel . .. .. .. .. .. .. .. .. .. .. .. .. .. ..771
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..775
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 779
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..782
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..783
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..783
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..784
28. - . .. .. .. .. .. .. .. .. 787
- Windows. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..787
C#. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..792
. .. .. .. .. ..795
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..799
. .. .. .. .. .. .. .. .. .. .. .. .. 803
FCL. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 804
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..806
. .. .. .. .. .. .. .. .. .. .. .. .. .. ..807
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 810
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 813
- . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 814
-.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..815
FileStream . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 816
-. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..817
19
29.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 820
. .. .. .. .. .. .. .. .. .. .. .. .. .. 822
.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 824
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..825
Volatile-. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..826
Interlocked-. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 832
. .. .. .. .. .. .. .. .. .. .. .. 837
Interlocked-. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 841
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..843
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 847
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..850
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 851
30. . .. 854
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..854
, . .. .. .. .. .. .. .. .. .. .. .. .. ..857
FCL. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..859
ManualResetEventSlim SemaphoreSlim. .. .. .. .. .. .. .. .. .. .. ..859
Monitor . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..860
ReaderWriterLockSlim. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..866
OneManyLock. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..868
CountdownEvent . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 871
Barrier. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..872
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 873
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..875
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 880
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 882
. .. .. .. .. .. .. .. .. .. .. .. .. 888
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..893
. , .
.
.
(9 ) (5 ). , . , , .
. .
. ? ,
!
. ,
; , . ,
, , .
. ,
( -
). . ,
, .
, .
.
, - 3
( 5- ,
, , ). -
.
, - , .
.
; . , , - - .
, ;
Microsoft.
. ,
, .
, ,
(reflection). , .
, ,
,
, . , .
async/await. ,
AsyncEnumerator, - .
, ! ,
, .
23
M, async/await,
, .
.
, WinRT
. WinRT , -
:
! , ; Windows
. . , .
! , ,
- .
, . , : WinRT,
!
, ( )
, .
? ,
.
,
( )
2012 .
! !
1999 Microsoft .NET Framework, (Common Language
Runtime, CLR) #.
: , .
, . , .NET Framework Win32
API (Application Program Interface, )
COM (Component Object Model, ).
.NET Framework, ,
. .
, , , , ( ),
. ( )
,
.
2012 , 13 ,
.NET Framework C#.
13 Microsoft
.NET Framework.
Wintellect (http://Wintellect.com)
, ,
, , .NET Framework.
,
.NET Framework .
, .
, .NET Framework. , , , CLR
.
(Framework Class Library, FCL). FCL ,
. ,
25
. Windows Forms,
Windows Presentation Foundation
(WPF), Microsoft Silverlight, - XML, -, Microsoft ASP.NET
MVC, Windows Store Apps .., , ,
.
Microsoft Visual Studio 2012, .NET Framework4.5
# 5.0. Microsoft
, , ,
. #,
CLR ,
, .
, , Wintellect
(http://Wintellect.com/Books).
, ,
, , , .
.
( )
,
JeffreyR@Wintellect.com.
.
, .
, , ,
, ,
. - . , ,
.
. .NETFramework ( )
,
. (Christophe Nasarre),
,
.
. , -
26
Microsoft Press.
(Ben Ryan), (Devon Musgrave)
(Carol Dillingham). (Susie Carr)
(Candace Sinclair) .
,
.
Microsoft Press oreilly.com http://
go.microsoft.com/FWLink/?Linkid=266601.
, ,
.
, Microsoft Press Book Support mspinput@microsoft.com.
, , Microsoft .
. ,
, http://microsoft.com/learning/booksurvey.
,
. !
! : http://twitter.com/MicrosoftPress.
. ,
comp@piter.com ( ,
).
!
-
http://www.piter.com.
I
CLR
1. CLR. .. .. .. . 28
2. , ,
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 58
3.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . 94
1.
CLR
, .NET Framework . ! .
, , ,
.
.
. , ,
C/C++ .
, .. , Microsoft Visual Basic6.0
COM-
.
(Common Language Runtime,
CLR) : ,
. CLR ( ,
, , , )
, . , , ,
, ,
. , ,
, ,
, , .
29
CLR ,
. ,
,
.
,
CLR.
?
. , ,
, ,
. , .
. ,
APL
Perl.
Microsoft , : C++/CLI, C# (
), Visual Basic, F# ( ), Iron Python, Iron Ruby
Intermediate Language (IL). Microsoft,
,
CLR. Ada, APL, Caml, COBOL, Eiffel, Forth, Fortran,
Haskell, Lexico, LISP, LOGO, Lua, Mercury, ML, Mondrian, Oberon, Pascal, Perl, Php,
Prolog, RPG, Scheme, Smalltalk Tcl/Tk.
1.1 .
, ,
CLR.
.
(managed module) (portable
executable, PE) 32- (PE32) 64- Windows (PE32+),
CLR. ,
(DEP, Data Execution Prevention) ASLR (Address Space
Layout Optimization),
.
,
, x86, 64 ARM. ,
CLR- IL-. ( IL- .) IL- (managed code),
CLR .
30
1. CLR
IL
(IL )
. 1.1.
. 1.1 .
1.1.
PE32
PE32+
PE- Windows, Common Object File Format (COFF). PE32 32- 64-
Windows, PE32+ 64. : GUI, CUI DLL,
, ,
. , IL-, PE32(+) .
, ,
CLR
( CLR ), . CLR, ,
MethodDef
( Main), /
, , , .
.
,
, , , ,
Intermediate
Language (IL)
, . CLR IL
31
, CLR, IL-,
(metadata)
. , , ,
, .
, , , .
, COM IDL (Interface Definition Language,
). , CLR
. , IDL-,
, IL-.
EXE- DLL-, , .
,
IL- .
. .
, /
IL-.
.
Microsoft Visual Studio . IntelliSense ,
, ,
.
CLR , ,
. ( .)
, ,
.
.
, .
2 .
C#, Visual Basic, F# IL-
, (IL) (, ).
CLR (
.NET Framework) , MFC Visual
Basic 6.0 Microsoft Foundation Class
(MFC) DLL- Visual Basic.
32
1. CLR
CLR , . (assembly)
, .
-,
. -,
, .
. CLR ,
.
2,
,
.
1.2 . ( ),
. PE32(+),
. PE32(+) , (manifest).
. ,
, ,
, .
, C#
, , .
, ,
33
( ), , .
,
(, AL.exe)
. 2.
(:
, )
. 1.2.
, ,
.
. ,
.
. , ,
.
,
.
,
( ). (self-describing). , CLR
, .
,
AD DS (Active Directory Domain Services).
, .
34
1. CLR
CLR
,
DLL,
. , CLR .
, , ,
.NET Framework. Microsoft .NET Framework ,
.
Windows .NET
Framework.
, .NET Framework , MSCorEE.dll %SystemRoot%\system32.
, .NET Framework .
.NET Framework.
, ,
:
%SystemRoot%\Microsoft.NET\Framework
%SystemRoot%\Microsoft.NET\Framework64
CLR
35
36
1. CLR
Windows EXE-
,
32- 64-. PE32
,
PE32+ 64- . Windows .
, 64- Windows
32- 64- , WoW64
(Windows on Windows64).
1.2 . -,
/platform
C#. -, Windows.
1.2. /platform .
/
platform
x86 Windows
x64 Windows
ARM Windows
RT
anycpu (
)
PE32/
32-
64-
32-
anycpu32bit
preferred
PE32/
32-
WoW64
32-
86
PE32/x86
32-
WoW64
64
PE32+/x64
64-
ARM
PE32+/Itanium
32-
37
MSCorEE.dll (x86,
x64 ARM). Windows x86 ARM 32-
MSCorEE.dll %SystemRoot%\System32. x64 x86
%SystemRoot%\SysWow64, 64-
MSCorEE.dll %SystemRoot%\System32 ( ).
MSCorEE.dll , CLR,
EXE, Main, .
1.
Win32 LoadLibrary
, Windows CLR ( ) .
, , ,
. , , /platform:x86, 64-
, WoW64
64 Windows.
,
IL. ,
Microsoft
, .
IL .
Is64BitOperatingSystem
, , 64- Windows,
Is64BitProcess, ,
64- .
1
38
1. CLR
,
. . IL
- .
,
C#, Visual Basic F#. IL-.
, , Microsoft
IL (ILAsm.exe), IL (ILDasm.exe).
, , ,
, CLR. IL
CLR.
CLR, ,
IL ,
.
CLR, , .
CLR ,
C#. ,
CLR
, . , ,
.
, CLR. , ,
. , C# Visual Basic,
-. APL (A Programming
Language) .
CLR C# , -,
APL. CLR
,
.
- IL-
. JIT- (Just-In-Time) CLR.
.1.4 , .
Main CLR
, Main. CLR ,
, . . 1.4 Main Console, CLR .
,
39
Console. , . CLR
,
CLR. JITCompiler.
( )
. 1.4.
Main WriteLine ,
JITCompiler. IL-
. IL- (just in time), CLR
JIT-.
40
1. CLR
. 1.5.
41
.
,
.
JIT- . , .
( ) JIT
IL- .
,
.
, JIT-, .
.
.
, .
, JIT- CLR
C++. :
,
, .
C#, ,
/optimize /debug .
IL, C#, , JIT.
IL-
JIT
/optimize- /debug-
/optimize- /debug(+/full/
pdbonly)
/optimize+ /debug(-/+/full/
pbdonly)
( )
42
1. CLR
, .
, , .
IL- , EXE DLL-; , IL- ,
IL-, , (, ).
, PDB (Program Database)
/debug(+/full/pdbonly) . PDB
IL .
/debug:full JIT- ,
; JIT- , IL.
JIT- Visual Studio
. /debug:full
IL ;
.
Visual Studio, JIT- IL ( /
debug), Suppress JIT Optimization On Module Load
(Managed Only) Visual Studio.
C# Visual Studio
/optimize /debug:full,
/optimize+ /debug:pdbonly.
C C++
, .
. .
,
IL-. IL-
,
, ,
.
CLR C/C++
. , ,
,
. Microsoft
, .
,
.
- , Microsoft . ,
.
, ( ) ,
43
. . , ,
JIT- IL- ,
, .
:
JIT- ,
Intel Pentium 4, ,
Pentium 4. ,
.
JIT- , ,
, . , :
if (numberOfCPUs > 1) {
...
}
, JIT-
. , ,
.
CLR IL
.
. CLR , , .
,
. ,
.
, JIT-
, ,
NGen.exe .NET Framework SDK.
IL-
. CLR ,
, , . ,
NGen.exe , , NGen.exe,
, JIT-.
System.
Runtime.ProfileOptimization. CLR ( ) -
44
1. CLR
, JIT- . , ,
, JIT-
. , , (
JIT-).
IL-
IL ; ,
. IL
, ,
CLR.
IL . , IL
, . (32- 64-).
,
, .
, , IL-
, . IL- .
IL CLR ,
IL
. , , ,
,
, return . .
, ,
.
Windows .
, .
(, ). Windows
; .
,
. , Windows.
Windows ,
45
.
, ,
.
.
, CLR
. (AppDomain).
EXE- ,
. , ()
CLR , IIS (Internet Information Services) Microsoft SQL Server,
. 22.
C# Microsoft .
, . Microsoft C# ,
. ,
, .
: ( )
. C# ,
, , unsafe,
/unsafe.
JIT- ,
, , ,
System.Security.Permissions.SecurityPermission SkipVerification System.Security.Permissions.
SecurityPermissionFlag. , JIT-
. CLR ,
. , JIT- System.
InvalidProgramException System.Security.VerificationException, . ,
, .
Microsoft PEVerify.exe,
, .
, PEVerify.exe , ;
.
46
1. CLR
, ,
; , ,
. , ,
. , .
,
.
, , . , PEVerify
, . PEVerify CLR ,
, . 2 3.
IL
, IL
. ,
, - IL, .
, IL- , , IL-
. , (-,
- ), . ,
IL
.
,
.
. . ,
, CLR IL- JIT-.
,
,
,
IL . CLR ( )
. , ,
.
FCL
47
NGen.exe
NGen.exe, .NET Framework,
IL-
. , JIT-
CLR ,
. NGen.exe .
. NGen.exe ,
,
.
. , ,
NGen.exe . , NGen.exe
IL .
, , .
FCL
.NET Framework FCL (Framework Class Library)
DLL, ,
.
Microsoft , Windows Azure
SDK DirectX SDK. ,
. , Microsoft
, Microsoft.
,
:
-. Microsoft ASP.NET XML Web Service Windows
Communication Foundation (WCF)
, .
Web Forms/ MVC HTML. ,
ASP.NET , ,
HTML.
Windows .
- ,
48
1. CLR
FCL , . , System (
) Object
. , System
, , ,
-, ,
, ,
.
System.
FCL, ,
, .
; FCL. -
, .NET Framework
. ,
, .
.
Win32 .
CTS
49
FCL , . .1.3
.
,
Microsoft, Microsoft SDK.
1.3. FCL
System
System.Data
System.IO
-,
System.Net
System.Runtime.
InteropServices
System.Security
System.Text
(, ANSI
)
System.Threading
System.Xml
XML
CLR , CLR. , ,
CLR.
-, Web Forms/MVC, WPF
.. ,
.
, ,
. ,
, .
CTS
, , CLR , .
50
1. CLR
, , ,
. CLR,
Microsoft CTS (Common Type
System), .
CTS, . II ,
:
, . .
, ,
. , .
( ), , , ,
.
,
( ).
/ .
, ,
.
. , , .
CTS . ,
( public),
, . , ( internal C#)
. , CTS ,
, CLR .
CTS
51
, ,
. :
()
.
, . : (, C# C++)
protected.
,
, . (, C# Visual Basic) . ,
IL- .
, . internal.
, . C#
protected internal.
.
, CTS , ,
, . .
, . , CTS ,
. IL, CLR,
.
CLR, ,
. C++/
CLI, . ,
C#
Visual Basic. ,
, ,
CTS.
, . CTS
. C++ , CTS
.
, , Microsoft
C++/CLI .
52
1. CLR
CTS: (
) System.Object (
Object System). Object ,
, ,
. , System.Object :
;
- ;
;
() ;
.
CLS
COM , , . , CLR ,
, .
CLR, (
) .
, ,
. , ,
, .
,
, , .
Microsoft CLS
(Common Language Speciication); , ,
, CLS-
CLR.
CLR/CTS ,
CLS. , ,
. , CLS ,
,
CLS- .
: CLS , -
CLS
53
. .1.6 ,
.
CLR/CTS
Visual
Basic
C#
CLS
Fortran
54
1. CLR
//: 'SomeLibrary.SomeLibraryType.abc()',
// ,
// CLS-
publicvoidabc(){}
// :
privateUInt32ABC(){return0;}
}
}
[assembly:CLSCompliant(true)] .
,
,
. C#
. - , Abc
; . - ,
, : Abc abc. Visual Basic
.
public sealed class SomeLibraryType
, . ,
SomeLibraryType internal, ,
. CLS Cross-Language Interoperability .NET Framework
SDK (http://msdn.microsoft.com/en-us/library/730f1wy3.aspx).
CLS . CLR
(), ().
,
. . ,
, , , , , ,
, , ,
. . , , CLR
.
, , , , . ,
, ,
.
usingSystem;
internalsealedclassTest{
CLS
55
//
publicTest(){}
//
~Test(){}
//
publicstaticBooleanoperator==(Testt1,Testt2){
returntrue;
}
publicstaticBooleanoperator!=(Testt1,Testt2){
returnfalse;
}
//
publicstaticTestoperator+(Testt1,Testt2){returnnull;}
//
publicStringAProperty{
get{returnnull;}
set{}
}
//
publicStringthis[Int32x]{
get{returnnull;}
set{}
}
//
public eventEventHandlerAnEvent;
}
,
. ,
IL Disassembler (ILDasm.exe), .NET Framework
SDK (.1.7).
.1.4 / CLR.
Test, .1.4 .class, .custom,
AnEvent, AProperty Item, .
,
, CLR, . , , Test
AnEvent,
(add_AnEvent remove_AnEvent).
56
1. CLR
1.4. Test
AnEvent
; AnEvent, System.
EventHandler
.ctor
Finalize
add_AnEvent
get_AProperty
Get-
get_Item
Get-
op_Addition
op_Equality
==
op_Inequality
!=
remove_AnEvent
set_AProperty
Set-
set_Item
Set-
57
.NET Framework
. , . Microsoft
, CLR , , .
, CLR :
DLL P/Invoke ( Platform Invoke).
, , FCL,
, Kernel32.dll, User32.dll . . ,
DLL . , C#
CreateSemaphore, Kernel32.dll.
COM.
COM. COM.
, .
TlbImp.exe,
.NET Framework SDK.
.
COM.
, , . ,
C# ActiveX
.
TlbExp.exe RegAsm.exe, .NET Framework SDK.
2. ,
,
, Microsoft
.NET Framework, ,
. , . 3
, ,
, , . ,
.
, Microsoft. ,
, . , , (CLR),
;
.
, ,
. , .NET Framework.
.NET Framework
Windows . , ,
. -,
(Dynamic Link Library, DLL), Microsoft
. ,
, -
100% , ,
. ,
.NET Framework
59
,
.
,
. ,
, ? ,
,
, ,
.
, ,
( ) . , ,
DLL. ,
.
,
.
, Windows,
.
. , , ,
(Desktop), (Start)
. , . ,
, ,
. ,
, . ,
, -
- .
.
, . ,
- (, ActiveX) , , .
,
. -
, .
, ,
,
.
, .NET Framework DLL
60
2. , ,
,
. , COM . ,
.
.NET Framework
(code access security). Windows
,
, , .
(, Microsoft SQL Server)
,
( ). , .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# Program.
exe ( /out:Program.exe). -
Win32 ( /t[arget]:exe).
C# WriteLine System.Console.
, WriteLine.
61
, , ,
WriteLine.
C#, C# , .
/r[eference]:MSCorLib.dll
, MSCorLib.dll.
MSCorLib.dll , :
Byte, Char, String, Int32 .. ,
, C# (MSCorLib.dll) .
, ( /r)
, :
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
(portable executable). , , 32-
64- Windows, -
. Windows :
(Console User Interface, CUI)
(Graphical User Interface, GUI). /t:exe C#
.
/t:winexe, Windows
Store /t:appcontainerexe.
(response files) ,
. CSC.
exe ,
.
62
2. , ,
@.
, MyProject.rsp :
/out:MyProject.exe
/target:winexe
(CSC.exe) ,
:
csc.exe @MyProject.rsp CodeFile1.cs CodeFile2.cs
C# . , ,
.
C# . ,
CSC.rsp .
CSC.exe CSC.rsp,
, .
.
. ,
, .
.NET Framework
CSC.rsp %SystemRoot%\Microsoft.NET\Framework(64)\
vX.X.X ( X.X.X .NET Framework).
:
#
#
#
#
,
C# (CSC)
,
"/noconfig".
# Framework
/r:Accessibility.dll
/r:Microsoft.CSharp.dll
/r:System.Configuration.dll
/r:System.Configuration.Install.dll
/r:System.Core.dll
/r:System.Data.dll
/r:System.Data.DataSetExtensions.dll
/r:System.Data.Linq.dll
/r:System.Data.OracleClient.dll
/r:System.Deployment.dll
/r:System.Design.dll
/r:System.DirectoryServices.dll
/r:System.dll
/r:System.Drawing.Design.dll
63
/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.dll
/r:System.Runtime.Serialization.Formatters.Soap.dll
/r:System.Security.dll
/r:System.ServiceModel.dll
/r:System.ServiceModel.Web.dll
/r:System.ServiceProcess.dll
/r:System.Transactions.dll
/r:System.Web.dll
/r:System.Web.Extensions.Design.dll
/r:System.Web.Extensions.dll
/r:System.Web.Mobile.dll
/r:System.Web.RegularExpressions.dll
/r:System.Web.Services.dll
/r:System.Windows.Forms.Dll
/r:System.Workflow.Activities.dll
/r:System.Workflow.ComponentModel.dll
/r:System.Workflow.Runtime.dll
/r:System.Xml.dll
/r:System.Xml.Linq.dll
CSC.rsp , /reference.
,
, Microsoft ,
/reference.
,
,
,
.
/reference - . ,
( ).
.
, (CSC.exe). MSCorLib.
dll .
:
- %SystemRoot%\Microsoft.NET\Framework\v4.0.#####.
- , /lib .
- , LIB.
64
2. , ,
, CSC.
rsp,
CSC.rsp ,
.
, CSC.rsp, /noconfig.
Program.exe? PE-
4- : PE32(+), CLR, (intermediate language, IL). PE32(+)
, Windows. CLR , , CLR ( ).
CLR,
, MethodDef ( ),
, CUI, GUI Windows Store,
( 3).
, ,
. CLR,
IMAGE_COR20_HEADER, CorHdr.h.
, .
: , . .2.1
,
.
2.1.
ModuleDef
, .
( ) ( GUID). ,
.
, CLR
TypeDef
, .
, , (public,
private ..) MethodDef, PropertyDef
EventDef, ,
65
MethodDef
FieldDef
ParamDef
,
. (in, out, retval ..),
PropertyDef
, . , ,
( )
EventDef
, .
, , , .2.1.
, , ,
, .
, . .2.2
, .
2.2. ,
AssemblyRef
, . ,
: ( ),
, (
-, ,
). -,
.
CLR - ,,
66
2. , ,
2.2 ()
ModuleRef
PE-,
, .
( ).
,
TypeRef
,
. ,
. , TypeRef.
, ModuleDef.
, ModuleRef.
,
AssemblyRef
MemberRef
(, ,
), .
TypeRef, ,
, . 2.1
2.2; , . ,
. .
PE-
. ILDasm.exe IL.
, :
ILDasm Program.exe
ILDasm.exe Program.exe.
,
View MetaInfo Show! ( Ctrl+M).
:
===========================================================
ScopeName : Program.exe
MVID
: {CA73FFE8
0D42
4610
A8D3
9276195C35AA}
===========================================================
Global functions
67
Global fields
Global MemberRefs
TypeDef #1 (02000002)
(00000096)
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)
TypeRef #2 (01000002)
Token:
ResolutionScope:
0x01000002
0x23000001
68
2. , ,
TypeRefName:
System.Runtime.CompilerServices.CompilationRelaxationsAttribute
MemberRef #1 (0a000001)
Token:
0x01000003
ResolutionScope:
0x23000001
TypeRefName:
System.Runtime.CompilerServices.RuntimeCompatibilityAttribute
MemberRef #1 (0a000002)
Token:
0x01000004
ResolutionScope:
0x23000001
TypeRefName:
System.Console
MemberRef #1 (0a000003)
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:
69
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)
Token: 0x23000001
Public Key or Token: b7 7a 5c 56 19 34 e0 89
Name: mscorlib
Version: 4.0.0.0
Major Version: 0x00000004
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.
(sealed) ,
System.Object ( ). Program
: Main .ctor ().
70
2. , ,
:
:
:
:
:
:
:
:
:
:
:
3584
512 (496 used)
1411
3
72
612
0
2
20
2048
1
093
(14.29%)
(39.37%)
( 2.01%)
(17.08%)
( 0.00%)
( 0.06%)
( 0.56%)
(57.14%)
(
30.50%)
: 3
CLR meta
data size : 612
Module
1 (10 bytes)
TypeDef 2 (28 bytes) 0 interfaces, 0 explicit layout
TypeRef
4 (24 bytes)
MethodDef 2 (28 bytes) 0 abstract, 0 native, 2 bodies
MemberRef
4 (24 bytes)
CustomAttribute 2 (12 bytes)
Assembly
1 (22 bytes)
AssemblyRef
1 (20 bytes)
Strings
184 bytes
Blobs
68 bytes
UserStrings
8 bytes
Guids
16 bytes
Uncategorized 168 bytes
CLR method headers : 2
Num.of method bodies
Num.of fat headers
2
0
Num.of tiny headers
71
Managed code : 20
Ave method size 10
( ),
( ).
Program.cs ,
PE . IL- 20. ,
, ,
.
ILDasm.exe ,
. , Unaccounted.
72
2. , ,
, GIF- JPG-. ,
EXE- DLL-.
, , Microsoft
. ,
. ,
. , ,
, . ,
, . ,
(independent software vendor, ISV), ,
Active Accessibility ( Microsoft).
, .
, , codeBase (. 3).
URL-, .
CLR URL codeBase
.
, , CLR
URL-. , CLR FileNotFoundException.
.
,
,
, .
. ,
.
.
(,
AL.exe, ).
: , Microsoft
Excel Microsoft Word, ,
.
, . C#, Visual Basic,
.
C# , Visual Basic .
.
. -
73
, . ,
ILDasm.exe IL. ILAsm.exe
, , .
IL-.
, , , .
, ,
. ,
CLR , ,
.
, , , ,
, .
,
,
, ,
. CLR Windows
: , .
, ,
. ,, nGen.exe ,
.
, PE-, . PE-,
, . .2.3
, .
2.3.
AssemblyDef
,
. ( ),
( ,
), , ,
(
null)
74
2. , ,
2.3 ()
FileDef
PE- , ( ,
).
( ), - . , FileDef
ManifestResourceDef
,
. , (public
private), FileDef, . (, JPEG- GIF-), PE-.
,
PE-
ExportedTypesDef
,
PE- .
, FileDef ( ,
),
TypeDef. :
, , ,
, TypeDef
. , , ,
, , ,
.
, , AssemblyRef.
,
. , ,
, ,
. AssemblyRef .
75
/t[arget]:library /t[arget]:winmdobj1. -
PE-
. , , Windows Store,
WINMD.
C# /t[arget]:module,
PE- .
DLL- PE.
,
. /t:module C# .netmodule.
. PE-
C#,
/addmodule. , ,
. , :
RUT.cs ;
FUT.cs .
, ,
:
csc /t:module RUT.cs
/t[arget]:winmdobj .winmdobj
WinMDExp.exe,
CLR Windows Runtime.
WinMDExp.exe IL.
1
76
2. , ,
C# FUT.cs
MultiFileLibrary.dll. /t:library,
PE- DLL MultiFileLibrary.dll.
/addmodule:RUT.netmodule , RUT.netmodule . , /addmodule
FileDef
, ExportedTypesDef
.
, (.2.1).
.
RUT.netmodule IL-, RUT.cs.
, , , ,
, , .., RUT.cs, , .,
RUT.cs. MultiFileLibrary.dll . RUT.
netmodule, IL-, FUT.cs,
. MultiFileLibrary.dll ,
. ,
( MultiFileLibrary.dll RUT.netmodule). ,
MultiFileLibrary.dll RUT.netmodule.
,
PE-, .
, PE-. ,
,
MultiFileLibrary.dll RUT.netmodule, .
.
MultiFileLibrary.dll, ILDasm.exe, ,
RUT.netmodule. FileDef
ExportedTypesDef :
File #1 (26000001)
Token: 0x26000001
Name : RUT.netmodule
HashValue Blob : e6 e6 df 62 2c a1 2c 59
Flags : [ContainsMetaData] (00000000)
ExportedType #1 (27000001)
Token: 0x27000001
Name: ARarelyUsedType
97 65 0f 21 44 10 15 96
f2 7e db c2
77
. 2.1.
: 4 .
(0x01=TypeRef, 0x02=TypeDef, 0x26=FileRef, 0x27=ExportedType). . CorTokenType
CorHdr.h .NET Framework SDK. . ,
0x26000001 FileRef (
1, 0). , TypeDef
2.
, MultiFileLibrary.dll, /r[eference]:MultiFileLibrary.
dll, MultiFileLibrary.dll ,
FileDef. ,
. RUT.netmodule, C# :
78
2. , ,
,
, .
.
CLR ,
, . CLR , , .
, ,
CLR, . , , CLR
, CLR . CLR
, . , ,
, .
Visual Studio
Visual Studio,
, . Solution Explorer,
, ,
Add Reference. Reference Manager (.2.2).
79
, .
, ( ),
Browse. Solution
, . COM
Reference Manager
COM- -,
Visual Studio. Browse ,
.
.NET,
:
http://msdn.microsoft.com/en-us/library/wkze6zky(v=vs.110).aspx
Assembly Linker
C#
(assembly linker) AL.exe. , , ( , /addmodule
C#), ,
. AL.exe ,
( ),
.
AL.exe EXE DLL PE,
, , .
, AL.exe, MultiFileLibrary.dll -:
csc /t:module RUT.cs
csc /t:module FUT.cs
al /out: MultiFileLibrary.dll /t:library FUT.netmodule RUT.netmodule
, , .2.3.
, RUT.netmodule FUT.netmodule.
, . MultiFileLibrary.dll PE DLL (
/t[arget]:library), IL-,
, , RUT.netmodule FUT.
netmodule . :
MultiFileLibrary.dll, RUT.netmodule FUT.netmodule,
.
AL.exe PE-
, Windows Store
/t[arget]:exe, /t[arget]:winexe /t[arget]:appcontainerexe).
, ,
PE-, IL-,
80
2. , ,
. ,
,
/main. AL.exe :
csc /t:module /r:MultiFileLibrary.dll Program.cs
al /out:Program.exe /t:exe /main:Program.Main Program.netmodule
. 2.3.
Program.cs ,
PE- Program.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 'Program.netmodule']Program::Main()
IL_0007: ret
} // end of method 'Global Functions'::__EntryPoint
81
, Main, Program,
Program.netmodule. /main,
AL.exe, , -
, PE- . ,
.
Ch02-3-BuildMultiFileLibrary.
bat, . Ch02-4-AppUsingMultiFileLibrary Visual Studio
.
, Visual Studio.
AL.exe, /embed[resource]
( , PE). PE-.
ManifestResourceDef , .
AL.exe /link[resource], .
ManifestResourceDef FileDef ,
. PE- ,
.
Win32.
# ,
/nowin32manifest. ,
C# , :
<?xml version="1.0" encoding="UTF
8" standalone="yes"?>
<assembly xmlns="urn:schemasmicrosoftcom:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
<trustInfo xmlns="urn:schemas
microsoft
com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas
microsoft
com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
82
2. , ,
PE-
ManifestResourceDef. /linkresource
ManifestResourceDef FileDef .
: Win32. , AL.exe CSC.exe RES-
/win32res. , Win32
, AL.exe CSC.exe ICO- /win32icon. Visual Studio
Application . ,
Windows (Windows Explorer)
.
AL.exe CSC.exe PE-,
Win32. , .
GetVersionInfo System.Diagnostics.
FileVersionInfo. .2.4 Details
Ch02-3-MultiFileLibrary.dll.
83
,
. , , .2.4.
using System.Reflection;
// FileDescription:
[assembly: AssemblyTitle("MultiFileLibrary.dll")]
// Comments:
[assembly: AssemblyDescription("This assembly contains MultiFileLibrary's types")]
// CompanyName:
[assembly: AssemblyCompany("Wintellect")]
// ProductName:
[assembly: AssemblyProduct("Wintellect (R) MultiFileLibrary's Type Library")]
// LegalCopyright:
[assembly: AssemblyCopyright("Copyright (c) Wintellect 2013")]
// LegalTrademarks:
[assembly:AssemblyTrademark("MultiFileLibrary is a registered trademark
of Wintellect")]
// AssemblyVersion:
[assembly: AssemblyVersion("3.0.0.0")]
// FILEVERSION/FileVersion:
[assembly: AssemblyFileVersion("1.0.0.0")]
// PRODUCTVERSION/ProductVersion:
[assembly: AssemblyInformationalVersion("2.0.0.0")]
// Language (. " ")
[assembly:AssemblyCulture("")]
, Windows
. , ,
AssemblyVersion, CLR
( 3).
. 2.4
, .
AL.exe,
. . 2.4
.
C#;
, .
84
2. , ,
2.4. .
AL.exe
AL.exe
FILEVERSION
/fileversion
System.Reflection.
AssemblyFileVersionAttribute
PRODUCTVERSION
/productversion
System.Reflection.AssemblyInformationalVersionAttribute
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
/copyright
System.Reflection.
AssemblyCopyrightAttribute
LegalTrademarks
/trademark
System.Reflection.
AssemblyTrademarkAttribute
85
AL.exe
OriginalFilename
/out
( )
PrivateBuild
ProductName
/product
System.Reflection.
AssemblyProductAttribute
ProductVersion
/productversion
System.Reflection.AssemblyInformationalVersionAttribute
SpecialBuild
86
2. , ,
, .
: 4 , (.2.5).
2.5.
719
. 2.5 2.5.719.2. , :
2.5. , 719, .
, .
2 .
(, , ),
.
Microsoft, .
: .
. ,
.
AssemblyFileVersion Win32
, CLR .
,
.
. Microsoft (, CSC.exe
AL.exe)
( ), . Windows
.
AssemblyInformationalVersion
Win32 , , ; CLR
. ,
. , 2.0
. 1.0, ,
1.0.
.
.
87
,
(culture). , ,
, .. ,
( RFC1766).
. 2.6.
2.6. ,
De
De
AT
De
CH
En
En
GB
En
US
,
. ,
,
(culture neutral).
, , Microsoft
88
2. , ,
.
, .
,
, , . ,
, (satellite assemblies). , ,
.
, .
AL.exe.
. AL.exe, /c[ulture]:text, text (, en-US,
).
,
, . ,
C:\MyApp, C:\MyApp\en-US.
System.Resources.ResourceManager.
, . /culture AL.exe
System.Reflection.AssemblyCulture,
, , :
// Swiss German
[assembly:AssemblyCulture("de-CH")]
,
. , AssemblyRef
.
, , (.23).
( )
, .
, .
( )
89
Windows Store
. Visual Studio ,
, .appx, Windows Store,
. .appx,
, CLR
, Windows .
.appx,
, . Windows Store,
.
, Windows .
,
Windows Store. , Windows ,
.
( Windows Store)
. , . , ,
. -
.
, , , CLR
, .
,
, !
, , CAB- (
).
MSI-, Windows (Windows Installer), MSIExec.exe. MSI
CLR .
MSI,
EXE- DLL-.
, ,
(Start) .
, ,
, .
90
2. , ,
. , Visual Studio
MSI- -, FTP- .
MSI- , .NET
Framework Microsoft SQL Server Express Edition. ,
ClickOnce.
, , , (privately deployed assemblies),
(
). ,
,
, CLR
. ; .
.
// . ,
, ,
. , .
, ,
. CLR
, . CLR
COM, ,
, .
3 , .
( )
. ,
.
,
3.
,
.
, . ,
( )
91
. CLR .
XML-
. (
, ) ,
:
.
3 ,
. ,
MultiFileLibrary, .
:
AppDir ( )
Program.exe
Program.exe.config ( )
AuxFiles ( MultiFileLibrary)
MultiFileLibrary.dll
FUT.netmodule
RUT.netmodule
MultiFileLibrary , CLR ,
System.IO.FileNotFoundException. , XML
.
config, Program.exe.
config.
:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="AuxFiles" />
</assemblyBinding>
</runtime>
</configuration>
, CLR ,
, AuxFiles.
privatePath , ,
, . ,
. ,
,
.
92
2. , ,
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
...
, .
, CLR
, EXE DLL.
, FileNotFoundException.
: ,
, . , AsmName.dll en-US,
:
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
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
( )
93
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
, %SystemRoot% ,
Windows ( C:\Windows), ,
.NET Framework (, v4.0.#####).
Machine.config
.
Machine.config,
, ,
. , ,
,
.
3.
2 , .
(private deployment),
, ,
. ,
.
, . , Microsoft .NET Framework,
,
Microsoft .NET Framework Class Library (FCL).
2, Windows - ,
. , Windows, , ,
Microsoft. , ,
.
.NET Framework, , ,
.
, Microsoft, : ,
.. ,
.
, .
, , , Windows.
.
, , 0 1 , ,
, ,
, . ,
95
. - ,
.
, : ,
, , ? .
, , ,
,
. , , , , ,
.
.NET Framework, . :
. , , (CLR). ,
, .
, , ,
.
CLR : (weakly named
assemblies) (strongly named assemblies).
.NET Framework. ? , .
,
. ,
, .
,
PE (portable executable), PE32(+),
CLR-, , , IL-,
1 2. , C# AL.exe. ,
, .
, ,
,
.
96
3.
CLR
, .
,
CLR.
.
. .
2.
- ,
CLR . ,
. ,
. .3.1.
3.1. .
, , CLR , .
( ) . ,
,
, , ,
(
DLL Windows DLL
System32).
, , . CLR
,
. .
, : ( ),
, . ,
- ,
97
Version=1.0.8123.0,
Version=1.0.8123.0,
Version=2.0.1234.0,
Version=1.0.8123.0,
Culture=neutral,
Culture="en-US",
Culture=neutral,
Culture=neutral,
PublicKeyToken=b77a5c561934e089"
PublicKeyToken=b77a5c561934e089"
PublicKeyToken=b77a5c561934e089"
PublicKeyToken=b03f5f7f11d50a3a"
MyTypes.exe MyTypes.dll (
, ).
- 1.0.8123.0,
, , Culture
neutral. MyTypes.dll ( MyTypes.exe) 1.0.8123.0
.
, ,
, .
Microsoft ( GUID, URL URN) , . ,
,
. . , ,
, ,
. , , ,
.
2 , ,
.
. CLR ,
.
,
98
3.
SN.exe MyCompany.snk,
.
, , .
SN.exe, .
SN.exe : p,
, (MyCompany.PublicKey)1:
SN p MyCompany.keys MyCompany.PublicKey
SN.exe tp ,
:
SN tp MyCompany.PublicKey
:
Microsoft (R) .NET Framework Strong Name Utility Version 4.0.30319.17929
Copyright (c) Microsoft Corporation. All rights reserved.
Public key (hash algorithm: sha256):
00240000048000009400000006020000002400005253413100040000010001003f9d621b702111
850be453b92bd6a58c020eb7b804f75d67ab302047fc786ffa3797b669215afb4d814a6f294010
b233bac0b8c8098ba809855da256d964c0d07f16463d918d651a4846a62317328cac893626a550
69f21a125bc03193261176dd629eace6c90d36858de3fcb781bfc8b817936a567cad608ae672b6
1fb80eb0
Public key token is 3db32f38c8b42c9a
SN.exe .
Enhanced Strong Naming, .NET
Framework 4.5. , .NET Framework,
(counter-signature)
AssemblySignatureKey. http://msdn.
microsoft.com/en-us/library/hh415055(v=vs.110).aspx.
1
99
.
( ), . 64- -
. SN.exe tp,
.
, ,
.
/keyfile:_:
csc /keyfile:MyCompany.snk Program.cs
, C# (MyCompany.snk),
. : ,
, .
Visual Studio .
Signing, Sign the assembly,
Choose a strong name key file <New>.
:
FileDef
, . ,
, - ,
FileDef.
, , AL.exe /algid
, ,
System.Reflection.AssemblyAlgorithmIdAttribute. - SHA-1.
PE- - ( Authenticode Signature,
PE), .3.1.
SHA-1,
. - , RSA
PE- ( PE- ),
CLR- PE- ,
.
PE- (
AssemblyDef ). ,
,
, .
, ,
Calculus, ( ).
.
100
3.
. 3.1.
2, , . , .
C# /reference.
AssemblyRef . AssemblyRef
, ,
( ), , .
, ,
,
. Microsoft 8 -. AssemblyRef
.
, .
, CLR , ,
.
AssemblyRef (
ILDasm.exe) MultiFileLibrary.dll, 2:
101
AssemblyRef #1 (23000001)
Token: 0x23000001
Public Key or Token: b7 7a 5c 56 19 34 e0 89
Name: mscorlib
Version: 4.0.0.0
Major Version: 0x00000004
Minor Version: 0x00000000
Build Number: 0x00000000
Revision Number: 0x00000000
Locale: <null>
HashValue Blob:
Flags: [none] (00000000)
, MultiFileLibrary.dll , :
"MSCorLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
, ILDasm.exe Locale,
Culture.
AssemblyDef MultiFileLibrary.
dll, :
Assembly
-----------------------------------Token: 0x20000001
Name : MultiFileLibrary
Public Key
:
Hash Algorithm : 0x00008004
Version: 3.0.0.0
Major Version: 0x00000003
Minor Version: 0x00000000
Build Number: 0x00000000
Revision Number: 0x00000000
Locale: <null>
Flags : [none] (00000000)
:
"MultiFileLibrary, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null"
, MultiFileLibrary.dll, 2, , ,
. SN.exe, /keyfile,
.
ILDasm.exe,
AssemblyDef Public Key, ,
. , AssemblyDef , .
102
3.
. ,
.
,
, CLR
.
, , CLR
. ,
,
(global assembly cache, GAC). GAC
, .NET Framework.
GAC
%SystemRoot%\Microsoft.NET\Assembly
GAC ,
.
GAC
, . GAC .
GAC GACUtil.exe.
, :
Microsoft (R) .NET Global Assembly Cache Utility. Version 4.0.30319.17929
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.
/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>
103
/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
/?
Options:
/r <reference_scheme> <reference_id> <description>
Specifies a traced reference to install (/i, /il) or uninstall (/u, /ul).
/f
/nologo
Suppresses display of the logo banner
/silent
Suppresses display of all output
GAC
Windows Administrators. GACUtil.exe ,
.
/i GACUtil.exe
. GACUtil.exe
/r /i
/u . /r
Windows.
,
, .
104
3.
CAB- ,
, GAC
GACUtil.exe, ,
.
GACUtil.exe .NET
Framework, .
, GAC, Windows Installer (MSI), ,
GAC
.
GAC
, Windows.
GAC , ,
, .
, .
GAC? , OurLibrary, :
OurLibrary.dll. , ,
, ,
- . GAC
, %SystemRoot%\Microsoft.NET\Assembly
.
GAC,
. ,
GAC CLR , GAC.
,
, , .
, System.Object MSCorLib.dll,
. ,
, Microsoft,
105
. 2 ,
CSC.exe /reference
, .
, CSC.exe
. 2,
, CSC.exe
( ).
1. .
2. , CSC.exe. DLL CLR.
3. , /lib .
4. , LIB.
, , System.
Drawing.dll Microsoft, CSC.exe
/reference:System.Drawing.dll . -
System.Drawing.dll CSC.
exe , DLL CLR,
. ,
,
.
, .NET Framework , Microsoft, .
CLR, GAC. CLR
, GAC
.
CSC.exe GAC,
, GAC . ,
:
System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken= b03f5f7f11d50a3a
,
.
, CLR . ,
. IL ,
x86, x64 ARM. GAC
IL, .
,
GAC ;
, .
106
3.
CLR ,
. GAC
RSA,
PE- ( ).
, .
, FileDef.
,
GAC .
, , CLR
GAC (, ,
). ,
, , .
,
, ,
.
, AssemblyRef
, AssemblyDef , . GAC, CLR
, ,
; , MSI, CLR
MSI .
, System.
IO.FileNotFoundException.
GAC, ,
, , . .
CLR ,
, .
, GAC, CLR
,
,
.
GAC,
( , codeBase
107
) CLR -. ,
.
, , .
-, CLR System.
IO.FileLoadException.
SN.exe. ,
Microsoft API-
Crypto. . , ( Microsoft)
,
.
. , , ,
.
,
. , ,
.NET Framework (delayed signing),
(partial signing).
,
. AssemblyRef
, ,
, GAC.
, , ,
. ,
,
.
, . ( , , , SN.exe
p.) ,
, , .
C# /delaysign. Visual Studio
Signing Delay sign only.
AL.exe /delay[sign].
108
3.
, ,
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.
, , , 64-
64- . 32- x86
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\
NETFX 4.0 Tools, 64 x64 C:\Program
Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\x64.
,
. ,
SN.exe, R, , . R SN.exe
,
RSA . .
, SN.exe
Vu Vx.
.
1. , ,
/keyfile /delaysign:
csc /keyfile:MyCompany.PublicKey /delaysign MyAssembly.cs
109
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,
-.
110
3.
GAC . GAC
,
. , GAC
(.). GAC
. GAC
,
GAC . , GAC
.
GAC,
. GAC,
. , .
. , GAC
C:\Windows\System32
.
, .
codeBase URL,
Web. - CLR
(
C:\Documents and Settings\<UserName>\Local Settings\ApplicationData\Assembly,
<UserName> , ). CLR
URL-. , CLR (
).
codeBase .
GAC , , . , ,
.
.
XML-, codeBase .
111
CLR , , . ,
. ,
,
.
2 :
public sealed class Program {
public static void Main() {
System.Console.WriteLine("Hi");
}
}
Program.exe. CLR.
JIT- CLR
, ( -
112
3.
). , System.Console.
Write-Line: Call 0A000003.
3 MemberRef ( 0A). , CLR ,
TypeRef ( System.Console). TypeRef
CLR AssemblyRef:
MSCorLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
CLR , ,
.
CLR
.
. , , ( ).
, .
. , ,
, FileRef .
, ,
. , -,
, CLR
, .
. , ,
, .
,
, CLR , .
(
, - ..), .
System.AppDomain.AssemblyResolve, System.AppDomain.
ReflectionOnlyAssemblyRessolve System.AppDomain. TypeResolve. ,
.
113
. 3.2. - , CLR, ,
, IL-
- , .
: CLR , , . GAC ,
, , .
GAC CLR , -
114
3.
, .
, , .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 , ,
.
. CLR
.
CLR (, , , ) . ,
.NET3.5 System.TimeZoneInfo System.Core.dll. .NET
4.0 Microsoft MsCorLib.dll.
.
CLR System.Runtime.CompilerServices.
TypeForwardedToAttribute, (, System.Core.dll). System.
Type. ( MSCorLib.dll), . ,
TypeForwardedToAttribute ,
, .
,
System.Runtime.CompilerServices.TypeForwardedToAttribute
, .
, . TypeForwardedToAttribute
, , , ,
.
( )
115
( )
( ) 2
, CLR. ,
, ,
CLR XML
.
2 privatePath probing,
XML-:
<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas
microsoft
com:asm.v1">
<probing privatePath="AuxFiles;bin\subdir" />
<dependentAssembly>
<assemblyIdentity name="SomeClassLibrary"
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/SomeClassLibrary.dll" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="TypeLib"
publicKeyToken="1f2e74e897abbcfe" culture="neutral"/>
<bindingRedirect
oldVersion="3.0.0.0
3.5.0.0" newVersion="4.0.0.0" />
<publisherPolicy apply="no" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
XML- CLR .
probing. AuxFiles bin\subdir, ,
116
3.
( )
117
2. ,
, codeBase, CLR URL-,
.
, CLR
. , , ,
. CLR ,
.
CLR ,
XML- .
, , ,
,
Machine.config , CLR
.
, ,
, , . ,
, . .
, ,
,
XML- .
, .
, - CLR
. ,
XML- ,
. ,
. , .
, , ,
.
, XML-. ,
. SomeClassLibrary.
config SomeClassLibrary.dll:
<configuration>
<runtime>
118
3.
<assemblyBinding xmlns="urn:schemas
microsoft
com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="SomeClassLibrary"
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/SomeClassLibrary.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
, .
, , . ,
probing publisherPolicy.
CLR
1.0.0.0 SomeClassLibrary 2.0.0.0. ,
, ,
. AL.exe
:
AL.exe /out:Policy.1.0.SomeClassLibrary.dll
/version:1.0.0.0
/keyfile:MyCompany.snk
/linkresource:SomeClassLibrary.config
AL.exe.
/ o u t AL.exe PE-
Policy.1.0.SomeClassLibrary.dll, , .
. , Policy,
CLR, .
, 1.0, CLR,
SomeClassLibrary,
1.0. ;
. , SomeClassLibrary,
, . , dll, ,
.
/version ,
. ,
( )
119
, , . , CLR 1.0.0.0
SomeClassLibrary 2.0.0.0, ,
1.0.0.0 SomeClassLibrary 2.5.0.0.
CLR , ,
.
/keyfile AL.exe
, .
, SomeClassLibrary. , CLR
, SomeClassLibrary
.
/linkresource AL.exe
XML .
.
SomeClassLibrary.
, XML- , AL.exe /embedresource,
CLR ,
XML .
, ,
SomeClassLibrary.dll . GAC. SomeClassLibrary
GAC, .
, URL-
codeBase.
.
.
. ,
, - , . , CLR
.
, publisherPolicy:
<publisherPolicy apply="no"/>
<assemblyBinding> -
120
3.
. <dependantAssembly>, .
, CLR , GAC
, . , CLR ,
Machine.config.
.
, . , ,
. . ,
, ,
. ,
.
II
4. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..122
5. ,
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 142
6. . .. .. .. .. 186
7. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 210
8. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..215
9. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 245
10. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..263
11. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 286
12. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 302
13. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..333
4.
(Common Language Runtime, CLR). , , , ,
, ,
. , , , .
System.Object
CLR System.
Object. , :
// , Object
class Employee {
...
}
// , Object
class Employee : System.Object {
...
}
, , ,
System.Object,
. System.Object -
. 4.1.
4.1. System.Object
Equals
true, .
5
GetHashCode
- .
, -. , Object
,
-; .
- 5
System.Object
123
ToString
(this.GetType().
FullName). ,
String,
. , , Boolean Int32,
. , :
, . ,
ToString CultureInfo, . ToString
14
GetType
, Type,
, GetType.
Type , .
23. GetType , ,
;
, , System.Object, (.4.2).
4.2. System.Object
Memberwise
Clone
this.
Finalize
, , ,
. ,
, . .
21
CLR , new. ,
Employee :
new :
124
4.
1. , , System.Object (
). ,
,
- (type object pointer) (sync block
index); CLR . ,
.
2.
. (0).
3. - .
4. ,
new ( ConstructorParam1 ).
.
. , System.
Object, .
, new ( )
. e Employee.
, new delete,
, . CLR
(.21), ,
, .
CLR (type safety).
CLR .
GetType.
, .
, Employee GetType,
SuperHero.
.
CLR
. -. , C#
,
125
.
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;
}
}
, .
, . CLR
, , . , ,
InvalidCastException:
internal class Employee {
...
}
internal class Manager : Employee {
...
}
public sealed class Program {
public static void Main() {
// Manager PromoteEmployee
// Manager Employee,
// PromoteEmployee
Manager m = new Manager();
PromoteEmployee(m);
// DateTime PromoteEmployee
// DateTime Employee,
// PromoteEmployee
// System.InvalidCastException
DateTime newYears = new DateTime(2013, 1, 1);
PromoteEmployee(newYears);
}
126
4.
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
127
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
}
, . ,
:
internal class B { //
}
internal class D : B { //
}
.4.3 C#.
CLR.
128
4.
, OK,
CTE (compile-time error),
RTE (run-time error).
4.3.
OK
Object o4 = o3;
B b1 = new B();
B b2 = new D();
D d1 = new D();
CTE
B b3 = new Object();
D d2 = new Object();
B b4 = d1;
RTE
D d3 = b2;
D d4 = (D) d1;
D d5 = (D) b2;
D d6 = (D) b1;
B b5 = (B) o1;
B b6 = (D) b2;
C# ,
8. , ,
is as C#.
,
. ,
System.Text , System.
129
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.
:
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# ,
. using C#
, .
CLR . -
CLR (
) , ,
, .
, :
, , ,
, ..
, System.IO ,
. ,
130
4.
System.Text. using,
, FileStream StringBuilder
System.IO.FileStream System.
Collections.StringBuilder. , ,
, .
/reference (. 2
3), .
. ,
. ,
, . C# MSCorLib.dll,
. FCL-,
Object, Int32, String .
, , ( ) .
Microsoft
. . CLR
. , , Microsoft
Wintellect, , Widget.
Widget Microsoft , Wintellect .
,
, .
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(); //
}
}
131
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 {
}
// TypeDef: CompanyName.A
namespace X {
public sealed class B { ... } // TypeDef: CompanyName.X.B
}
}
,
CLR .
132
4.
,
. C# namespace
.
(, )
. , , , . ,
System.IO.FileStream MSCorLib.dll, System.
IO.FileSystemWatcher System.dll. , System.IO.dll
.NET Framework .
. ,
System.Int32 System.Text.StringBuilder MSCorLib.dll.
.NET Framework SDK, ,
, , ,
. .4.1 , ResXFileRef System.Resources System.Windows.Forms.
dll. , ResXFileRef, using System.Resources
/r:System.Windows.forms.dll.
. 4.1. SDK
133
, , , . , ,
, . . , ,
, CLR, ,
, CLR.
.4.2 Microsoft Windows
CLR. .
1.
. .4.2 .
(
). - ,
- (
). , , M1.
. 4.2. M1
, , (prologue
code), . , (epilogue code), ,
, . M1
name (.4.3).
M1 M2, name. name (.4.4).
M2 - s. (,
,
134
4.
.)
( .4.4).
. 4.3. M1
. 4.4. M2 M1 .
M2
length tally (.4.5).
M2. , M2 , , M2
, .4.3.
M1, M2,
, M1.
, M1 ,
( , name), M1
, .4.2.
, , M1,
, .
135
. 4.5. M2
CLR. ,
:
internal
public
public
public
}
class Employee {
Int32 GetYearsEmployed () { ... }
virtual String GetProgressReport () { ... }
static Employee Lookup(String name) { ... }
Windows , CLR,
, ( 1 ). - , M3 (.4.6). M3
, , CLR;
, , , .
IL- 3 JIT
, M3, Employee,
Int32, Manager String (- "Joe"). CLR ,
. , , CLR
, .
- Employee Manager .4.7.
M3 - , , - Int32 String ( ,
), .
-.
, : - . Employee
Manager .
136
4.
.
-. , -
, . 1. Employee
(GetYearsEmployed, GenProgressReport Lookup),
. Manager (
GenProgressReport), .
. 4.6. CLR , ,
, M3
137
CLR -
M3,
M3. M3 (.4.8). , CLR
null 0 ()
.
, , #
Use of unassigned local variable ( ).
. 4.8. M3
M3 Manager.
Manager, Manager (.4.9).
Manager -
. ,
, Manager,
,
Manager ( Employee Object). CLR
- , - (
- Manager). , CLR
null
0 () , , ,
. new
Manager, e ( ).
138
4.
. 4.9. Manager
M3 Lookup
Employee. CLR -,
, .
- CLR ,
JIT- ( )
. ,
Lookup Employee ,
Joe. , , Joe , Lookup Manager,
Joe . e. .4.10.
M3
GenProgressReport Employee.
CLR . -, CLR
, , . e Joe
Manager. -, CLR -.
CLR - ,
JIT- ( )
. GenProgressReport
Manager, e Manager.
.4.12.
, Lookup Employee , Joe
Employee, Manager, Lookup Employee,
139
- - Employee; ,
GenProgressReport Employee, Manager.
, , IL
JIT-, , ,
, .
, - (
140
4.
). , CLR
, . CLR , , .
, CLR.
, Employee Manager -. - .
141
-, CLR - .
: ? ,
CLR -
System.Type ( MSCorLib.dll). Employee Manager , -
- System.Type (.4.13).
, - System.Type -; , ,
. , - System.
Type -. , CLR. , GetType
System.Object , -
. , GetType
( -).
5. ,
,
Microsoft .NET Framework. ,
. .NET Framework, , ,
,
. ,
.
,
. ,
:
System.Int32 a = new System.Int32();
, . , ( C#)
, :
int a = 0;
143
. 5.1 FCL
C#. ,
(Common Language Specification, CLS),
. , CLS,
.
5.1. # FCL
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
float
System.Single
32- IEEE
double
System.Double
64- IEEE
bool
System.Boolean
(true false)
decimal
System.Decimal
128-
,
,
. ,
96
, 8
10,
96- ( 0 28).
144
5. ,
5.1 ()
FCL-
CLS
string
System.String
object
System.Object
dynamic
System.Object
CLR dynamic
object. #
dynamic
.
dynamic
, , C# ,
using ( 4):
using
using
using
using
using
using
...
sbyte = System.SByte;
byte = System.Byte;
short = System.Int16;
ushort = System.UInt16;
int = System.Int32;
uint = System.UInt32;
C#:
, ,
FCL- . , , ,
FCL-. .
, , : string String. C# ,
string FCL- System.String. ,
, 32-
int 32- , 64 64 . : C# int
System.Int32, 32-
.
Int32 .
C# long System.Int64,
Int16 Int32. , ++/CLI long Int32.
145
- , ,
.
long, , .
FCL- , . , BinaryReader ReadBoolean, ReadInt32, ReadSingle
.., System.Convert ToBoolean, ToInt32, ToSingle ..
, , float,
; , :
BinaryReader br = new BinaryReader(...);
float val = br.ReadSingle(); // ,
Single val = br.ReadSingle(); //
, #, ,
CLR . ,
FCL #, FCL
, GetLongLength Array, Int64, long #,
(, C++/CLI). LongCount
System.Linq.Enumerable.
FCL.
:
Int32 i = 5; // 32-
Int64 l = i; // 64-
, 4,
, . - System.Int32 System.Int64,
. : , . , C#
.
, IL-,
, . , ,
, .
,
, :
Int32 i = 5; //
Int64 l = i; //
Single s = i; //
Byte b = (Byte) i; //
Int16 v = (Int16) s; //
Int32 Int32
Int32 Int64
Int32 Single
Int32 Byte
Single Int16
C# , ,
; Int32 Int64.
146
5. ,
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 )
, , . ,
(, - ),
, .
147
CLR
32 ( 64 ,
32 ). b 200 ( 32
) 32- , . 32- (300 , 12C
), b,
Byte. C# ,
Byte.
. C C++
, . Visual Basic
, .
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
148
5. ,
checked unchecked C# ,
:
checked { //
Byte b = 100;
b = (Byte) (b + 200); //
} //
, += Byte,
:
checked { //
Byte b = 100;
b += 200; //
} //
,
checked, ( ) checked IL- , ,
. :
checked {
// , SomeMethod 400 Byte
SomeMethod(400);
// OverflowException SomeMethod
//
}
, .
-
- . , checked
unchecked.
(Int32 Int64)
(UInt32 UInt64) , . . ,
(, Length Array String) ,
( ,
149
). ,
CLS.
checked , , ,
, .
, OverflowException,
.
unchecked ,
(, ).
, checked unchecked, ,
. ,
,
.
/checked+. ,
, checked unchecked.
, .
/checked-, ; .
checked Microsoft Visual Studio,
, Build, Advanced
Check for arithmetic overflow/underflow, .5.1.
. 5.1. .
Visual Studio Advanced Build Settings
, /checked .
150
5. ,
. ,
, OverflowException,
- .
System.Decimal .
( C# Visual Basic), CLR Decimal .
CLR IL- Decimal. .NET
Framework , Decimal - Add,
Subtract, Multiply, Divide , +, -, *, / ..
Decimal
Decimal, . Decimal
CLR-. , IL-
Decimal,
checked unchecked, , Decimal
OverflowException.
, System.Numerics.BigInteger UInt32
,
. , BigInteger
OverflowException.
OutOfMemoryException, .
CLR : (reference types) (value types). FCL ,
.
, C# new ,
.
, :
;
, , , ;
(
);
.
,
. , ,
151
Int32 ! , , CLR
.
( ).
;
. , (dereference) .
,
,
,
.
.NET Framework , , . (class),
. , System.Object, System.Exception,
System.IO.FileStream System.Random . ,
(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 -
. . 15.
, . , CLR ,
-
. , ,
Boolean, Char, Int32, Uint64, Single, Double, Decimal ..
( , , C/C++)
. C/C++ , ,
: . : ,
, , ,
, , .
( .5.2) :
152
5. ,
// ( '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"
// . 5.2
//
SomeRef r2 = r1; // ()
SomeVal v2 = v1; //
r1.x = 8; // r1.x r2.x
v1.x = 9; // v1.x, v2.x
Console.WriteLine(r1.x); // "8"
Console.WriteLine(r2.x); // "8"
Console.WriteLine(v1.x); // "9"
Console.WriteLine(v2.x); // "5"
// . 5.2
//
}
. 5.2.
SomeVal struct,
class. C# , struct,
, class, .
153
.
, : ,
.
:
SomeVal v1 = new SomeVal(); //
, SomeVal .
C# , SomeVal ,
SomeVal . C#
.
:
SomeVal v1; //
, ,
. .
, .
. , ,
,
, , (immutable).
, readonly
(.7).
.
.
, ;
, . :
, , ,
154
5. ,
, .
, :
( 16 ).
( 16 ),
.
, . ,
. :
(. ):
(unboxed) (boxed).
.
System.ValueType.
, System.Object. System.ValueType
Equals, true,
. , System.ValueType GetHashCode,
- , . - , ,
Equals GetHashCode. Equals
GetHashCode .
,
.
( ).
. , null,
.
NullReferenceException.
,
0.
,
NullReferenceException . CLR
, null (nullable types).
19.
, . -
155
,
.
, ,
, , .
,
.
,
, ( ).
CLR
CLR
. , CLR ,
, . ,
, ,
CLR .
CLR ,
System.Runtime.InteropServices.StructLayout
Attribute. CLR, LayoutKind.Auto, LayoutKind.Sequential, LayoutKind.
Explicit , . StructLayoutAttribute,
.
() C# LayoutKind.
Auto, () LayoutKind.Sequential. , , , , ,
. ,
, , , , , :
using System;
using System.Runtime.InteropServices;
// CLR
//
[StructLayout(LayoutKind.Auto)]
internal struct SomeValType {
private readonly Byte m_b;
156
5. ,
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)]
private readonly Byte m_b; // m_b m_x
[FieldOffset(0)]
private readonly Int16 m_x; //
}
, . ,
,
, .
: , ,
. ,
Point ArrayList
( System.Collections). :
//
struct Point {
public Int32 x, y;
}
public sealed class Program {
public static void Main() {
157
Point,
Point ArrayList. , ArrayList:
Point, Point - ?
Add ArrayList .
Add :
public virtual Int32 Add(Object value);
, Add Object,
( ) .
p, Point. , Point .
(boxing).
.
1. .
.
.
2. , .
3. . ,
.
C# IL-, , , ,
.
C# , ,
, ,
. p Point
Point. Point ( )
Add. Point . p Point , ArrayList
. :
.
158
5. ,
FCL , -
. , System.
Collections.ArrayList System.Collections.Generic.List<T>.
. , API- , ,
.
, /.
, , ,
, .
,
(. 12).
, . ,
ArrayList:
Point p = (Point) a[0];
( ), 0
ArrayList, p Point. ,
Point, p
, . CLR
. Point Point.
(unboxing).
, .
.
, ,
( ), . ,
,
( ) .
.
, / ( ,
), ,
, .
.
1. , ,
null, NullReferenceException.
2. ,
, InvalidCastException1.
CLR , null (. 19).
1
159
, ,
:
public static void Main() {
Int32 x = 5;
Object o = x; // x; o
Int16 y = (Int16) o; // InvalidCastException
}
, .
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, .
:
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.
, , () ( ). , ,
.
160
5. ,
, C++/CLI, , .
(
). ,
, (
). ,
C++/CLI ,
x Point Point. ,
!
, , ,
. , ,
. , ,
ILDasm.exe, IL- ,
.
, :
public static void
Int32 v = 5; //
Object o = v; //
v = 123; //
Main() {
o
Int32, 5
123
?
! , , IL- Main.
, .
.method public hidebysig static void
{
.entrypoint
// 45 (0x2d)
.maxstack 3
.locals init ([0]int32 v,
[1] object o)
// 5 v.
IL_0000: ldc.i4.5
IL_0001: stloc.0
// v o.
IL_0002: ldloc.0
IL_0003:
IL_0008:
box
stloc.1
161
[mscorlib]System.Int32
// 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
v,
Int32, 5.
WriteLine, String,
. Int32 (v), String ( )
Int32 (o), Int32. - ,
String.
String, C# ,
Concat String.
, .
162
5. ,
, 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"
o (Int32). ,
o Object
Concat. , :
. ,
IL-:
.method public hidebysig static void
{
.entrypoint
// 35 (0x23)
.maxstack 3
.locals init ([0] int32 v,
[1] object o)
// 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
163
// 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
v = 123; // 123
Console.WriteLine(v); // "123"
v = (Int32) o; // o v
Console.WriteLine(v); // "5"
}
164
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 , .
, (,
, ).
, ,
(.12).
, : , - , -
165
,
. .
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
.
.
,
. : ,
. ,
, .
, .
, , ,
:
;
, :
.
, ,
System.Threading.Monitor ( lock
C#).
166
5. ,
,
(, Equals, GetHashCode
ToString), . , CLR
,
. , , , .
,
, this
.
(, GetType
MemberwiseClone) ,
System.Object, , this .
,
, , . (
. 13.) :
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 ( ToString )
return String.Format("({0}, {1})", m_x.ToString(), m_y.ToString());
}
// 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()) {
167
,
/.
ToString. ToString p1 . ,
p1 , ToString , , System.ValueType.
168
5. ,
, p1
, Point. JIT- ,
ToString Point, ,
() ToString. ,
, Point ,
- . ToString Point
base.ToString(),
ToString System.ValueType.
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.
169
Point. c Point, , c, ,
p2, Point, .
, ,
. , .NET Framework,
.
(
)
, , . : ,
.
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.ToString(), m_y.ToString());
}
}
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;
170
5. ,
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
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.To_String(), m_y.ToString());
171
.
, 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#
.
172
5. ,
, ,
, -
. , readonly, ,
, .
.
,
. , ,
. ,
,
.
.
(, ), , . ,
, .
, , .
. ,
- ,
. Point class, struct
, . , ,
, FCL Byte, Int32, UInt32, Int64, UInt64,
Single, Double, Decimal, BigInteger, Complex ,
.
. ,
,
, .
, ,
, .
System.Object Equals,
true . Equals
Object:
public class Object {
public virtual Boolean Equals(Object obj) {
// ,
// ,
if (this == obj) return true;
// ,
return false;
}
}
173
:
, this obj, ,
true, false. ,
Equals , .
, Equals ,
, false. , ,
Equals Object
, .
, .
,
Equals.
Equals:
1. obj null, false, , ,
this, null Equals.
2. obj this , true.
.
3. obj this , false.
, String FileStream false.
4. obj this.
, false.
5. Equals ,
. Equals false, false,
true.
, Microsoft Equals
Object :
public class Object {
public virtual Boolean Equals(Object obj) {
// null
if (obj == null) return false;
//
if (this.GetType() != obj.GetType()) return false;
// , true ,
// .
// System.Object ,
// ,
return true;
}
}
174
5. ,
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 Equals .
, false.
4. true. Equals ValueType
Object.
3 Equals ValueType
(.23). CLR , Equals ,
. , ,
Equals .
Equals, , :
: x.Equals(x) true.
: x.Equals(y) y.Equals(x)
.
175
-
FCL , - .
System.Object GetHashCode, (Int32) -.
Equals, GetHashCode.
, C# . ,
: warning
CS0659: 'Program' overrides Object.Equals(Object o) but does not override
Object.GetHashCode() ('Program' Object.Equals(Object o),
Object.GetHashCode()).
public sealed class Program {
public override Boolean Equals(Object obj) { ... }
}
176
5. ,
, Equals
GetHashCode , , System.Collections.
Hashtable, System.Collections.Generic.Dictionary
, -. , Equals, GetHashCode
, , ,
- .
, - ,
- . ,
-. , -. -
, .
,
, .
-,
-, , -
-.
GetHashCode .
, .
, Point:
internal sealed class Point {
private readonly Int32 m_x, m_y;
public override Int32 GetHashCode() {
return m_x ^ m_y; // m_x m_y
}
...
}
- , :
, ,
-.
GetHashCode
,
GetHashCode Object ValueType, .
.
, , ,
.
.
dynamic
177
. , String, ,
-.
GetHashCode System.Object
. ,
; ,
.
- ,
GetHashCode, -.
. ,
-
.
, .
- , .
(String) GetHashCode, . -
, GetHashCode ,
- .
. , CLR
GetHashCode String -.
-!
dynamic
C# . , ,
, .
, , ,
,
.
,
IL
.
, - ,
, .
,
(, C#) ,
, , , -
178
5. ,
.
C#,
, ,
(. 23). #
, #.
, Python Ruby,
COM-, IDispatch (,
C++), DOM (Document Object
Model), .
DOM- Silverlight-.
, #
(dynamic). .
() ,
, /, , , /
. (), IL-,
. (payload).
, ().
, :
internal static class DynamicDemo {
public static void Main() {
dynamic value;
for (Int32 demo = 0; demo < 2; demo++) {
value = (demo == 0) ? (dynamic) 5 : (dynamic) "A";
value = value + value;
M(value);
}
}
Main :
M(Int32): 10
M(String): AA
, , +.
dynamic. # ,
value ,
+.
dynamic
179
+ 5 ( Int32),
10 ( Int32).
value. M, value. M
,
, M.
value Int32, M,
Int32.
+ A ( String), AA ( ).
M, value.
, , M, ,
M .
, ,
dynamic,
System.Object System.Runtime.CompilerServices.
DynamicAttribute , .
,
Object, DynamicAttribute - , . - ,
dynamic Object , ,
dynamic Object.
dynamic ( ), ( ), , . , dynamic
Object DynamicAttribute ,
. , , ,
Object,
,
.
dynamic, , Object1.
Object , .
dynamic .
Object o1 = 123; // OK: Int32 Object ()
Int32 n1 = o1; // : Object Int32
Int32 n2 = (Int32) o1; // OK: Object Int32 ()
dynamic d1 = 123; // OK: Int32 dynamic ()
Int32 n3 = d; // OK: dynamic Int32 ()
, .
180
5. ,
, CLR . , CLR InvalidCastException.
:
dynamic d = 123;
var result = M(d); // 'var result' - , 'dynamic result'
, , M . ,
, M. , result . ,
var Visual Studio
IntelliSense- .
dynamic: Represents an object whose operations will be resolved at runtime.
M, , void, Microsoft.CSharp.RuntimeBinder.RuntimeBinderException.
dynamic ,
, . dynamic
, :
dynamic d = 123;
var x = (Int32) d; // : 'var x' 'Int32 x'
var dt = new DateTime(d); // : 'var dt' 'DateTime dt'
dynamic foreach
using, , System.IEnumerable
System.IDisposable . , , .
Microsoft.CSharp.RuntimeBinder.
RuntimeBinderException.
dynamic
181
dynamic , System.Object. ,
. ,
. Visual
Studio - IntelliSense-
.
dynamic ( 8), Object.
- ( 17) ,
.
C# COM- IDispatch
Microsoft Office Excel A1.
using Microsoft.Office.Interop.Excel;
...
public static void Main() {
Application excel = new Application();
excel.Visible = true;
excel.Workbooks.Add(Type.Missing);
((Range)excel.Cells[1, 1]).Value = "Text in cell A1";
// A1.
}
182
5. ,
// ,
Type[] argTypes = newType[] { arg.GetType() };
MethodInfo method = target.GetType().GetMethod("Contains", argTypes);
//
Object[] arguments = newObject[] { arg };
Boolean result = Convert.ToBoolean(method.Invoke(target, arguments));
C# dynamic,
.
dynamic target = "Jeffrey Richter";
dynamic arg = "ff";
Boolean result = target.Contains(arg);
, C# ,
. ,
(runtime binder). , .
C# Microsoft.CSharp.dll,
,
dynamic. , CSC.rsp.
, + Int32 ,
String .
Microsoft.CSharp.dll ,
. , Microsoft.SCharp.dll System.dll
System.Core.dll. dynamic COM-,
System.Dynamic.dll.
, ,
, (Anonymously Hosted
Dynamic Methods Assembly).
,
(call site) , .
- , C#, ,
:
.
, : ( ), ( COM-).
#
. ,
dynamic
183
IDynamicMetObjectProvider. , GetMetaObject, ,
DynamicMetaObject. ,
, . IDynamicMetaObjectProvider
DynamicMetaObject System.
Dynamic System.Core.dll.
, Python Ruby, ,
DynamicMetaObject, (, C#). C# COM DynamicMetaObject,
COM-. DynamicMetaObject
System.Dynamic.dll.
, ,
IDynamicMetaObjectProvider, C#
C#
.
,
, .
,
. StaticMemberDynamicWrapper,
System.Dynamic.DynamicObject,
IDynamicMetaObjectProvider.
(. 23). StaticMemberDynamicWrapper.
internal sealed class StaticMemberDynamicWrapper : DynamicObject {
private readonly TypeInfo m_type;
public StaticMemberDynamicWrapper(Type type) { m_type = type.GetTypeInfo(); }
public override IEnumerable<String> GetDynamicMemberNames() {
return m_type.DeclaredMembers.Select(mi => mi.Name);
}
public override Boolean TryGetMember(GetMemberBinder binder, out object result)
{
result = null;
var field = FindField(binder.Name);
if (field != null) { result = field.GetValue(null); return true; }
var prop = FindProperty(binder.Name, true);
if (prop != null) { result = prop.GetValue(null, null); return true; }
return false;
}
public override Boolean TrySetMember(SetMemberBinder binder, object value) {
var field = FindField(binder.Name);
184
5. ,
if (field != null) { field.SetValue(null, value); return true; }
return m_type.DeclaredProperties.FirstOrDefault(
pi => pi.Name == name && pi.SetMethod != null &&
pi.SetMethod.IsPublic && pi.SetMethod.IsStatic);
,
Type .
-
dynamic
185
. Concat(String,
String) String:
6.
4 5 , . , ,
. ,
,
. 7 11 .
.
, .
, ,
. ,
,
. .7.
,
/.
. ()
.
,
. .7.
, . .8.
,
. .8.
, , ( )
( ).
. .8.
,
.
187
CLS,
. .8.
,
.
CLS , . .8.
,
( )
. (
) ( , ).
.10.
.
() .
, . ,
() .
, -
. .11.
. ,
.
,
, .
, IL- .
CLR .
, ,
.
CLR , , , ,
. ,
Microsoft .NET Framework;
, .
C#
. ( ),
188
6.
,
. , .
using System;
public sealed class SomeType {
// 1
//
private class SomeNestedType { }
// 2
// ,
//Constant,read
only,andstaticread/writefield
privateconst
Int32 c_SomeConstant =1
;
privatereadonlyStringm_SomeReadOnlyField ="2";
privatestatic
Int32 s_SomeReadWriteField=3;
// 3
// 4
// 5
//
static SomeType() { }
// 6
//
public SomeType(Int32 x) { }
public SomeType() { }
// 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 (.6.1).
, .
, , (17), ( ) .
, ,
,
, .
189
. 6.1. , ILDasm.exe.
,
(public) (internal).
. ,
. C# ( ). .
using System;
//
public class ThisIsAPublicType { ... }
//
internal class ThisIsAnInternalType { ... }
// ,
class ThisIsAlsoAnInternalType { ... }
: ,
, , .
, ,
, , ;
.
190
6.
,
. ,
.
, ,
. , , ,
. ,
,
. CLR C#
(friend assemblies). , , ,
.
,
, InternalsVisibleTo, System.Runtime.CompilerServices.
,
( , ). ,
,
. ,
Wintellect Microsoft:
using System;
using System.Runtime.CompilerServices; // 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;
}
}
191
, , ,
. , (
InternalsVisibleTo) C# /out:. , , .
, C#
, ;
.
.
, ( )
/t:module, ,
/moduleassemblyname: C#.
, ,
.
( )
. ,
. CLR ,
. , Assembly CLR , ,
C# internal.
. 6.1 ,
(Private) (Public).
6.1.
CLR
C#
Private ()
private
Family ()
protected
( )
Family and
Assembly (
)
( )
( )
192
6.
6.1 ()
CLR
C#
Assembly ()
internal
Assembly or Family
(
)
protected
internal
, ( )
Public ()
public
,
. , ,
, B ,
B.
. -
, . , JIT-
IL- . , , , JIT-
FieldAccessException MethodAccessException .
IL- ,
. , , ( );
,
(protected) (private), .
, C# ( ) . CLR ,
. C#
, .
C# ,
, C#
, Declared Accessibility C#.
193
, . 6.1, CLR
. C#
C#.
, C#
, . ,
. C#,
CLR. CLR , . ,
, .
,
. CLR
,
.
, ,
Console, Math, Environment ThreadPool.
. , . , Math ,
. C#
static. , (
), CLR ,
.
.
System.Object
,
, .
, .
(, ,
). .
,
, , , .
, .
, ;
.
194
6.
using System;
public static class AStaticClass {
public static void AStaticMethodQ { }
public static String AStaticProperty {
get { return s_AStaticField; }
set { s_AStaticField = value; }
}
private static String s_AStaticField;
}
.6.2
ILDasm.exe (DLL) , -
. , static
C# (abstract) (sealed). ,
(.ctor).
. 6.2. ILDasm.exe
partial C#, ,
.
195
; CLR . ,
.
. ,
.
, -
, . partial ,
.
.
.
.
, , , .. ,
.
(
).
. Microsoft Visual Studio
Windows Forms Web Forms
. . Visual Studio
.
. ,
.
. Visual Studio 2005, Visual Studio
: , , .
.
partial
. , exe dll (
netmodule). ,
C#;
.
196
6.
,
- ()
. 70- 80- -
,
. , ,
,
.
, , , - (, ,
), ..
. ,
. ,
.
.
(Component Software Programming,
CSP) . .
( .NET) .
, ,
.
(
.NET
).
( ).
. C#
XML-
/doc .
. CLR
(Code Access Security, CAS).
( )
. (servicing)
, .
,
197
.
.
,
. ,
.
,
, .
.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).
, . , CLR
. 1.2.3.4
, CLR 1.2.3.4 (
).
CLR (
C#), , .
, ,
(),
(). ,
. ,
.
C# / , , CLR. . 6.2 C#,
, .
198
6.
6.2. C# .
C#
//
abstract
()
virtual
()
()
override
()
()
sealed
.
,
()
new
, , , ,
, ,
,
CLR.
, CLR
, , , ,
.
, ( ) ().
, , (void).
,
.
,
. (
IL) , ,
199
. , C#
(.8).
Employee .
internal class Employee {
//
public Int32 GetYearsEmployed { ... }
// ( - , )
public virtual String GetProgressReport { ... }
//
public static Employee Lookup(String name) { ... }
}
. , ,
, .
, ,
, , IL-
. CLR :
call , .
, , .
,
, call ,
null . , ,
. ,
. call
.
callvirt ( ) . , .
, ,
. callvirt
CLR ,
, .
JIT-
null, CLR NullReferenceException.
- callvirt , call. null
.
, C#.
200
6.
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 o)
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,
.
using System;
public sealed class Program {
public Int32 GetFive() { return 5; }
public static void Main() {
Program p = null;
Int32 x = p.GetFive(); // C# NullReferenceException
}
}
201
. p null,
GetFive CLR p,
Program. GetFive this null, GetFive
, . C# call callvirt,
NullReferenceException.
,
. ,
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 , , .
, .
, ,
null, NullReferenceException . ,
CLR
,
, .
, .
202
6.
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) {
returnFind(value,startIndex,m_length startIndex);
}
//
//
public virtual Int32 Find(Object value, Int32 startIndex, Int32 endIndex) {
// , ...
}
//
}
.NET Framework ,
, .
.
( ,
), . , -
.
, ,
203
. ,
.
, .
, ,
.
. ( 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 ToStringO {
return String.Format("({0}, {1})", m_x, m_y);
}
public static void Main() {
Point p = new Point(3, 4);
// C# callvirt,
// JIT-
// ToString,
// p Point,
Console.WriteLine(p.ToString());
}
}
204
6.
.
. ,
,
, . , . ,
,
, .
,
.
,
. . CLR
,
C# (. 8),
ConditionalWeakTable (. 21).
, :
,
. , C#
.
, . ,
C#. ,
, ,
, .
,
. , C# . ,
, C# ,
protected, internal, public .. .
. (internal)
,
, .
, . , C# . ,
, ,
, , . ,
205
- ,
.
: .
, ,
. , .
.
, FxCopCmd.
exe Visual Studio
( ),
. , .
, . 3 (
, , ).
. ,
.
.
Company Phone:
namespace CompanyA {
public class Phone {
public void Dial() {
Console.WriteLine("Phone.Dial");
//
}
}
}
, CompanyB ,
BetterPhone, Phone :
namespace CompanyB {
public class BetterPhone : CompanyA.Phone {
public void Dial() {
Console.WriteLine("BetterPhone.Dial");
EstablishConnection();
206
6.
base.Dial();
CompanyB C# :
warning CS0108: 'CompanyB.BetterPhone.Dial()' hides inherited member
'CompanyA.Phone.Dial()'. Use the new keyword if hiding
was intended.
CompanyB
BetterPhone :
public sealed class Program {
public static void Main() {
CompanyB.BetterPhone phone = new CompanyB.BetterPhone();
phone.Dial();
}
}
207
:
BetterPhone.Dial
BetterPhone.EstablishConnection
Phone.Dial
, , CompanyB. Dial
, BetterPhone.
EstablishConnection, Dial
Phone.
, Phone,
Company. ,
Dial.
Company Phone:
namespace CompanyA {
public class Phone {
public void Dial() {
Console.WriteLine("Phone.Dial");
EstablishConnection();
//
}
protected virtual void EstablishConnection() {
Console.WriteLine("Phone.EstablishConnection");
//
}
}
}
CompanyB
BetterPhone ( Phone)
:
warning CS0114: 'BetterPhone.EstablishConnection()' hides inherited member
'Phone.EstablishConnection()'. To make the current member override
that implementation, add the override keyword. Otherwise,
add the new keyword
, 'BetterPhone. EstablishConnection()'
'Phone.EstablishConnection()',
, override;
new.
, Phone, BetterPhone EstablishConnection,
. BetterPhone
, , , Phone.
208
6.
CompanyB , EstablishConnection
, ,
Dial EstablishConnection, BetterPhone,
Phone.
CompanyB 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");
//
}
}
}
209
( ++),
BetterPhone Dial
EstablishConnection. , ,
.
, .
,
, Dial EstablishConnection,
, .
: CompanyB, Company
Phone, , Dial EstablishConnection
Phone , . CompanyB
Dial BetterPhone. CompanyB
, EstablishConnection BetterPhone
Phone,
new. ,
EstablishConnection BetterPhone.
, CompanyB 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
, Main Dial, ,
Phone BetterPhone. ,
Dial , Phone ,
EstablishConnection , BetterPhone,
EstablishConnection,
Phone.
7.
, , . ,
.
(constant) , . , ,
.
. , ,
. C#
: Boolean, Char,
Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal
String. C# , , null:
using System;
public sealed class SomeType {
// , #
// null
public const SomeType Empty = null;
}
,
. , , .
.
, , ,
IL-.
, . ,
. , ,
, ,
( MaxInt16
32767). , .
DLL-:
211
using System;
public sealed class SomeLibraryType {
// : C#
// static, ,
//
public const Int32 MaxEntriesInList = 50;
}
:
using System;
public sealed class Program {
public static void Main() {
Console.WriteLine("Max entries supported in list: "
+ SomeLibraryType.MaxEntriesInList);
}
}
MaxEntriesInList . , ,
MaxEntriesInList 50, 50
Int32 IL- . -
DLL- ,
.
.method public hidebysig static void Main() cil managed
{
.entrypoint
// Code size 25 (0x19)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Max entries supported in list: "
IL_0006: ldc.i4.s 50
IL_0008: box [mscorlib]System.Int32
IL_000d: call string [mscorlib]System.String::Concat(object, object)
IL_0012: call void [mscorlib]System.Console::WriteLine(string)
IL_0017: nop
IL_0018: ret
} // Program::Main
. MaxEntriesInList
1000 DLL-, . ,
.
( ),
, .
,
.
212
7.
(field) ,
. .7.1 ,
.
7.1.
CLR
C#
Static
static
Instance
( )
InitOnly
readonly
Volatile
volatile
, ,
, CLR . (volatile)
: , Single, Boolean, Byte, SByte, Int16, UInt16,
Int32, UInt32, Char, ,
Byte, SByte, Int16, UInt16, Int32
UInt32. 2
, (CLR)
(), ().
,
(.22),
JIT- , .
.
,
. ,
. ,
,
(
).
CLR , (),
, ().
. ,
.
( ). ,
213
, , ,
. ,
.
, .
DLL-:
using System;
public sealed class SomeLibraryType {
// static ,
// ,
public static readonly Int32 MaxEntriesInList = 50;
}
, ,
, ,
. Main CLR DLL- ( )
MaxEntriesInList ,
. , 50.
, 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) {
//
// ,
//
214
7.
this.Pathname = pathname;
(inline). C# ,
. 8, C# ,
.
, C# ,
,
. 8.
,
, , , :
public sealed class {
// InvalidChars
public static readonly Char[] InvalidChars = new Char[] { '', '', 'C'};
}
public sealed class AnotherType {
public static void M() {
// ,
// InvalidChars
.InvalidChars[0] = 'X';
.InvalidChars[1] = 'Y';
.InvalidChars[2] = 'Z';
// ,
// InvalidChars
.InvalidChars = new Char[] { 'X', 'Y', 'Z' };
}
}
8.
,
, , . , ,
- ( ),
( ). ,
, ,
.
( )
, . , ,
- .ctor ( constructor).
( -
), ,
.
. , , 0 null.
.
, ,
. , virtual, new, override, sealed abstract.
, (
C#) ( ), .
, :
public class SomeType { }
:
public class SomeType {
public SomeType() : base() { }
}
216
8.
protected,
(public). ,
,
. ( )
.
,
.
- .
, C#,
, , , .
System.Object
.
, System.Object
, .
. , MemberwiseClone Object
, , , . ,
. ,
GetUninitializedObject GetSafeUninitializedObject System.Runtime.
Serialization.FormatterServices (.24).
- ,
. :
, , ,
.
.
C# ,
:
internal sealed class SomeType {
private Int32 m_x = 5;
}
SomeType m_x 5.
: ? IL- -
( .ctor), :
( )
217
, SomeType ,
m_x 5 . , -
C# ,
. , . ,
, :
internal sealed class SomeType {
private Int32 m_x = 5;
private String m_s = "Hi there";
private Double m_d = 3.14159;
private Byte m_b;
//
public
public
public
}
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,
, .
, , . ,
, ,
.
.
218
8.
( )
219
( )
(struct) , (class).
CLR
. , ,
. ( C#) , .
:
internal
public
}
internal
public
}
struct Point {
Int32 m_x, m_y;
sealed class Rectangle {
Point m_topLeft, m_bottomRight;
Rectangle , new
. ,
C#. , Rectangle,
Point. CLR
, . ,
, /null.
, 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);
}
}
220
8.
. Rectangle
m_topLeft m_bottomRight new Point,
m_x m_y Point 0.
Point , ,
. :
internal struct Point {
public Int32 m_x, m_y;
public Point() {
m_x = m_y = 5;
}
public Rectangle() {
}
, 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# ( CS0568:
):
error CS0568: Structs cannot contain explicit parameterless constructors
C# , ,
. ,
( )
221
, .
/null.
0 null,
. , ,
, 0 null, .
, ,
, .
, - , . C# ,
, , , ,
.
.
, , .
C#
, CLR.
, (, IL)
.
C# ,
: ( CS0573: 'SomeValType.m_x':
):
error CS0573: 'SomeValType.m_x': cannot have instance field initializers in structs
, :
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;
222
8.
// : m_y
}
}
C# :
( CS0171: 'SomeValType.m_y'
):
error CS0171: Field 'SomeValType.m_y' must be fully assigned before control leaves
the constructor
, y -
(0).
, :
// C#
public SomeValType(Int32 x) {
// , ,
// 0 null
this = new SomeValType();
m_x = x; // m_x x
// , m_y
}
this
,
.
this .
, CLR ( , ). ( C#
), . ,
,
. .
; ,
.
C#:
internal sealed class SomeRefType {
static SomeRefType() {
// SomeRefType
}
223
}
internal struct SomeValType {
// C#
//
static SomeValType() {
// SomeValType
}
}
, , ,
. , (C#
).
( - ), C#
: ( CS0515: 'SomeValType.Some-ValType()':
):
error CS0515: 'SomeValType.SomeValType()': access modifiers are not allowed on
static constructors
,
, , CLR
.
,
, CLR .
:
internal struct SomeValType {
static SomeValTypeQ {
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- ,
. , JIT-
224
8.
IL- . , JIT- , ,
.
, JIT- , , .
, . CLR
,
.
. ,
, , .
.
,
. ,
. , -
CLR , ,
.
CLR ,
, ,
- (singleton), .
,
, . , ClassA , ClassB,
, ClassA. CLR ,
,
ClassA
ClassB. . ,
CLR, ,
.
, , CLR
.
System.TypeInitializationException.
;
, .
, C# :
internal sealed class SomeType {
private static Int32 s_x = 5;
}
225
C#
, . ,
class struct, , .
SomeType. , ,
:
internal sealed class SomeType {
private static Int32 s_x;
static SomeType() { s_x = 5; }
}
ILDasm.exe ,
. IL- .
, , - .cctor ( class constructor).
IL- , .cctor
. ,
s_x 5.
.method private hidebysig specialname rtspecialname static
void .cctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldc.i4.5
IL_0001: stsfld int32 SomeType::s_x
IL_0006: ret
} // end of method SomeType::.cctor
.
,
.
, Java, ,
, . , , , .
CLR ,
RunClassConstructor,
System.Runtime.CompilerServices.RuntimeHelpers. , ,
, .
RunClassConstructor CLR ,
, , .
226
8.
:
internal sealed class SomeType {
private static Int32 s_x = 5;
static SomeTypeQ {
s_x = 10;
}
C# - ,
s_x 5, 10.
, IL- C#
, ,
, - .
:
? -, ,
. , , ,
, .
,
Finalize, . , CLR
Finalize. : ,
DomainUnload System.AppDomain.
,
. , (, System.String, System.
Decimal System.DateTime) (==)
(!=). CLR
, . ,
, , .
, C# +, , .
+ , C# ,
. C# !=, Visual Basic <>. , ^ C#
(XOR), Visual Basic .
CLR , , ,
227
.
, , ,
. CLR
.
, ,
. CLR , .
C# ( ) , ,
, , . ,
C#
.
, C#:
public sealed class Complex {
public static Complex operator+(Complex c1, Complex c2) { ... }
}
op_Addition specialname, ,
. ( C#)
+, . , op_Addition
specialname, .
, , ,
.
. 8.1 8.2 , C#
,
, . .
8.1. # CLS- .
C#
CLS-
op_UnaryPlus
Plus
op_UnaryNegation
Negate
op_LogicalNot
Not
op_OnesComplement
OnesComplement
228
8.
8.1 ()
C#
CLS-
++
op_Increment
Increment
--
op_Decrement
Decrement
op_True
IsTrue { get; }
op_False
IsFalse { get; }
8.2. 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
Equals
<
op_LessThan
Compare
>
op_GreaterThan
Compare
<=
op_LessThanOrEqual
Compare
>=
op_GreaterThanOrEqual
Compare
CLR , , C# . ,
. ECMA (www.ecma-international.org/
publications/standards/Ecma-335.htm) CLI,
10.3.1 ( ) 10.3.2 ( ).
229
,
. ; , , , , +
( ),
. , , op_
(, op_Addition) .
, +
, op_Addition.
, C# op_Addition, +,
. +, C# op_Addition
specialname, , op_Addition
. op_Addition
, , specialname ,
C# . ,
op_Addition, +
.
Microsoft,
, , , , . ,
,
specialname, ,
,
. , ,
,
230
8.
op_. , Microsoft
, ,
Microsoft .
Microsoft
, . , op_Addition op_AdditionAssignment
Add.
.8.1 8.2. , 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 ,
( ).
231
. , System.Xml.Linq.
XElement XML Boolean, (U)Int32, (U)Int64,
Single, Double, Decimal, String, DateTime, DateTimeOffset, TimeSpan, Guid
, null ( String).
, FCL Rational,
Int32 Single. ,
Rational Int32
Single.
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
:
232
8.
,
. 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
}
}
233
.
C# ( )
IL-,
, Rational.
? , Rational
. ,
. , Rational, :
public
public
public
public
static
static
static
static
, , , 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- .
234
8.
,
. , .
,
, .
# ,
. , as is.
- , System.
Decimal . Decimal , Decimal . ToXxx Decimal
. ,
.
.
14 , StringBuilder
, String, ,
StringBuilder ,
. ,
StringBuilder . ,
IndexOf:
public static class StringBuilderExtensions {
public static Int32 IndexOf(StringBuilder sb, Char value) {
for (Int32 index = 0; index < sb.Length; index++)
if (sb[index] == value) return index;
return -1;
}
}
, :
//
StringBuilder sb = new StringBuilder("Hello. My name is Jeff.");
//
// (5)
Int32 index = StringBuilderExtensions.IndexOf(sb.Replace('.', '!'), '!');
235
, . -, , StringBuilder,
StringBuilderExtensions. -,
,
StringBuilder, , .
Replace,
IndexOf, ,
IndexOf, Replace.
, :
//
sb.Replace('.', '!');
// (5)
Int32 index = StringBuilderExtensions.IndexOf(sb, '!');
,
. StringBuilderExtensions
: IndexOf. StringBuilder
IndexOf,
:
//
// (5)
Int32 index = sb.Replace('.', '!').IndexOf('!');
!
StringBuilder ,
.
, .
,
. , IndexOf , , .
IndexOf ,
this :
public static class StringBuilderExtensions {
public static Int32 IndexOf(this StringBuilder sb, Char value) {
for (Int32 index = 0; index < sb.Length; index++)
if (sb[index] == value) return index;
return -1;
}
}
:
Int32 index = sb.IndexOf('X');
StringBuilder , IndexOf
236
8.
Char. ,
IndexOf,
, .
this. sb
StringBuilder. IndexOf : StringBuilder ( this) Char.
IndexOf IL- .
, , . ,
, ,
IndexOf StringBuilder?
Microsoft Visual Studio IntelliSense. ,
, IntelliSense- .
, IntelliSense- , , . IntelliSense-
.8.1. , ,
,
. ,
,
.
237
, .
# ,
, , ..
( this )
.
, . ,
, , ,
this.
C# ,
, . ,
, ,
C# ( CS1109:
, StringBuilderExtensions
):
error CS1109: Extension method must be defined in a top-level static
class; StringBuilderExtensions is a nested class
,
# - , ; ,
, .
,
, C# .
, - StringBuilderExtensions Wintellect, ,
,
using Wintellect.
. ,
,
( CS0121:
'StringBuilderExtensions.IndexOf(string, char)' 'AnotherStringBuild
erExtensions.IndexOf(string, char)):
error CS0121: The call is ambiguous between the following methods
or properties: 'StringBuilderExtensions.IndexOf(string, char)'
and 'AnotherStringBuilderExtensions.IndexOf(string, char)'.
, .
238
8.
,
, , .
,
. , ,
. , ,
System.Object, ,
IntelliSense.
.
Microsoft IndexOf StringBuilder
, , , IndexOf
Microsoft IndexOf. -
-. ,
.
,
StringBuilder. ,
, CLR
, ( null).
// sb null
StringBuilder sb = null;
// : NullReferenceException
// IndexOf
// NullReferenceException IndexOf
sb.IndexOf('X');
// : NullReferenceException
// Replace
sb.Replace('.', '!');
,
, :
public static void ShowItems<T>(this IEnumerable<T> collection) {
foreach (var item in collection)
Console.WriteLine(item);
}
, , IEnumerable<T>:
239
-, :
public static void InvokeAndCatch<TException>(this Action<Object> d, Object o)
where TException : Exception {
try { d(o); }
catch (TException) { }
}
:
Action<Object> action = o => Console.WriteLine(o.GetType());
// NullReferenceException
action.InvokeAndCatch<NullReferenceException>(null);
// NullReferenceException
, ( .15).
, # ,
(.17):
public static void Main () {
// C Action,
// ShowItems; "Jeff"
Action a = "Jeff".ShowItems;
.
.
.
// , ShowItems
// "Jeff"
a();
}
240
8.
# IL- ,
Action.
, ,
. ,
, , null, .
C# , ,
ShowItems,
"Jeff". , , CLR
"Jeff". - , , ,
.
, ,
#. ,
, , .
,
.
, .
#,
this, ,
.
System.Core.dll :
// System.Runtime.CompilerServices
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class
| AttributeTargets.
Assembly)]
public sealed class ExtensionAttribute : Attribute {
}
,
, , . , ,
, ,
.
, ,
, .
241
, , C# . ,
, .
, .
, , . ,
, ,
, . :
// :
internal class Base {
private String m_name;
// m_name
protected virtual void OnNameChanging(String value) {
}
public String Name {
get { return m_name; }
set {
//
OnNameChanging(value.ToUpper());
m_name = value; //
}
}
}
//
internal class Derived : Base {
protected override void OnNameChanging(string value) {
if (String.IsNullOrEmpty(value))
throw new ArgumentNullException("value");
}
}
242
8.
, .
(sealed) .
( ).
, .
. , , . OnNameChanging,
- ,
. ToUpper , OnNameChanging , ,
.
C#. ,
, :
//
internal sealed partial class Base {
private String m_name;
//
// m_name
partial void OnNameChanging(String value);
public String Name {
get { return m_name; }
set {
//
OnNameChanging(value.ToUpper());
m_name = value; //
}
}
}
// ,
internal sealed partial class Base {
// ,
// m_name
partial void OnNameChanging(String value) {
if (String.IsNullOrEmpty(value))
throw new ArgumentNullException("value");
}
}
, .
( ). ,
.
243
, , , ,
, ( .6).
, ,
. partial .
, , .
partial .
, , . ,
,
- .
, ,
.
. ,
, , . , IL- ,
:
// ,
//
internal sealed class Base {
private String m_name;
public String Name {
get { return m_name; }
set {
m_name = value; //
}
}
}
, . IL- ,
, , .
244
8.
ToUpper.
IL-
!
System.Diagnostics.
ConditionalAttribute. ,
ConditionalAttribute ,
.
, .
.
void
, out.
, ,
, ,
. ,
out, , . ,
ref, , , , unsafe.
,
. , ,
. , ,
.
,
, .
, .
( CS0762:
'Base.OnNameChanging(string)',
):
"error CS0762: Cannot create delegate from method
'Base.OnNameChanging(string)' because it is a partial method
without an implementing declaration
, C#
private .
9.
.
, ,
. ,
.
1
( )
.
, . ,
,
. , :
public static class Program {
private static Int32 s_n = 0;
private static void M(Int32 x = 9, String s = "A",
DateTime dt = default(DateTime), Guidguid = new Guid()) {
Console.WriteLine("x={0}, s={1}, dt={2}, guid={3}", x, s, dt, guid);
}
public static void Main() {
// 1. : M(9, "A", default(DateTime), new Guid());
M();
// 2. : M(8, "X", default(DateTime), new Guid());
M(8, "X");
// 3. : M(5, "A", DateTime.Now, Guid.NewGuid());
M(5, guid: Guid.NewGuid(), dt: DateTime.Now);
// 4. : M(0, "1", default(DateTime), new Guid());
M(s_n++, s_n++.ToString());
// 5. : String t1 = "2"; Int32 t2 = 3;
// M(t2, t1, default(DateTime), new Guid());
M(s: (s_n++).ToString(), x: s_n++);
}
}
:
x=9, s=A, dt=1/1/0001 12:00:00 AM, guid=00000000-0000-0000-0000-000000000000
x=8, s=X, dt=1/1/0001 12:00:00 AM, guid=00000000-0000-0000-0000-000000000000
msdn.microsoft.com , .
. . .
1
246
9.
, ,
, .
M (named parameter). x , guid dt.
.
M s_n (0) x,
s_n s_n (1)
s. s_n 2.
.
M s_n (2) (t1). s_n 3,
(t2). s_n 4. ,
M, t2, t1, DateTime
Guid.
, ,
:
,
(C#). , . ,
.
. , ,
,
. , M
("A") s, .
,
params ( ). ,
. .
.
, .5.1 5. , null.
, .
default, new, -
247
IL-.
M dt
guid .
,
,
. , M dt dateTime, ( CS1739:
'M' 'dt'):
"error CS1739: The best overload for 'M' does not have a parameter
named 'dt'
.
.
, , .
0 null.
. :
// :
private static String MakePath(String filename = "Untitled") {
return String.Format(@"C:\{0}.txt", filename);
}
// :
private static String MakePath(String filename = null) {
// ,
// null (??); . 19
return String.Format(@"C:\{0}.txt", filename ?? "Untitled");
}
, ref out,
.
:
; .
,
, ,
(c ).
C# . ,
M(1,,DateTime.Now) , . ,
.
,
ref/out:
248
9.
// :
private static void M(ref Int32 x) { ... }
// :
Int32 a = 5;
M(x: ref a);
C#
, COM Microsoft Office.
COM- C# ref/out
. .
COM- ,
ref/out .
DefaultParameterValue
, C#. ,
, ,
,
. ,
,
.
C#
System.Runtime.InteropServices.OptionalAttribute,
. ,
System.Runtime.InteropServices.DefaultParameterValueAttribute,
.
DefaultParameterValueAttribute ,
.
, , ,
, ,
.
C# :
249
ImplicitlyTypedLocalVariables var. ,
(=). "Jeff" , name
String. , , ShowVariableType.
. ShowVariableType ImplicitlyTypedLocalVariables.
() ImplicitlyType
dLocalVariables ( CS0815:
null
):
error CS0815: Cannot assign <null> to an implicitly-typed local variable
, null
, null. ,
. ,
null - ,
( String). , ,
, String x = null;, .
250
9.
. Dictionary<String, Single>.
,
,
.
foreach var ,
.
var foreach, using
for. , . ,
,
. .
, ,
! , , ,
,
.
Microsoft Visual Studio
var , . C#
, . 10.
var .
, ,
. , ,
. ,
. C# .
. C#
, ( ) .
, ( 10)
.
251
CLR ,
. (
) . ,
.
, .
, .
, ,
.
CLR , . C#
out ref.
, .
,
.
CLR, out ref ,
IL-, ,
, .
C# , , .
out,
, .
,
. ref,
,
, .
out
ref . :
public sealed class Program {
public static void Main() {
Int32 x; // x
GetVal(out x); // x
Console.WriteLine(x); // 10
}
private static void GetVal(out Int32 v) {
v = 10; // V
}
}
252
9.
x Main, GetVal.
v Int32.
GetVal Int32, v,
10. , GetVal
. 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
}
}
Main x 5. AddVal, v
Int32 Main. AddVal
Int32, v. , AddVal v
. ,
. AddVal
10. , , x
Main 15, .
, IL CLR out
ref : . ,
. , ref, ( CS0165:
x, ):
error CS0165: Use of unassigned local variable 'x'
, :
public sealed class Program {
public static void Main() {
Int32 x; // x
// , :
// error CS0165: Use of unassigned local variable 'x'
AddVal(ref x);
Console.WriteLine(x);
}
private static void AddVal(ref Int32 v) {
253
v += 10; // v
}
}
, C#
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) { ... }
Point C# (
CS0663: 'Add' , ref out):
error CS0663: 'Add' cannot define overloaded methods that differ only
on ref and out
out ref ,
.
.
, .
, .
out ref , .
:
using System;
using System.IO;
public sealed class Program {
public static void Main() {
FileStream fs; // fs
//
254
9.
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. :
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) {
// ,
255
, ref
, :
public static void Swap(ref Object a, ref Object b) {
Object t = b;
b = a;
a = t;
}
, , String, :
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. :
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
. , ,
256
9.
. ,
( , ):
internal sealed class SomeType {
public Int32 m_val;
}
public sealed class Program {
public static void Main() {
SomeType st;
// CS1503: Argument '1':
// cannot convert from 'ref SomeType' to 'ref object'.
GetAnObject(out st);
}
Console.WriteLine(st.m_val);
, Main GetAnObject
SomeType. GetAnObject Object,
GetAnObject o
. st , GetAnObject
Main, String, SomeType. , Console.WriteLine
. , C# , st
SomeType, GetAnObject
Object.
, , . Swap:
public static void Swap<T>(ref T a, ref T b) {
T t = b;
b = a;
a = t;
}
( )
:
public static void SomeMethod() {
String s1 = "Jeffrey";
String s2 = "Richter";
Swap(ref s1, ref s2);
Console.WriteLine(s1); // "Richter"
Console.WriteLine(s2); // "Jeffrey"
}
257
, ,
System.Threading.Interlocked CompareExchange Exchange.
,
. , System.String , , ,
.
, , :
static Int32 Add(params Int32[] values) {
// :
//
Int32 sum = 0;
if (values != null) {
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.
258
9.
, C# , ParamArray.
, , .
ParamArray ,
. ,
, , .
Add, Int32 .
Add, Int32, Add,
Int32 ParamArray.
, Int32 Add. ,
, Add , , Add,
.
params
(ParamArrayAttribute). .
null , . Add , ,
0 ( ):
public static void Main() {
// "0"
Console.WriteLine(Add()); //
Console.WriteLine(Add(null)); //
//
}
//
Int32[0] Add
Add null,
(
)
,
Int32. , ? :
, Int32[] Object[].
Type :
public sealed class Program {
public static void Main() {
DisplayTypes(new Object(), new Random(), "Jeff", 5);
}
259
:
System.Object
System.Random
System.String
System.Int32
, , , , , null.
,
. , ,
params. Concat
System.String, :
public sealed class String : Object,
public static string Concat(object
public static string Concat(object
public static string Concat(object
public static string Concat(params
public
public
public
str3);
public
}
... {
arg0);
arg0, object arg1);
arg0, object arg1, object arg2);
object[] args);
, Concat , params . , , ,
.
params ,
. ,
.
,
, . , ,
, , IEnumerable<T> , List<T>,
ICollection<T> IList<T>:
260
9.
//
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>.
, , .
, . , ,
, , :
//
public void ProcessBytes(Stream someStream) { ... }
//
public void ProcessBytes(FileStream fileStream) { ... }
: FileStream,
NetworkStream, MemoryStream .. FileStream,
.
, ,
(
). , ,
FileStream, Stream:
//
//
public FileStream OpenFile() { ... }
//
//
public Stream OpenFile() { ... }
,
FileStream Stream.
,
Stream, .
, .
OpenFile , -
261
- FileStream ( ,
FileStream). , List<String>, , String[].
.
:
// :
//
public IList<String> GetStringCollection() { ... }
// :
//
public List<String> GetStringCollection() { ... }
GetStringCollection List<String>,
IList<String>.
String[], ,
. , . ,
IEnumerable<String> ICollection<String>.
, C++, .
, . CLR
, .
, ,
( C#).
, C++
const .
,
. C++
, ,
.
, ,
. , ,
String .
, Microsoft CLR . CLR
,
262
9.
, .
, . , .
,
. , , ,
, .
, CLR
/.
10.
. . CLR : , ,
. , C#
, Visual Basic .
,
,
System.Tuple.
,
. . ,
, :
public sealed class Employee {
public String Name; //
public Int32 Age; //
}
,
:
Employee e = new Employee();
e.Name = "Jeffrey Richter"; //
e.Age = 48; //
Console.WriteLine(e.Name); // "Jeffrey Richter"
. , .
-
. ,
,
,
. ,
Employee:
e.Age = -5; // , 5 ?
264
10.
. , , - , - ,
, .
, ,
, .
, -,
(private), -,
, . ,
, (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;
}
}
,
. , ,
.
SetXxx
(protected).
, : -, - , -,
:
e.SetName("Jeffrey Richter"); //
String EmployeeName = e.GetName(); //
e.SetAge(41); //
e.SetAge(-5); //
//
Int32 EmployeeAge = e.GetAge(); //
265
ArgumentOutOfRangeException
. 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) (.13).
( void).
( , ).
266
10.
, : 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;
}
}
267
, get_ set_ , .
C#. ,
, .
,
. ,
.
, ,
,
. ,
get set.
, .
System.Reflection.PropertyInfo. CLR ,
.
, #
,
(Automatically Implemented Properties, AIP). Name:
public sealed class Employee {
//
public String Name { get; set; }
private Int32 m_Age;
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;
}
}
}
set get,
C# .
String . get_Name set_Name
.
, ,
Name? . AIP , . ,
, get set.
, ,
268
10.
, , ,
. Name
, , , , .
,
.
, ,
. AIP .
, .
. AIP ,
, , ,
. ,
.
AIP- set get,
, .
, .
, AIP
, set get.
,
, , ,
. - ,
,
. ,
AIP. AIP .
, Microsoft
.NET Framework .
, , .
. , , ,
, .
,
, . ,
(get set).
269
, , , .
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);
}
}
- ,
. ,
, . ,
(, System.MarshalByRefObject),
- , . , , MarshalByRefObject,
.
-
, . System.DateTime
Now, .
. ,
Microsoft , Now .
Environment.TickCount.
- ,
. ,
, .
-
, , -
270
10.
;
,
. , ,
, .
, ,
. , : ,
, . , ,
.
.NET Framework ,
,
GetXxx SetXxx.
,
, ,
!
Visual Studio
Microsoft Visual Studio
. get .
, .
, FileStream , ,
FileStream.Length .
get,
!
, get - ,
. , get
, .
- Visual Studio
, . ToolsOptions, Options
DebuggingGeneral Enable Property Evaluation And Other Implicit
Function Calls (.10.1). ,
, ,
Value Visual Studio.
271
( ) . C# , :
Employee e = new Employee() { Name = "Jeff", Age = 45 };
,
, ,
. , :
String s = new Employee() { Name = "Jeff", Age = 45 }.ToString().ToUpper();
Employee, ,
, ToString,
272
10.
ToUpper. # -
, .
, :
String s = new Employee { Name = "Jeff", Age = 45 }.ToString().ToUpper();
IEnumerable IEnumerable<T>,
, ( ). ,
:
public sealed class Classroom {
private List<String> m_students = new List<String>();
public List<String> Students { get { return m_students; } }
}
public Classroom() {}
Classroom Stu-
dents:
, Students
List<String> IEnumerable<String>.
, List<String>
Add ( Add
). Add .
:
public static void M() {
Classroom classroom = new Classroom();
classroom.Students.Add("Jeff");
classroom.Students.Add("Kristin");
classroom.Students.Add("Aidan");
classroom.Students.Add("Grant");
// 4 ,
foreach (var student in classroom.Students)
Console.WriteLine(student);
}
273
IEnumerable IEnumerable<T>,
Add,
,
( CS0117: System.Collections.
Generic.IEnumerable<string> Add):
error CS0117: 'System.Collections.Generic.IEnumerable<string>' does not
contain adefinition for 'Add'
Add . ,
Add Dictionary:
public void Add(TKey key, TValue value);
Add , :
var table = new Dictionary<String, Int32> {
{ "Jeffrey", 1 }, { "Kristin", 2 }, { "Aidan", 3 }, { "Grant", 4 }
};
:
var table = new Dictionary<String, Int32>();
table.Add("Jeffrey", 1);
table.Add("Kristin", 2);
table.Add("Aidan", 3);
table.Add("Grant", 4);
#
. (tuple type)1 ,
, - .
(Name String Year Int32),
Name Jeff, Year 1964.
// ,
var o1 = new { Name = "Jeff", Year = 1964 };
//
Console.WriteLine("Name={0}, Year={1}", o1.Name, o1.Year); // :
// Name=Jeff, Year=1964
,
new, , , tuple : single, double, triple,
quadruple, quintuple, n-tuple.
1
274
10.
( ).
. , , , ,
o1.
, 9,
(=).
, , .
:
var o = new { property1 = expression1, ..., propertyN = expressionN };
, ,
, .
. ,
Equals, GetHashCode ToString
. , , :
[CompilerGenerated]
internal sealed class <>f__AnonymousType0<...>: Object {
private readonly t1 f1;
public t1 p1 { get { return f1; } }
...
private readonly tn fn;
public tn pn { get { return fn; } }
public <>f__AnonymousType0<...>(t1 a1, ..., tn an) {
f1 = a1; ...; fn = an; //
}
public override Boolean Equals(Object value) {
// false, - ;
// true
}
public override Int32 GetHashCode() {
// -, -
}
public override String ToString() {
// "name = value",
}
}
Equals GetHashCode, -. ,
275
, - .
- , -, . ToString
. Visual Studio
, , Visual Studio
ToString . ,
IntelliSense- Visual Studio .
,
:
String Name = "Grant";
DateTime dt = DateTime.Now;
//
// 1. Name Grant
// 2. Year Int32 Year dt
var o2 = new { Name, dt.Year };
, Name. Name ,
,
String. /:
Year. Year DateTime Int32, ,
Year Int32.
, Name , Name, Name
Grant. Year ,
dt Year.
. ,
,
. ,
. o1
o2 ,
Name/String Year/Int32, Name Year.
, , , ,
:
//
Console.WriteLine("Objects are equal: " + o1.Equals(o2));
o1 = o2; //
276
10.
,
( .16):
// ,
var people = new[] {
o1, // .
new { Name = "Kristin", Year = 1970 },
new { Name = "Aidan", Year = 2003 },
new { Name = "Grant", Year = 2008 }
};
//
// ( var ).
foreach (var person in people)
Console.WriteLine("Person={0}, Year={1}", person.Name, person.Year);
(Language Integrated Query, LINQ), , ,
.
. ,
:
String myDocuments =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var query =
from pathname in Directory.GetFiles(myDocuments)
let LastWriteTime = File.GetLastWriteTime(pathname)
where LastWriteTime > (DateTime.Now - TimeSpan.FromDays(7))
orderby LastWriteTime
select new { Path = pathname, LastWriteTime };
foreach (var file in query)
Console.WriteLine("LastWriteTime={0}, Path={1}",
file.LastWriteTime, file.Path);
. ,
.
. Object ( Object),
Object ,
.
System.Tuple,
.
System.Tuple
System
( Object), . .
277
// :
[Serializable]
public class Tuple<T1> {
private T1 m_Item1;
public Tuple(T1 item1) { m_Item1 = item1; }
public T1 Item1 { get { return m_Item1; } }
}
// :
[Serializable]
public class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> {
private T1 m_Item1; private T2 m_Item2;
private T3 m_Item3; private T4 m_Item4;
private T5 m_Item5; private T6 m_Item6;
private T7 m_Item7; private TRestm_Rest;
public Tuple(T1 item1, T2 item2, T3 item3,
T4 item4, T5 item5, T6 item6, T7 item7, TRest t) {
m_Item1 = item1; m_Item2 = item2; m_Item3 = item3; m_Item4 = item4;
m_Item5 = item5; m_Item6 = item6; m_Item7 = item7; m_Rest = rest;
}
public
public
public
public
public
public
public
public
T1 Item1 {
T2 Item2 {
T3 Item3 {
T4 Item4 {
T5 Item5 {
T6 Item6 {
T7 Item7 {
TRest Rest
get {
get {
get {
get {
get {
get {
get {
{ get
return m_Item1; } }
return m_Item2; } }
return m_Item3; } }
return m_Item4; } }
return m_Item5; } }
return m_Item6; } }
return m_Item7; } }
{ return m_Rest; } }
, Tuple
( ). , Tuple
CompareTo, Equals, GetHashCode ToString, Size.
Tuple IStructuralEquatable, IStructuralComparable
IComparable, Tuple , .
SDK.
, Tuple
.
// Item1 Item2
private static Tuple<Int32, Int32>MinMax(Int32 a, Int32 b) {
return new Tuple<Int32, Int32>(Math.Min(a, b), Math.Max(a, b));
}
// Tuple
private static void TupleTypes() {
varminmax = MinMax(6, 2);
278
10.
Console.WriteLine("Min={0}, Max={1}",
minmax.Item1, minmax.Item2); // Min=2, Max=6
}
, , , Tuple
, Item#.
, . Tuple
, . , , .
,
, , / .
, , . System Tuple
Create,
.
Tuple .
Tuple MinMax:
// Item1 Item2
private static Tuple<Int32, Int32>MinMax(Int32 a, Int32 b) {
return Tuple.Create(Math.Min(a, b), Math.Max(a, b)); //
//
}
Tuple , ,
Tuple Rest:
var t = Tuple.Create(0, 1, 2, 3, 4, 5, 6, Tuple.Create(7, 8));
Console.WriteLine("{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}",
t.Item1, t.Item2, t.Item3, t.Item4, t.Item5, t.Item6, t.Item7,
t.Rest.Item1.Item1, t.Rest.Item1.Item2);
, System.Dynamic.
ExpandoObject ( System.Core.dll assembly). C# ( 5)
( -) . ,
( IntelliSense),
ExpandoObject C# ,
Python. ExpandoObject:
dynamic e = new System.Dynamic.ExpandoObject();
e.x = 6; // 'x' Int32
// 6
279
, , get . (parameterless
properties). , .
,
, (parameterful 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 must be > 0");
//
m_numBits = numBits;
//
280
10.
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))
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"));
}
281
. System.Collections.Generic.Dictionary ,
.
,
, .
set , set ( C# value),
.
CLR .
, . , . C# this[...]
, , , C#
. C# , - ,
CLR .
CLR ,
:
get ,
get;
set ,
set;
;
: CLR .
BitArray ,
:
public sealed class BitArray {
// get
public Boolean get_Item(Int32 bitPos) { /* ... */ }
// set
public void set_Item(Int32 bitPos, Boolean value) { /* ... */ }
}
,
get_ set_. C#
, C#
, Item.
get_Item set_Item.
282
10.
get_Item set_Item
get_Bit set_Bit. C#
IndexerName , ,
; 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# ,
IndexerNameAttribute ECMA
CLI C#.
1
283
, , .
C#
( CS0111: SomeType this
):
error CS0111: Class 'SomeType' already defines a member called 'this' with the same
parameter types
, :
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# [],
.
, System.String, String Chars, Item.
. ,
, []
, Chars .
, C#
.
.
,
. CLR ,
System.Reflection.PropertyInfo.
, C# ,
:
284
10.
, ,
?
C#?
: ,
System.Reflection.DefaultMemberAttribute. , DefaultMemberAttribute
, . #
, , DefaultMember
IndexerName.
, ,
.
, C# , ,
IndexerName, DefaultMember, ,
Item.
IndexerName, DefaultMember
, IndexerName. : C#
, .
, ,
DefaultMember.
, C#.
285
get set
. get set:
public class SomeType {
private String m_name;
public String Name {
get { return m_name; }
protected set {m_name = value; }
}
}
, C# CLR ,
- ( ). C# .
, .
, , . ,
/ ,
. -
( ) , .
11.
,
, . , ( ), ,
. , Button ()
Click (), ,
Button, . ,
. ,
:
;
;
.
,
.
, .
CLR (delegate). , .
(callback methods) , .
, 17.
CLR, , . ,
. ,
. ,
MailManager, . MailManager NewMail.
(, Fax Pager)
. MailManager ,
, . ,
.
MailManager Fax Pager. .11.1 , .
287
. 11.1. ,
MailManager,
NewMail. Fax Pager NewMail (
) MailManager, MailManager ,
.
MailManager , NewMail,
.
, ,
. .
MailManager ( Books http://wintellect.com) MailManager, Fax Pager. ,
Fax Pager .
288
11.
1.
,
, , - .
,
( ) . , ,
, ,
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;
}
, . ,
.
. , Button
, . , ,
Event-Args,
EventArgs.Empty.
289
2. -
C# event. -
( ,
), , (
), ( ). NewMail:
internal class MailManager {
// 2. -
public event EventHandler<NewMailEventArgs> NewMail;
...
}
:
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.
290
11.
: ,
, EventArgs, e. : , .
(, Microsoft Visual Studio) ,
e.
: , void.
,
. void
. , FCL ,
ResolveEventHandler, Microsoft Assembly.
3. ,
, .
, MailMsgEventArgs, .
, ,
,
.
MailManager:
internal class MailManager {
...
// 3. ,
//
// ,
//
protected virtual void OnNewMail(NewMailEventArgs e) {
//
//
EventHandler<NewMailEventArgs> temp = Volatile.Read (ref NewMail);
// ,
// ,
if (temp != null) temp(this, e);
}
...
}
291
,
.NET Framework :
// 1
protected virtual void OnNewMail(NewMailEventArgs e) {
if (NewMail != null) NewMail(this, e);
}
, NewMail
temp , . temp null temp,
, NewMail temp. ,
, .
,
, temp.
, -
NullReferenceException.
OnNewMail :
// 3
protected void OnNewMail(NewMailEventArgs e) {
EventHandler<NewMailEventArgs> temp = Thread.VolatileRead(ref NewMail);
if (temp != null) temp(this, e);
}
VolatileRead NewMail
temp. temp , null.
Volatile.Read 28.
, 2 JIT-,
, .
JIT- Microsoft
, ,
, .
,
292
11.
. Microsoft JIT-
, 1. , ( Windows
Presentation Foundation Windows Store),
.
(.8), , .
:
public static class EventArgExtensions {
public static void Raise<TEventArgs>(this TEventArgs e,
Object sender, ref EventHandler<TEventArgs> eventDelegate) {
//
//
EventHandler<TEventArgs> temp = Volatile.Read(ref eventDelegate);
// ,
if (temp != null) temp(sender, e);
}
}
OnNewMail :
protected virtual void OnNewMail(NewMailEventArgs e) {
e.Raise(this, ref m_NewMail);
}
, MailManager ,
OnNewMail, -
. ,
. OnNewMail ,
.
.
4. ,
, . MailManager SimulateNewMail
MailManager:
internal class MailManager {
// 4. ,
JIT-.
293
//
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 )
//
public void add_NewMail(EventHandler<NewMailEventArgs> value) {
// CompareExchange
// ,
EventHandler<NewMailEventArgs>prevHandler;
EventHandler<NewMailEventArgs> newMail = this.NewMail;
do {
prevHandler = newMail;
EventHandler<NewMailEventArgs> newHandler =
(EventHandler<NewMailEventArgs>) Delegate.Combine(prevHandler, value);
newMail = Interlocked.CompareExchange<EventHandler<NewMailEventArgs>>(
ref this.NewMail, newHandler, prevHandler);
294
11.
// 3. remove_Xxx ( Xxx )
//
// c
public void remove_NewMail(EventHandler<NewMailEventArgs> value) {
// CompareExchange
// ,
EventHandler<NewMailEventArgs> prevHandler;
EventHandler<NewMailEventArgs> newMail = this.NewMail;
do {
prevHandler = newMail;
EventHandler<NewMailEventArgs> newHandler =
(EventHandler<NewMailEventArgs>) Delegate.Remove(prevHandler, value);
newMail = Interlocked.CompareExchange<EventHandler<NewMailEventArgs>>(
ref this.NewMail, newHandler, prevHandler);
} while (newMail != prevHandler);
}
. , . null; ,
, .
,
EventHandler<NewMailEventArgs>, , , EventHandler<NewMailEventArgs>. ,
. ,
.
: (NewMail ) ,
.
,
. , , , .
, C#, ,
. C# ,
add_ (NewMail). C#
, Combine
System.Delegate. Combine
, .
, C#, ,
. C# , remove_
(NewMail). Remove System.Delegate.
295
,
.
, , Delegate.Remove
. , ,
.
add remove
, .
28.
add remove ,
. , add remove,
, .
, ,
, . ;
add remove
.
,
.
-, add remove. ,
.
, , ,
System.Reflection.EventInfo.
CLR
.
,
. , , , .
Fax:
internal sealed class Fax {
// MailManager
296
11.
MailManager
. Fax,
MailManager . Fax Fax
NewMail MailManager +=
C#:
mm.NewMail += FaxMsg;
, C# += , :
mm.add_NewMail(new EventHandler<NewMailEventArgs>(this.FaxMsg));
, C# ,
EventHandler<NewMailEventArgs>, FaxMsg
Fax. C# add_NewMail MailManager, -
. , ,
IL- , ILDasm.exe.
297
, , , add.
, .
add ,
.
MailManager, FaxMsg Fax. sender
MailManager. , , Fax
MailManager.
NewMailEventArgs. , , NewMailEventArgs, .
NewMailEventArgs FaxMsg
,
. Fax , .
,
. , Fax
NewMail,
. ,
. Dispose IDisposable,
( IDisposable
. 21).
, ,
Unregister Fax.
Fax. , +=
=. , =,
C# remove :
mm.remove_NewMail(new EventHandler<NewMailEventArgs>(FaxMsg));
+=, , ,
remove,
- , .
, . ,
, .
, C# , += =.
add remove, C#
(CS0571: ):
CS0571: cannot explicitly call operator or accessor
298
11.
System.Windows.Forms.Control 70 .
Control ,
add remove -, Control
70- !
, ,
Control ,
. , System.Web.UI.Control ( ASP.NET) System.Windows.
UIElement ( Windows Presentation Foundation, WPF)
, .
, C#
, , add remove
. , .
,
.
,
, ( ),
, . .
. ,
.
, .
.
, ,
. ,
, . ,
, . , ,
.
.
EventSet, :
using System;
using System.Collections.Generic;
using System.Threading;
//
// EventSet
public sealed class EventKey : Object { }
public sealed class EventSet {
// EventKey -> Delegate
private readonly Dictionary<EventKey, Delegate> m_events =
newDictionary<EventKey, Delegate>();
// EventKey -> Delegate,
// EventKey
public void Add(EventKey eventKey, Delegate handler) {
Monitor.Enter(m_events);
Delegate d;
m_events.TryGetValue(eventKey, out d);
m_events[eventKey] = Delegate.Combine(d, handler);
Monitor.Exit(m_events);
}
// EventKey ( )
// EventKey -> Delegate
//
public void Remove(EventKey eventKey, Delegate handler) {
Monitor.Enter(m_events);
// TryGetValue
// EventKey.
Delegate d;
if (m_events.TryGetValue(eventKey, out d)) {
d = Delegate.Remove(d, handler);
// , EventKey,
// EventKey
if (d != null) m_events[eventKey] = d;
else m_events.Remove(eventKey);
}
Monitor.Exit(m_events);
}
// EventKey
public void Raise(EventKey eventKey, Object sender, EventArgs e) {
// EventKey
Delegate d;
Monitor.Enter(m_events);
m_events.TryGetValue(eventKey, out d);
Monitor.Exit(m_events);
if (d != null) {
// -
// , ,
// , .
// DynamicInvoke System.Delegate,
// . DynamicInvoke
//
// . ,
// .
d.DynamicInvoke(newObject[] { sender, e });
}
}
299
300
11.
, EventSet.
, EventSet,
, add EventSet, remove
( ).
using System;
// , EventArgs
public class FooEventArgs : EventArgs { }
public class TypeWithLotsOfEvents {
// , .
// "Event/Delegate"
// : EventSet FCL,
//
private readonly EventSet m_eventSet = newEventSet();
//
protected EventSet EventSet { get { return m_eventSet; } }
#region Code to support the Foo event (repeat this pattern for additional events)
// , Foo.
// 2a. ,
// .
// -
// .
protected static readonly EventKey s_fooEventKey = newEventKey();
// 2b.
// .
public event EventHandler<FooEventArgs> Foo {
add { m_eventSet.Add(s_fooEventKey, value); }
remove { m_eventSet.Remove(s_fooEventKey, value); }
}
// 2c. On .
protected virtual void OnFoo(FooEventArgs e) {
m_eventSet.Raise(s_fooEventKey, this, e);
}
// 2d. ,
public void SimulateFoo() {OnFoo(newFooEventArgs());}
#endregion
}
, TypeWithLotsOfEvents, ,
.
.
:
public sealed class Program {
public static void Main() {
TypeWithLotsOfEvents twle = new TypeWithLotsOfEvents();
//
twle.Foo += HandleFooEvent;
//
twle.SimulateFoo();
}
private static void HandleFooEvent(object sender, FooEventArgs e) {
Console.WriteLine("Handling Foo Event here...");
}
}
301
12.
- .
, .
,
. (generics)
, CLR
.
, , , , , , , ,
, .
, ,
Int32, String .., DateTime, Version ..
. CLR
, , . , CLR
.
, CLR , , .
, FCL
, . . , ,
.
FCL-, , List<T> System.Collections.Generic.
( ):
[Serializable]
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>,
IList, ICollection, IEnumerable {
public
public
public
public
List();
void Add(T item);
Int32 BinarySearch(T item);
void Clear();
public
public
public
public
public
public
public
303
<T> List ,
.
, (, T),
(type parameters). T ,
, .
, List T (
Add T) ( ToArray T) . -
( C# this). get,
T, set, T. T
, ,
.
, List<T> ;
, . -
(type arguments). , List,
DateTime -:
private static void SomeMethod() {
// (List), DateTime
List<DateTime> dtList = new List<DateTime>();
// DateTime
dtList.Add(DateTime.Now); //
// DateTime
304
12.
dtList.Add(DateTime.MinValue); //
// String
dtList.Add("1/1/2004"); //
// DateTime
DateTime dt = dtList[0]; //
}
.
. , ,
( C++
, , ).
.
, CLR ,
, .
.
String Add .
. , ,
. SomeMethod (DateTime), dt ( 0).
.
, Object.
,
CLR . 5,
,
, , ,
.
,
CLR .
(. ), CLR
, .
, ,
ArrayList FCL List. ,
:
using
using
using
using
305
System;
System.Collections;
System.Collections.Generic;
System.Diagnostics;
306
12.
}
//
internal sealed class OperationTimer : IDisposable {
private Int64 m_startTime;
private String m_text;
private Int32 m_collectionCount;
public OperationTimer(String text) {
PrepareForOperation();
m_text = text;
m_collectionCount = GC.CollectionCount(0);
//
//
m_startTime = Stopwatch.StartNew();
}
public void Dispose() {
Console.WriteLine("{0} (GCs={1,3}) {2}", (m_stopwatch.Elapsed),
GC.CollectionCount(0) m_collectionCount, m_text);
}
( ) , :
00:00:01.6246959
00:00:10.8555008
00:00:02.5427847
00:00:02.7944831
(GCs= 6)
(GCs=390)
(GCs= 4)
(GCs= 7)
List<Int32>
ArrayList of Int32
List<String>
ArrayList of String
, Int32 List ,
ArrayList. , : 1,6
11 , 7 ! ,
(Int32) ArrayList , ,
, 390 , List 6.
: .
List
. ,
. ,
FCL
307
,
.
, CLR
.
.
.
FCL
, , FCL . System.Collections.Generic System.Collections.ObjectModel.
System.Collections.Concurrent. Microsoft
. -, ,
, ,
. -,
, . , , , ,
, .
, ,
, ,
, . FCL
,
.
System.Collections.Generic.
: .
. , List<T> IList<T>,
List< DateTime> IList.
, System.Array , , ,
AsReadOnly, BinarySearch, ConvertAll, Exists, Find, FindAll, FindIndex, FindLast,
FindLastIndex, ForEach, IndexOf, LastIndexOf, Resize, Sort TrueForAll.
:
public abstract class Array : ICloneable, IList, ICollection, IEnumerable,
IStructuralComparable, IStructuralEquatable {
308
12.
:
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"
}
2.0 CLR,
. Microsoft
:
IL-, .
.
( C#, Microsoft Visual
Basic .NET .),
.
IL-
.
JIT-, IL-, , .
, , .
, ,
.
309
, , ,
.
IntelliSense Microsoft Visual Studio
.
,
CLR. ,
.
, CLR
, . (type objects). , CLR
-.
(), (), .
- (open type),
CLR (
).
. , (closed type). 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<,>
Type t = typeof(Dictionary<,>);
// ()
o = CreateInstance(t);
Console.WriteLine();
// DictionaryStringKey<>
310
12.
t = typeof(DictionaryStringKey<>);
// ()
o = CreateInstance(t);
Console.WriteLine();
// 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.
Dictionary`2[TKey,TValue] because Type.ContainsGenericParameters is true.
Cannot create an instance of DictionaryStringKey`1[TValue] because
Type.ContainsGenericParameters is true.
Created instance of DictionaryStringKey`1[System.Guid]
Object type=DictionaryStringKey`1[System.Guid]
, CreateInstance
Activator ArgumentException. , .
,
(`), ,
(arity) , . , Dictionary 2,
TKey TValue. DictionaryStringKey 1,
TValue.
311
, CLR
- (.4). , . , , List<T>,
List<DateTime> List<String>,
.
(. 8), .
, . , ,
, :
internal sealed class GenericTypeThatRequiresAnEnum<T> {
static GenericTypeThatRequiresAnEnum() {
if (!typeof(T).IsEnum) {
throw new ArgumentException("T must be an enumerated type");
}
}
}
CLR (constraints),
. . ,
,
, .
, , . 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) {
}
312
12.
:
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()); // "ABC"
}
Node m_next ,
m_data . ,
( ) . , Node ,
Char, DateTime, String , ,
Node<Object>,
, .
,
Node, TypedNode ( Node
).
,
. :
internal class Node {
protected Node m_next;
313
return m_data.ToString() +
((m_next != null) ? m_next.ToString() : String.Empty);
. :
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());
}
.
(<) (>),
. ,
. ,
:
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<DateTime>, DateTimeList, DateTimeList List<DateTime>. .
, C#
, .
314
12.
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));
C#,
:
using System;
using System.Collections.Generic;
...
internal sealed class SomeType {
private static void SomeMethod () {
// , dtl
// System.Collections.Generic.List<System.DateTime>
var dtl = List<DateTime>();
...
}
}
JIT- CLR IL-
-, ,
. , ,
. : CLR
+ ,
(code explosion);
, .
, CLR , . -,
, CLR + . ,
List<DateTime> (
), CLR List<DateTime>
. .
315
, 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) :
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> - Point
316
12.
, ,
-:
internal sealed class ArrayEnumerator<T> : IEnumerator<T> {
private T[] m_array;
// Current IEnumerator<T> T
public T Current { get { ... } }
...
}
: ArrayEnumerator T (
T , , ArrayEnumerator,
T ). , Current T.
13.
CLR
, .
, . 17,
: 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 virtual TReturn Invoke(TKey key, TValue value);
public virtual IAsyncResult BeginInvoke(TKey key, TValue value,
AsyncCallback callback, Object object);
public virtual TReturn EndInvoke(IAsyncResult result);
}
317
, , Action
Func FCL. 17.
-
-
.
-. - :
. - . -.
. - ,
. C# in. -
, , .
. -
. #
out.
, , .
, :
public delegate TResult Func<in T, out TResult>(T arg);
- T in, ,
- TResult out, .
:
Func<Object, ArgumentException> fn1 = null;
Func -:
Func<String, Exception> fn2 = fn1; //
Exception e = fn2("");
, fn1 , Object
ArgumentException. fn2 ,
String Exception.
String , Object ( String
Object), , ArgumentException, Exception ( ArgumentException
Exception), ,
.
318
12.
,
. , - (boxing).
, - . :
void ProcessCollection(IEnumerable<Object> collection) { ... }
, List<DateTime> -
DateTime Object, DateTime Object.
:
void ProcessCollection<T>(IEnumerable<T> collection) { ... }
ProcessCollection(IEnumerable<Object> collection)
, JIT-.
ProcessCollection<T> (IEnumerable<T> collection)
JIT-, T, . T, ,
JIT-,
.
-,
out ref. , :
delegate void SomeDelegate<in T>(ref T t);
( : - 'T'
'SomeDelegate<T>.Invoke(ref T)'. - 'T' ):
Invalid variance: The type parameter 'T' must be invariantly valid on
'SomeDelegate<T>.Invoke(ref T)'. 'T' is contravariant
in out , .
,
.
, -
, . :
public interface IEnumerator<out T> : IEnumerator {
Boolean MoveNext();
T Current { get; }
}
T :
319
// IEnumerable
Int32 Count(IEnumerable<Object> collection) { ... }
...
// IEnumerable<String> Count
Int32 c = Count(new[] { "Grant" });
, in
out . ,
,
. , C# ,
. , ,
,
- .
, - ,
, -,
.
. - , ,
. in out
-, , .
, , -.
- ,
. 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));
320
12.
return result;
GenericType - (T),
Converter (TOutput). GenericType,
. Converter ,
m_value, , . -
.
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 = "Grant";
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/ref 9. , Exchange CompareExchange
Interlocked 1:
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#
. ,
where .
321
# (type inference)
. ,
( ) ,
. :
private static void CallingSwapUsingInference() {
Int32 n1 = 1, n2 = 2;
Swap(ref n1, ref n2); // Swap<Int32>
String s1 = "Aidan";
Object s2 = "Grant";
Swap(ref s1, ref s2); // ,
}
, Swap
< >. Swap C# ,
n1 n2 Int32, Swap,
- Int32.
C#
, , .
Swap C# , s1 String,
s2 Object ( s2 String). s1 s2
,
Swap ( CS0411:
Program.Swap<T>(ref T, ref T) .
):
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
,
, -,
:
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(String)
Display(123); // Display<T>(T)
Display<String>("Aidan"); // Display<T>(T)
Display,
String, Display ( T String).
C# , ,
322
12.
Display, String.
Display, String,
Display. , ,
.
Display, ToString, String,
.
Display String.
, , .
,
Display, . Display
ToString ,
Display.
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;
}
323
(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, #
, . ( CS0117: T CompareTo):
error CS0117: 'T' does not contain a definition for 'CompareTo'
, , , ,
Object, ! . ,
CLR
(constraints), .
,
, .
Min, ( ):
public static T Min<T>(T o1, T o2) where T : IComparable<T> {
if (o1.CompareTo(o2) < 0) return o1;
return o2;
}
324
12.
( CS0311: object
- 'T'
'SomeType.Min<T>(T,T)'.
'Object' 'System.IComparable<object>'.
Error CS0311: The type 'object' cannot be used as type parameter 'T' in the generic
type or method 'SomeType.Min<T>(T, T)'. There is no implicit
reference conversion from 'object' to 'System.IComparable<object>'.
:
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
//
private static void
private static void
private static void
AnotherType {
:
M() {}
M<T>() {}
M<T1, T2>() {}
// : M<T>,
private static void M<T>() where T : IComparable<T> {}
// : M<T1, T2>.
private static void M<T3, T4>() {}
}
-, , ,
, . ,
-, -. ,
-, , -
, . :
325
( CS0460:
):
Error CS0460: Constraints for override and explicit interface implementation
methods are inherited from the base method, so they cannot be
specified directly
- .
, .
: 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
}
}
326
12.
- T Stream ( System.IO), ,
, PrimaryConstraintOfStream,
Stream (, FileStream). -
, System.Object.
System.Object, C#
( CS0702: object):
error CS0702: Constraint cannot be special class 'object'
temp null , , T ,
null. T , ,
null.
struct ,
.
, . CLR
System.Nullable<T> ,
null . ,
Nullable<T> struct, CLR
, Nullable<Nullable<T>>.
null 19.
, -
struct:
internal sealed class PrimaryConstraintOfStruct<T> where T : struct {
public static T Factory() {
// ,
//
return new T();
}
}
T new , ,
T , . T ,
327
, ,
.
- . ,
- , .
,
, (
, ). .13.
(type parameter constraint). ,
, ,
- . .
-:
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);
// 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);
328
12.
// IList<String> IList<Exception>
IList<Exception> le = ConvertIList<String, Exception>(ls); //
}
ConvertIList , String
Object. String Object,
-. ConvertIList
, String IComparable.
String IComparable,
-. ConvertIList ,
String IComparable<String>. String
IComparable<String>, -.
ConvertIList , String
. ConvertIList , String
Exception. String Exception,
,
( CS0311: string 'T' Program.ConvertIList<T,TBase>(System.
Collectons.Generic.IList<T>).
'string' 'System.Exception':
error CS0311: The type 'string' cannot be used as type parameter 'T' in the
generic type or method Program.ConvertIList<T,TBase>(System.Collections.Ge
neric.IList<T>)'. There is no implicit reference conversion from 'string' to
'System.Exception'.
- .
, -
, .
, #
struct, .
.
- :
internal sealed class ConstructorConstraint<T> where T : new() {
public static T Factory() {
// ,
// ,
// ,
//
return new T();
}
}
new T , , T . ,
329
, ,
, -.
, .
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 ,
:
330
12.
T , , null .
, temp null,
. C# Microsoft , .
# default:
private static void SettingAGenericTypeVariableToDefaultValue<T>() {
T temp = default(T); //
}
T , . obj null. C#
, .
JIT, , if true,
if .
!=, JIT-
if ( ), if.
, struct, # ,
, null,
.
, :
331
T ,
,
, ==. T
class, , == true, . T
, operator==,
, ==. , !=.
(Byte, Int32,
Single, Decimal ..) # , .
ComparingTwoGenericTypeVariables struct,
. - ,
, ,
, . ,
; C# ,
.
,
. 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;
}
, :
. :
CS0019: < T :
332
12.
CS0023: ++ :
error CS0023: Operator '++' cannot be applied to operand of type 'T'
CS0019: += T :
error CS0019: Operator '+=' cannot be applied to operands
of type 'T' and 'T'
CLR,
( , )
. ,
, (.23),
dynamic (. 5), ..
.
, CLR Microsoft
.
13.
(multiple inheritance) ,
. , TransmitData,
, ReceiveData, .
, SocketPort, , . SocketPort
: TransmitData ReceiveData.
, SocketPort, .
CLR ( , )
. CLR (interfaces).
,
, ,
, .
.NET Framework System.Object, 4
: ToString, Equals, GetHashCode GetType. ,
Object. , , Object,
.
Object :
. ,
Object, -
.
. ,
Object, Object .
CLR (
Object). .
, ,
.
334
13.
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 {
335
IEnumerator<T> GetEnumerator();
CLR, ,
. CLR , . ,
.
(public, protected, internal ..).
I , . CLR
( ) .
, .12.
. ,
, .
. ,
TCollection<T> TEnumerable<T> IEnumerable.
:
, ICollection<T>,
, ICollection<T>, IEnumerable<T>
IEnumerable;
, , ICollection<T>,
,
IEnumerable<T> IEnumerable.
, , ,
.
C# , ,
.
336
13.
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> {
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 , -
337
. ,
, , .
. ,
, .
,
,
.
, . :
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("Base's Dispose");
}
}
338
13.
// Base IDisposable
internal class Derived : Base, IDisposable {
// Dispose Base.
// 'new' ,
// Dispose IDisposable
new public void Dispose() {
Console.WriteLine("Derived's Dispose");
// : ,
// ( )
// base.Dispose();
}
}
( )
339
// enumerable String
//
// ,
IEnumerable enumerable = (IEnumerable) comparable;
// enumerable, ,
// IEnumerable ( ,
// Object)
String
, , ,
, String, "Jeffrey".
, . s String, , ,
String (, Length). s
, Object (, GetType).
cloneable ICloneable, ,
Clone, . , , Object (, GetType),
CLR , Object.
cloneable ,
, String. comparable CompareTo ,
Object, .
, ( ) .
, ,
, CLR . CLR ,
.
( )
CLR,
(.1). , , ,
. ,
, , . , :
340
13.
, :
, Object
;
,
IDisposable ( IDisposable
Dispose);
, Dispose, SimpleType.
, C# , SimpleType Dispose Dispose
IDisposable. C# ,
,
. , . ,
Dispose , C#
.
, 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,
, - .
:
341
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),
. .
, EIMI- , ,
. , EIMI- ; ( , ) .
, , .
EIMI.
C# CLR
.
.
-, . (, IComparable)
, Object.
, . :
private void SomeMethod1() {
Int32 x = 1, y = 2;
IComparable c = x;
342
13.
// CompareTo Object,
// y Int32
c.CompareTo(y); //
// CompareTo Object,
// "2" ( String) ,
// ArgumentException
c.CompareTo("2");
}
, , FCL IComparable<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"); //
}
,
. :
SomeMethod1 CompareTo IComparable
Object; y ( Int32)
y. SomeMethod2 CompareTo
IComparable<T> Int32; y ,
.
FCL IComparable,
ICollection, IList, IDictionary .
,
. FCL , , .NET Framework .
, .
,
, .
, IEnumerable<T>
IEnumerable. IEnumerable<T>,
IEnumerable.
343
, ,
, .
,
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) {
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");
}
}
,
.
12.
344
13.
.
- .
, - .
. :
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 {
...
}
}
!
, . ,
, . ,
.
, , ,
( ), .
, .
. M
x ( Int32, ). x M . M t.CompareTo(...),
(
, CompareTo).
345
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 {
// GetMenu IWindow
Object IWindow.GetMenu() { ... }
// GetMenu IRestaurant
Object IRestaurant.GetMenu() { ... }
// GetMenu (),
//
public Object GetMenu() { ... }
}
346
13.
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. ,
, :
internal struct SomeValueType : IComparable {
private Int32 m_x;
public SomeValueType(Int32 x) { m_x = x; }
public Int32 CompareTo(Object other) {
347
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 other SomeValueType, InvalidCastException.
EIMI.
SomeValueType, :
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. SomeValueType
CompareTo, IComparable.
CompareTo,
.
348
13.
:
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-,
IntelliSense- Microsoft Visual Studio;
;
EIMI .
349
.NET Framework
,
. , Int32 ,
IConvertible. , , ; , ,
IConvertible Int32 . ,
.
public static void Main() {
Int32 x = 5;
Single s = x.ToSingle(null); //
// IConvertible
}
C#
( CS0117: int ToSingle):
error CS0117: 'int' does not contain a definition for 'ToSingle'
; ,
Int32 ToSingle , .
ToSingle Int32,
IConvertible:
public static void Main() {
Int32 x = 5;
Single s = ((IConvertible) x).ToSingle(null);
}
,
.
Int32 IConvertible
, . .
, , EIMI ,
.
:
internal class Base : IComparable {
// (EIMI)
Int32 IComparable.CompareTo(Object o) {
Console.WriteLine("Base's CompareTo");
return 0;
}
}
internal sealed class Derived : Base, IComparable {
// ,
public Int32 CompareTo(Object o) {
350
13.
Console.WriteLine("Derived's CompareTo");
// EIMI :
// "error CS0117: 'Base' does not contain a definition for 'CompareTo'"
base.CompareTo(o);
return 0;
}
}
return 0;
: ?
351
//
// ( )
public virtual Int32 CompareTo(Object o) {
Console.WriteLine("Base's virtual CompareTo");
return 0;
}
}
internal sealed class Derived : Base, IComparable {
// ,
public override Int32 CompareTo(Object o) {
Console.WriteLine("Derived's CompareTo");
// Base
return base.CompareTo(o);
}
}
: ,
. ,
.
, . EIMI,
, . !
,
, .
:
?
,
? . ,
.
. .
, ,
. . ,
(IConvertible),
(ISerializable) .. ,
System.ValueType
. .
352
13.
. , , .
,
, .
.
. ,
. , COM
COM-
Microsoft Word Microsoft Internet Explorer.
,
.
. ,
.
.
.
FCL , , . System.IO.Stream , , Read Write. (System.
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> .
: ?
353
, , .
, , . , IList<T>, ,
, , .
.
, , , . , FCL
IComparer<T>, .
, FCL Comparer<T>, ()
Compare IComparer. ,
.
III
14. , . .. .. ..356
15. . .. ..403
16. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 416
17. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..434
18. . .. .. .. .. .. .. .. .. .. ..464
19. Null- . .. .. .. .. 485
14. ,
,
Microsoft .NET Framework. System.Char
.
System.String, (
, ).
System.Text.StringBuilder.
,
.
System.Security.SecureString,
,
.
357
. (culture), (
, CurrentCulture System.
Globalization.CultureInfo), ToLower ToUpper.
,
CultureInfo.
ToLower ToUpper, . , U+0069 (
i) U+0130 (
I ),
U+0049 ( I).
, Char . Equals true,
Char 16- . CompareTo ( IComparable IComparable<Char>)
. ConvertFromUtf32 , UTF-16,
UTF-32. ConvertToUtf32 UTF-32
. ToString ,
, Parse TryParse
String UTF-16.
, GetNumericValue .
:
using System;
public static class Program {
public static void Main() {
Double d; //
d = Char.GetNumericValue('\u0033'); //
//
Console.WriteLine(d.ToString()); //
Char, .
. ,
IL- - . -
358
14. ,
Char , Int32,
. , (, C#)
, :
(. 5).
Convert. System.Convert , Char . ,
OverflowException.
IConvertible. Char
.NET Framework Class Library (FCL)
IConvertible, , ToUInt16 ToChar.
, : Char
. IConvertible System.
InvalidCastException, (, Char Boolean) . (
Char FCL) EIMI-
IConvertible (.13), , -
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
System.String
359
c = Convert.ToChar(65);
Console.WriteLine(c); // "A"
n = Convert.ToInt32(c);
Console.WriteLine(n); // "65"
// Convert
try {
c = Convert.ToChar(70000); // 16
Console.WriteLine(c); //
}
catch (OverflowException) {
Console.WriteLine("Can't 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() {
360
14. ,
:
using System;
public static class Program {
public static void Main() {
String s = "Hi there.";
Console.WriteLine(s);
}
}
ILDasm.exe:
IL- newobj.
. IL- ldstr
( ), String ,
. , String CLR
.
, String Char*
SByte*. new String, Char* SByte*.
String ,
Char . , , .
C# . , ,
, , C# ,
C/C++:
// String
String s = "Hi\r\nthere.";
System.String
361
, , .
System.Environment NewLine, Windows , .
NewLine ,
. , CLI UNIX NewLine ,
\n. ,
:
String s = "Hi" + Environment.NewLine + "there.";
, +
C#:
//
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.
362
14. ,
, String , ;
, . .
, :
if (s.ToUpperInvariant().Substring(10, 21).EndsWith("EXE")) {
...
}
ToUpperInvariant ; s
. SubString , ToUpperInvariant,
, EndsWith .
,
ToUpperInvariant SubString,
. ,
String , .
. , 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)
System.String
363
. ,
, ,
, .
comparisonType ( )
, StringComparison,
:
public enum StringComparison {
CurrentCulture = 0,
CurrentCultureIgnoreCase = 1,
InvariantCulture = 2,
InvariantCultureIgnoreCase = 3,
Ordinal = 4,
OrdinalIgnoreCase = 5
}
options ,
CompareOptions:
[Flags]
public enum CompareOptions {
None = 0,
IgnoreCase = 1,
IgnoreNonSpace = 2,
IgnoreSymbols = 4,
IgnoreKanaType = 8,
IgnoreWidth = 0x00000010,
Ordinal = 0x40000000,
OrdinalIgnoreCase = 0x10000000,
StringSort = 0x20000000
}
364
14. ,
, CompareOptions,
.
Ordinal OrdinalIgnoreCase, Compare
.
:
, URL-, ,
, , XML-, XML- .. , .
StringComparison.
Ordinal StringComparison.OrdinalIgnoreCase.
,
.
,
( ), StringComparison.CurrentCulture
StringComparison.CurrentCultureIgnoreCase.
StringComparison.InvariantCulture
StringComparison.InvariantCultureIgnoreCase. ,
, StringComparison.Ordinal
StringComparison.OrdinalIgnoreCase. ,
,
.
, String ToUpperInvariant
ToLowerInvariant. ToUpperInvariant, ToLowerInvariant - , Microsoft
. , FCL
.
, .
StartsWith, EndsWith Compare Boolean
CultureInfo.
. - ( RFC 1766) .NET Framework
System.Globalization.CultureInfo. , en-US -
System.String
365
() , en-AU
, de-DE . CLR
,
CultureInfo.
CurrentUICulture , . Web Forms, ,
,
.
Win32- GetUserDefaultUILanguage
CultureInfo, Windows. MUI (Multilingual User Interface) Windows
Regional and Language Options (
) .
CurrentCulture ,
CurrentUICulture, , .
CultureInfo .
Win32- GetUserDefaultLCID
CultureInfo. Regional Options
( ) Regional and Language Options ( ) .
,
,
DefaultThreadCurrentCulture DefaultThreadCurrentUICulture CultureInfo.
CurrentUICulture CurrentCulture
CultureInfo,
. . , ,
366
14. ,
, , .
CurrentUICulture CultureInfo, es (), CurrentCulture CultureInfo,
en-US.
CultureInfo System.
Globalization.CompareInfo,
. :
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("de-DE");
// 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 .
. ,
System.String
367
. CompareInfo CultureInfo. ,
CompareInfo
,
CompareInfo.
Compare String . ,
CurrentCulture . , Compare, CompareInfo
Compare CompareInfo, (,
). , ,
Compare CompareInfo.
Compare CompareInfo
CompareOptions. .
.NET Framework.
:
using
using
using
using
using
System;
System.Text;
System.Windows.Forms;
System.Globalization;
System.Threading;
368
14. ,
CompareInfo.Compare
"shinkansen" (
) :
= " "; // ("\u3057\u3093\u304b\u3093\u305b\u3093")
= " "; // ("\u30b7\u30f3\u30ab\u30f3\u30bb\u30f3")
//
ci = new CultureInfo("ja-JP");
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("ja-JP");
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");
}
}
ANSI,
.
Microsoft Visual Studio, Save File As, Save With Encoding.
(UTF-8 with signature) Codepage 65001. C#
, .
,
.14.1.
System.String
369
. 14.1.
,
CompareOptions,
Compare, IndexOf, LastIndexOf, StartsWith EndsWith String.
, , FCL System.StringComparer,
.
,
.
, ,
.
(ordinal comparison) CLR , . ,
, .
CLR ,
.
. , ,
.
, CLR (string interning).
CLR -,
,
. , , . String , -:
public static String Intern(String str);
public static String IsInterned(String str);
370
14. ,
, Intern, String -.
, String.
, -, . String, ,
. , ,
-,
String. String, -,
,
.
Intern , IsInterned String
-. , IsInterned
. null,
-.
CLR ,
. ,
- -,
Microsoft . System.Runtime.CompilerServices.CompilationRelaxations
Attribute, System.Runtime.CompilerServices.
CompilationRelaxations.NoStringInterning,
ECMA CLR , . ,
C#
/.
/, CLR
, .
, ,
Intern String.
:
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'
System.String
371
. , ,
,
/ , "Hello"
. , CLR 4.5 /,
NGen.exe.
ReferenceEquals "Hello" , s1 "Hello".
Intern s2 "Hello", s1. ReferenceEquals
True ,
/.
, .
NumTimesWordAppearsEquals : ,
. ,
, :
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, . ,
, .
, :
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;
}
372
14. ,
, wordlist
. -, ,
, wordlist String . -,
, , ,
.
NumTimesWordAppearsIntern , NumTimes
WordAppearsEquals ,
, NumTimesWordAppearsIntern - ,
wordlist ( ).
NumTimesWordAppearsIntern , ,
wordlist. ,
, .
, C# ,
.
.
,
.
, ( C#)
.
. .
Microsoft C/C++
(string pooling). ,
. , .
,
.
String,
Length, Chars ( C#), GetEnumerator, ToCharArray, Contains, IndexOf,
LastIndexOf, IndexOfAny LastIndexOfAny.
System.Char 16-
, . , Unicode-
. , U+0625 (
System.String
373
) U+0650 ( ) , .
, ,
16- . (high surrogate),
(low surrogate).
U+D800 U+DBFF, U+DC00 U+DFFF.
Unicode
.
- .
System.Globalization.StringInfo.
,
. , , LengthInTextElements StringInfo.
SubstringByTextElements StringInfo,
.
, StringInfo GetTextElementEnumerator,
System.Globalization.TextElementEnumerator, ,
, .
, ParseCombiningCharacters
StringInfo, Int32,
.
.
StringInfo :
using
using
using
using
System;
System.Text;
System.Globalization;
System.Windows.Forms;
374
14. ,
(.14.214.4).
. 14.2.
SubstringByTextElements
. 14.3.
GetTextElementEnumerator
. 14.4.
ParseCombiningCharacters
375
. 14.1 String,
.
14.1.
Clone
(this).
, String .
ICloneable String
Copy
. , .
. , ,
(),
CopyTo
Substring
ToString
(this)
, String
: Insert, Remove, PadLeft, Replace,
Split, Join, ToLower, ToUpper, Trim, Concat, Format . ,
; , ( ).
String ,
String FCL System.
Text.StringBuilder. String. ,
String, StringBuilder,
, , .
StringBuilder
Char. StringBuilder,
376
14. ,
, . ,
, 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 ( ). ,
,
. StringBuilder .
(capacity) Int32,
StringBuilder. 16. ,
StringBuilder,
StringBuilder. StringBuilder ,
. ,
StringBuilder , ,
, . .
,
, .
377
StringBuilder
StringBuilder String . , StringBuilder ,
, . StringBuilder
:
, ;
ToString StringBuilder.
. 14.2 StringBuilder.
14.2. StringBuilder
MaxCapacity
Capacity
/
.
, , ,
MaxCapacity,
ArgumentOutOfRangeException
EnsureCapacity
,
, ,
.
StringBuilder,
. ,
, ,
Length
.
. 0
StringBuilder
378
14. ,
14.2 ()
ToString
String,
StringBuilder
Chars
. C# ( ),
( [])
Clear
StringBuilder, Length 0
Append
,
. ,
Insert
,
. ,
AppendFormat
,
.
.
StringBuilder
AppendLine
Replace
Remove
Equals
true, StringBuilder
,
CopyTo
StringBuilder
Char
: StringBuilder
StringBuilder.
:
379
StringBuilder String.
, String ToLower, ToUpper, EndsWith, 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); // "JEFFREY-Marc-RICHTER"
- , StringBuilder
, String. ,
Microsoft StringBuilder,
.
380
14. ,
.NET Framework - ,
,
. , FCL ,
. .
ToString.
System.Object, . ToString ,
,
. , ,
, ,
.
ToString System.Object
. ,
. , , FileStream Hashtable?
, , ToString . ,
FCL (Byte, Int32, UInt64, Double ..),
ToString,
. Visual Studio .
ToString . ,
ToString,
.
ToString . -,
, , , , ,
. -,
, . ,
.
, .
ToString,
.
, System.IFormattable:
public interface IFormattable {
String ToString(String format, IFormatProvider formatProvider);
}
381
, .
ToString IFormattable . ,
format, , . , formatProvider, , System.
IFormatProvider. ToString . .
, ToString IFormattable, .
, System.FormatException.
FCL . , DateTime
: "d" , "D"
, "g" , "M" /, "s"
, "T" , "u" ISO 8601,
"U" , "Y" / ..
: "G" , "F"
, "D" "X" .
.15.
, :
"C" , "D" , "E" () , "F" , "G" ,
"N" , "P" , "R" (round-trip)
"X" .
, .
,
ToString ,
, ..
. .NET Framework SDK,
.
null,
ToString "G". , ,
. , , , , ;
. , ToString
.
, .
,
. ToString ToString IFormattable null
formatProvider.
382
14. ,
(
, , ), .
ToString Guid, GUID, , GUID.
, .
T o S t r i n g
formatProvider. null, ToString , , System.Threading.
Thread.CurrentThread.CurrentCulture. System.
Globalization.CultureInfo.
, ToString NumberFormat DateTimeFormat .
System.Globalization.NumberFormatInfo System.
Globalization.DateTimeFormatInfo . NumberFormatInfo , CurrencyDecimalSeparator, CurrencySymbol,
NegativeSign, NumberGroupSeparator PercentSymbol. , DateTimeFormatInfo , Calendar, DateSeparator, DayNames,
LongDatePattern, ShortTimePattern 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("vi-VN"));
MessageBox.Show(s);
, (.14.5).
ToString Decimal, , formatProvider
null, GetFormat :
NumberFormatInfo nfi = (NumberFormatInfo)
formatProvider.GetFormat(typeof(NumberFormatInfo));
383
. 14.5.
GetFormat ,
, . .NET
Framework GetFormat
/; .
, , ,
InvariantCulture System.Globalization.CultureInfo
formatProvider ToString:
Decimal price = 123.54M;
String s = price.ToString("C", CultureInfo.InvariantCulture);
MessageBox.Show(s);
(.14.6). : . (U+00A4).
. 14.6. , .
384
14. ,
. ,
.
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);
// ToString(null, formatProvider)
// ToString IConvertible
// : ,
//
public String ToString(IFormatProvider formatProvider);
, .
.
, :
String s = String.Format("On {0}, {1} is {2} years old.",
new DateTime(2012, 4, 22, 14, 35, 5), "Aidan", 9);
Console.WriteLine(s);
385
en-US,
:
On 4/22/2012 2:35:05 PM, Aidan is 9 years old.
Format String ,
. Format {0} (
), {1} (Aidan) {2} ,
(9).
Format ToString, . , . ,
,
.
,
. ,
0 2:
String s = String.Format("On {0:D}, {1} is {2:E} years old.",
new DateTime(2012, 4, 22, 14, 35, 5), "Aidan", 9);
Console.WriteLine(s);
en-US,
:
On Sunday, April 22, 2012, Aidan is 9.000000E+000 years old.
, Format , 0 IFormattable
ToString, D null. , Format ToString IFormattable 2,
E null. IFormattable,
Format ToString ,
.
String
Format. , IFormatProvider,
, . ,
Format ToString ,
IFormatProvider.
String StringBuilder,
AppendFormat StringBuilder . , Format String , ,
StringBuilder.
386
14. ,
AppendFormat ,
IFormatProvider.
System.Console Write WriteLine,
. Console Write WriteLine, IFormatProvider.
, Format String,
IFormatProvider, 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);
}
}
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
387
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> September 1
Main StringBuilder ,
. AppendFormat
BoldInt32s. ,
IFormatProvider,
ICustomFormatter:
public interface ICustomFormatter {
String Format(String format, Object arg,
IFormatProvider formatProvider);
}
. 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));
// (
// )
// StringBuilder.
Boolean MoreReplaceableArgumentsToAppend = true;
while (MoreReplaceableArgumentsToAppend) {
388
14. ,
// 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;
}
389
. : ,
.
, . Microsoft ,
.
, , ,
Parse. String, ; Parse . FCL Parse
, DateTime, TimeSpan
(, SQL).
, .
(Byte, SByte, Int16/UInt16, Int32/UInt32, Int64/UInt64, Single, Double, Decimal
BigInteger) Parse. Parse
Int32 ( Parse ).
public static Int32 Parse(String s, NumberStyles style, IFormatProvider
provider);
, . s
String , Int32. style System.
Globalization.NumberStyles
, Parse . provider
IFormatProvider , Parse
, .
, Parse
System.FormatException, :
Int32 x = Int32.Parse(" 123", NumberStyles.None, null);
390
14. ,
, Parse style:
Int32 x = Int32.Parse(" 123", NumberStyles.AllowLeadingWhite, null);
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);
391
.
, Parse DateTime
, , . DateTime
ParseExact, , , , ,
. . , DateTimeFormatInfo,
.NET Framework SDK.
Microsoft : 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 20.
:
Win32- ,
Unicode Multi-Byte Character Set (MBCS).
, ,
. CLR 16- ,
16- . .
.
,
16- ,
. (encode) 16-
, (decode)
16- .
, , . ,
392
14. ,
393
, . Unicode Consortium
UTF-7.
ASCII 16- ASCII-; 16 0x0080 .
0x007F , . , ASCII- (
0x00 0x7F), ,
( ).
ASCII-, .
, FCL 16-
. ASCII, , . UTF-16 UTF-8 ,
, - .
,
, System.Text.Encoding. Encoding ,
, Encoding.
UTF-8:
using System;
using System.Text;
public static class Program {
public static void Main() {
//
String s = "Hi there.";
// , Encoding, ""
// UTF-8
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);
}
}
394
14. ,
:
Encoded bytes: 48-69-20-74-68-65-72-65-2E
Decoded string: Hi there.
, Regional and Language Options (
) (. Win32-
GetACP). Default , ,
, ,
.
, Encoding
GetEncoding, ( ).
GetEncoding , /,
. , GetEncoding
"Shift-JIS" 932.
Encoding (
GetEncoding) .
; .
.
GetEncoding Encoding, System.Text.
UnicodeEncoding, 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 , .
395
( ):
396
14. ,
, Encoding, .14.3.
397
14.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
, UTF-16 System.Net.Sockets.NetworkStream. ,
, 5, 7.
UTF-16 .
GetString Encoding 5
, . GetString
7, GetString , ,
!
,
Encoding
. ,
,
, .
398
14. ,
,
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,
, .
Base-64
UTF-16 UTF-8 .
base-64. FCL
base-64. , ,
Encoding, -
base-64 ,
System.Convert.
399
base-64 ,
FromBase64String FromBase64CharArray Convert.
base-64
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));
// base-64
String s = Convert.ToBase64String(bytes);
Console.WriteLine(s);
// base-64
bytes = Convert.FromBase64String(s);
Console.WriteLine(BitConverter.ToString(bytes));
}
}
( ,
):
3B-B9-27-40-59-35-86-54-5F-F1
O7knQFk1hlRf8Q==
3B-B9-27-40-59-35-86-54-5F-F1
String ,
. , String ,
, ,
. String
, CLR
( String ),
, .
, ,
400
14. ,
,
.
, .
Microsoft FCL System.
Security.SecureString. SecureString
, .
.
.
, ,
AppendChar, InsertAt, RemoveAt SetAt.
,
. , . ,
, ,
, .
SecureString IDisposable,
, . ,
Dispose SecureString
SecureString using. Dispose , ,
. SecureString
, SafeBuffer, .
SafeBuffer CriticalFinalizerObject (.21), Finalize
SecureString, .
String, SecureString
.
, , SecureString,
. , FCL SecureString , ,
SecureString, . 4 .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;
401
. System.
Diagnostics.Eventing.Reader.EventLogSession;
System.Windows.Controls.PasswordBox
. SecurePassword.
, ,
SecureString. SecureString
, ,
.
, .
.
SecureString String
,
. SecureString ToString
( String).
Secure
String ( /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,
//
}
// ,
private unsafe static void DisplaySecureString(SecureString ss) {
Char* pc = null;
try {
// SecureString
402
14. ,
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. ,
. .14.4 System.Runtime.InteropServices.Marshal,
SecureString ,
.
14.4. Marshal
SecureString
SecureStringToBSTR
ZeroFreeBSTR
SecureStringToCoTaskMemAnsi
ZeroFreeCoTaskMemAnsi
SecureStringToCoTaskMemUnicode
ZeroFreeCoTaskMemUnicode
SecureStringToGlobalAllocAnsi
ZeroFreeGlobalAllocAnsi
SecureStringToGlobalAllocUnicode
ZeroFreeGlobalAllocUnicode
15.
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).
- , , . ,
, ,
, .
404
15.
. , ,
Color.Orange ( ),
Fruit ().
CLR ,
. ,
,
(, C++).
System.Enum, System.ValueType, , , System.Object.
, (.5)
, .
, ,
. , ,
(extension methods).
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,
,
405
, .
.
.
, . .
, ,
. , , , ,
. 7.
, System.Enum GetUnderlyingType,
System.Type GetEnumUnderlyingType:
public static Type GetUnderlyingType(Type enumType); //
// System.Enum
public Type GetEnumUnderlyingType(); // System.Type
,
. ,
byte, sbyte, short, ushort, int ( C# ), uint, long ulong. C# FCL.
C# ;
FCL (, Int32) ( CS1008:
byte, sbyte, short, ushort, int, uint, long ulong):
error CS1008: Type byte, sbyte, short, ushort, int, uint, long, or ulong expected
C# ,
byte (System.Byte):
internal enum Color : byte {
White,
Red,
Green,
Blue,
Orange
}
C o l o r ,
GetUnderlyingType :
// "System.Byte"
Console.WriteLine(Enum.GetUnderlyingType(typeof(Color)));
C# ,
(==, !=,
406
15.
, C# .
.
ToString, System.Enum:
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")); //
"Blue" ( )
"Blue" ( )
"Blue" ( )
"3" ( )
"03" ( )
ToString
. ,
. byte/sbyte , short/
ushort , int/uint , long/ulong .
.
ToString .
, Format
value, . ,
"Blue":
// "Blue"
Console.WriteLine(Enum.Format(typeof(Color), 3, "G"));
, . ,
, . ,
.
407
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);
}
:
Number of symbols defined: 5
Value
Symbol
---------0
White
1
Red
2
Green
3
Blue
4
Orange
GetEnumValues
:
Color[] colors = GetEnumValues<Color>();
,
. ,
( , ..)
ToString ( ,
). GetValues, System.Enum System.Type :
//
public static String GetName(Type enumType, Object value); //
// System.Enum
public String GetEnumName(Object value); // System.Type
// :
408
15.
//
public static String[] GetNames(Type enumType); // System.Enum
public String[] GetEnumNames(); // System.Type
,
( ) .
, , ,
.
Parse TryParse Enum:
public static Object Parse(Type enumType, String value);
public static Object Parse(Type enumType, String value, Boolean ignoreCase);
public static Boolean TryParse<TEnum>(String value,
out TEnum result) where TEnum: struct;
public static Boolean TryParse<TEnum>(String value,
Boolean ignoreCase, out TEnum result)
where TEnum : struct;
:
// Orange 4, 'c' 4
Color c = (Color) Enum.Parse(typeof(Color), "orange", true);
// Brown , ArgumentException
c = (Color) Enum.Parse(typeof(Color), "Brown", false);
// Color 1
Enum.TryParse<Color>("1", false, out c);
// Color 23
Enum.TryParse<Color>("23", false, out c);
Defined Type:
:
// "True", Color
// Red 1
Console.WriteLine(Enum.IsDefined(typeof(Color), 1));
// "True", Color
// White 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), (Byte)10));
IsDefined . :
public void SetColor(Color c) {
if (!Enum.IsDefined(typeof(Color), c)) {
409
,
SetColor :
SetColor((Color) 547);
547 , SetColor
ArgumentOutOfRangeException ,
.
IsDefined . , , -,
, . , .
, ,
, . , Color
, SetColor . SetColor
IsDefined , White, Red, Green, Blue
Orange. Color Purple,
SetColor ,
.
ToObject System.Enum,
Byte, SByte, Int16, UInt16, Int32, UInt32, Int64
UInt64 .
.
,
. , :
, . FCL ,
, .
, .
.
. GetAttributes
System.IO.File FileAttributes. FileAttri
410
15.
butes , 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 = Assembly.GetEntryAssembly().Location;
FileAttributes attributes = File.GetAttributes(file);
Console.WriteLine("Is {0} hidden? {1}", file, (
attributes & FileAttributes.Hidden) != 0);
Enum HasFlag, :
public Boolean HasFlag(Enum flag);
ConsoleWriteLine:
Console.WriteLine("Is {0} hidden? {1}", file,
attributes.HasFlag(FileAttributes.Hidden));
HasFlag. ,
Enum, , ,
.
, :
File.SetAttributes(file, FileAttributes.ReadOnly | FileAttributes.Hidden);
FileAttributes , , ,
.
, .
411
, ,
, .
,
, .
.
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; // 0x0005
Console.WriteLine(actions.ToString()); // "Read, Delete"
ToString
. 0x0005 . Actions [Flags], ToString
. 0x0001 0x0005
, ToString "Read, Delete".
Actions [Flags], "5".
ToString
: "G" (), "D" () "X" ().
, [Flags].
, , . , ToString
:
1. , ,
.
2. (AND)
.
412
15.
, .
.
3.
, , .
.
4. , , .
5. , ,
.
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; // 0x0005
Console.WriteLine(actions.ToString("F")); // "Read, Delete"
, -
, ,
, .
: , ,
. , Actions All, 0x001F.
Actions 0x001F "All". .
.
, , Parse
Enum TryParse. :
// Query 8, 'a' 8
Actions a = (Actions) Enum.Parse(typeof(Actions), "Query", true);
413
Console.WriteLine(a.ToString()); // "Query"
// Query, Read, 'a'
// 9
Enum.TryParse<Actions>("Query, Read", false, out a);
Console.WriteLine(a.ToString()); // "Read, Query"
// Actions enum 28
a = (Actions) Enum.Parse(typeof(Actions), "28", false);
Console.WriteLine(a.ToString()); // "Delete, Query, Sync"
Parse TryParse :
1. .
2. , (+)
(), ,
, .
3. ,
.
4. . , Parse System.
ArgumentException, TryParse false. (OR)
, .
5. .
IsDefined . :
, ,
. , , , .
, .
, false.
,
. ,
414
15.
,
. ,
C# (extension method),
8.
FileAttributes . :
internal static class FileAttributesExtensionMethods {
public static Boolean IsSet(
this FileAttributes flags, FileAttributes flagToTest) {
if (flagToTest == 0)
throw new ArgumentOutOfRangeException(
"flagToTest", "Value must not be 0");
return (flags & flagToTest) == flagToTest;
}
public static Boolean IsClear(
this FileAttributes flags, FileAttributes flagToTest) {
if (flagToTest == 0)
throw new ArgumentOutOfRangeException(
"flagToTest", "Value must not be 0");
return !IsSet(flags, flagToTest);
}
public static Boolean AnyFlagsSet(
this FileAttributes flags, FileAttributes testFlags) {
return ((flags & testFlags) != 0);
}
public static FileAttributes Set(
this FileAttributes flags, FileAttributes setFlags) {
return flags | setFlags;
}
public static FileAttributes Clear(
this FileAttributes flags, FileAttributes clearFlags) {
return flags & ~clearFlags;
}
public static void ForEach(this FileAttributes flags,
Action<FileAttributes> processFlag) {
if (processFlag == null) throw new ArgumentNullException("processFlag");
for (UInt32 bit = 1; bit != 0; bit <<= 1) {
UInt32 temp = ((UInt32)flags) & bit;
if (temp != 0) processFlag((FileAttributes)temp);
}
}
}
415
.
, , :
FileAttributes fa = FileAttributes.System;
fa = fa.Set(FileAttributes.ReadOnly);
fa = fa.Clear(FileAttributes.System);
fa.ForEach(f => Console.WriteLine(f));
16.
,
. Microsoft .NET (CLR)
(single-dimension), (multidimension) (jagged) .
System.Array, System.Object. ,
,
, . :
Int32[] myIntegers; //
myIntegers = new Int32[100]; // Int32 100
myIntegers,
Int32.
null, .
100 Int32; 0.
, 100
Int32 .
, , , .
myIntegers.
:
Control[] myControls; //
myControls = new Control[50]; // 50
// Control
myControls
Control. null,
.
50 Control, null. Control ,
, - .
myControls.
.16.1 ,
.
Controls :
myControls[1] = new Button();
myControls[2] = new TextBox();
myControls[3] = myControls[2]; //
417
. 16.1.
(CLS),
. , C#,
, , ,
Microsoft Visual Basic .NET. , , Microsoft
.
CLR , .
, , 0. .
, . ,
( 0) .
.
.
.
, SZ-, . , (Intermediate Language, IL),
newarr, ldelem, ldelema, ldlen stelem. , ,
. :
// Doubles
Double[,] myDoubles = new Double[10, 20];
418
16.
//
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]);
. C#
:
String[] names = new String[] { "Aidan", "Grant" };
(array initializer).
419
,
.
String.
,
var:
// :
var names = new String[] { "Aidan", "Grant" };
, names
String[], ,
(=). C#, .
new []
:
// :
var names = new[] { "Aidan", "Grant", null };
,
, ,
.
String null. ,
String.
:
//
//
var names = new[] { "Aidan", "Grant", 123 };
( CS0826:
):
error CS0826: No best type found for implicitly-typed array
, Int32
Object.
Object, Int32
, 123. ,
, ,
.
:
String[] names = { "Aidan", "Grant" };
,
. new, ,
420
16.
. , ,
:
//
var names = { "Aidan", "Grant" };
:
error CS0820: Cannot initialize an implicitly-typed local variable with
an array initializer
error CS0622: Can only use array initializer expressions to assign array types.
Try using a new expression instead
,
,
,
new. ,
, , . , new,
, , .
. (
.10.)
:
// ,
// :
var kids = new[] {new { Name="Aidan" }, new { Name="Grant" }};
// ( ):
foreach (var kid in kids)
Console.WriteLine(kid.Name);
,
( new ). ( Name String)
. ( new
). ,
.
kids, .
foreach, kid .
:
Aidan
Grant
421
CLR .
; ,
. CLR
. ,
Array.Copy,
. :
// 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,
. . Copy
:
,
Int32[] Object[].
422
16.
,
Object[] Int32[].
(widening) ,
Int32[] Double[].
,
. , ,
Object[] IFormattable[]. Object[]
IFormattable[], .
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). , . , :
oa, Object[],
String[].
5, Int32, Object.
, CLR , -
System.Array
423
Int32. ,
ArrayTypeMismatchException.
BlockCopy System.Buffer, Array.Copy. ,
, Array.Copy.
Int32 ,
. BlockCopy . ,
Byte[], ,
Char[].
.
ConstrainedCopy System.Array. ,
,
. ConstrainedCopy
(Constrained Execution Region, CER). ,
, ,
. ,
, .
System.Array
:
FileStream[] fsArray;
FileStream[] . FileStream[]
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. . . , ,
424
16.
.
SDK.
IEnumerable,
ICollection IList
,
, IEnumerable , ICollection IList .
,
System.Array. ,
System.Object.
, System.Array
, .
CLR ,
IEnumerable<T>, ICollection<T> IList<T> System.Array,
,
, .
. : 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;
425
CLR ,
fsArray .
, :
void M1(IList<FileStream> fsList) { ... }
void M2(ICollection<Stream> sCollection) { ... }
void M3(IEnumerable<Object> oEnumerable) { ... }
, , ,
,
. :
DateTime[] dtArray; //
DateTime[]
IEnumerable<DateTime>, ICollection<DateTime> IList<DateTime>;
, System.ValueType System.Object,
. , dtArray
M3 . - ( ).
,
. , .
, . ,
Array.Copy (shallow) ,
, .
, .
, ; , ,
, ,
. , .
, Array.Copy,
. ,
.
, ,
, null,
. Microsoft ,
. ,
, :
//
Appointment[] appointments = GetAppointmentsForToday();
426
16.
, :
//
Appointment[] appointments = GetAppointmentsForToday();
if (appointments != null) {
for (Int32 a = 0, a < appointments.Length; a++) {
// appointments[a]
}
}
, null
, .
. , ,
,
.
, .
CreateInstance Array.
,
, , , . ,
. , CreateInstance,
ElementType[] ( ElementType ),
.
GetValue SetValue Array.
System.Decimal. 2005 2009 , 1 4 .
. ,
, GetLowerBound
GetUpperBound System.Array:
using System;
public static class DynamicArrays {
public static void Main() {
// [2005..2009][1..4]
Int32[] lowerBounds = { 2005, 1 };
427
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();
}
}
}
:
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- ( single-dimensional, zero-based), .
.
( ):
using System;
public sealed class Program {
public static void Main() {
Array a;
//
//
428
16.
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[]"
// 1
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),
new Int32[] { 0, 0 }, new Int32[] { 1, 1 });
Console.WriteLine(a.GetType()); // "System.String[,]"
}
}
Console.WriteLine .
System.String[], ,
System.String[*] . * , CLR
. C# String[*] ,
. ,
GetValue SetValue Array,
.
, ,
: System.String[,]. CLR
. ,
System.String[*,*], CLR
*. ,
.
429
,
. . -,
(newarr, ldelem, ldelema, ldlen stelem)
JIT- . , ,
. ,
. ,
:
using System;
public static class Program {
public static void Main() {
Int32[] a = new Int32[5];
for(Int32 index = 0; index < a.Length; index++) {
// - a[index]
}
}
}
Length
for. , JIT- , Length
Array, ,
, .
.
.
JIT- , .
,
.
Length .
, JIT- ,
, Length- 1. , , .
, :
(0 >= a.GetLowerBound(0)) && ((Length 1) <= a.GetUpperBound(0))
. , ,
.
.
, .
. , ,
430
16.
.
. ,
( ).
, C# CLR
() .
. SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Char, Single,
Double, Decimal, Boolean,
.
,
. ; ,
, ,
. , , Security Permission,
Skip Verification.
,
,
:
using System;
using System.Diagnostics;
public static class Program {
private const Int32 c_numElements = 10000;
public static void Main() {
//
Int32[,] a2Dim = new Int32[c_numElements, c_numElements];
// ( )
Int32[][] aJagged = new Int32[c_numElements][];
for (Int32 x = 0; x < c_numElements; x++)
aJagged[x] = new Int32[c_numElements];
// 1: ,
Safe2DimArrayAccess(a2Dim);
// 2:
SafeJaggedArrayAccess(aJagged);
// 3:
Unsafe2DimArrayAccess(a2Dim);
}
private static Int32 Safe2DimArrayAccess(Int32[,] a) {
431
Int32 sum = 0;
for (Int32 x = 0; x < c_numElements; x++) {
for (Int32 y = 0; y < c_numElements; y++) {
sum += a[x, y];
}
}
return sum;
}
private static Int32 SafeJaggedArrayAccess(Int32[][] a) {
Int32 sum = 0;
for (Int32 x = 0; x < c_numElements; x++) {
for (Int32 y = 0; y < c_numElements; y++) {
sum += a[x][y];
}
}
return sum;
}
private static unsafe Int32 Unsafe2DimArrayAccess(Int32[,] a) {
Int32 sum = 0;
fixed (Int32* pi = a) {
for (Int32 x = 0; x < c_numElements; x++) {
Int32 baseOfDim = x * c_numElements;
for (Int32 y = 0; y < c_numElements; y++) {
sum += pi[baseOfDim + y];
}
}
}
return sum;
}
}
Unsafe2DimArrayAccess unsafe,
fixed C#.
/unsafe Allow Unsafe Code Build
Microsoft Visual Studio.
, , :
- fixed ;
,
, ,
;
- CLR
(, Microsoft
Silverlight).
432
16.
,
:
, (
);
, (
SecureString 14 , SecureStringToCoTaskMemUnicode System.
Runtime.InteropServices.Marshal);
, .
,
. stackalloc
C# ( alloca C).
.
. , , ,
FCL-. ()
. . C# /unsafe.
StackallocDemo
stackalloc:
using System;
public static class Program {
public static void Main() {
StackallocDemo();
InlineArrayDemo();
}
private static void StackallocDemo() {
unsafe {
const Int32 width = 20;
Char* pc = stackalloc Char[width]; //
//
String s = "Jeffrey Richter"; // 15
for (Int32 index = 0; index < width; index++) {
pc[width - index - 1] =
(index < s.Length) ? s[index] : '.';
}
433
// ".....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 - index - 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;
;
: Boolean, Char, SByte,
Byte, Int32, UInt32, Int64, UInt64, Single Double.
, ,
. , , , InlineArrayDemo, -
, StackallocDemo.
17.
, . Microsoft
.NET Framework (delegates).
, C++,
. ,
(
CLR). , , ,
.
qsort C
. Windows , ,
. .NET Framework
. ,
: ,
, , .
C/C++ ,
.
, , , . ,
C/C++ (
).
.NET Framework ,
Windows.
,
. ,
:
using System;
using System.Windows.Forms;
using System.IO;
// ;
435
// 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();
436
17.
fbChain +=
fbChain +=
fbChain +=
Counter(1,
fb1;
fb2;
fb3;
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) {
using (StreamWriter sw = new StreamWriter("Status", true)) {
sw.WriteLine("Item=" + value);
}
}
.
Feedback. . ,
Int32 void. typedef
C/C++, .
Program Counter.
, from to.
fb, Feedback. Counter , fb
null, ( fb).
. ,
.
437
, Counter,
.
StaticDelegateDemo .
StaticDelegateDemo Counter, fb null.
.
Counter StaticDelegateDemo Feedback.
,
, .
Program.FeedbackToConsole Feedback, ,
. new
Counter,
FeedbackToConsole. .
Counter StaticDelegateDemo
, Feedback
Program.FeedbackToMsgBox. FeedbackToMsgBox ,
,
.
. , Feedback ,
FeedbackToConsole FeedbackToMsgBox Program
. ,
( Int32) (void). FeedbackToConsole :
private static Boolean FeedbackToConsole(String value) {
...
}
FeedbackToConsole ):
438
17.
, ,
, :
String SomeMethod(Stream s);
, SomeMethod ( String),
, (Object);
. SomeMethod ( Stream)
(FileStream);
.
,
, void. , MyCallback :
Int32 SomeOtherMethod(Stream s);
, SomeOtherMethod
( Int32), ,
MyCallback ( Object), ,
Int32 . void , ,
.
,
.
,
. InstanceDelegateDemo .
, p Program
InstanceDelegateDemo. , .
Counter Feedback,
p.FeedbackToFile.
FeedbackToFile, , -
439
. Counter ,
fb, FeedbackToFile,
p
this.
FeedbackToFile FeedbackToConsole FeedbackTo
MsgBox , (
Status AppBase ).
, ,
. , .
,
. ,
.
.
C# delegate, new ,
.
.
,
.
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);
}
440
17.
, , : ,
Invoke, BeginInvoke EndInvoke. Invoke. BeginInvoke EndInvoke
.NET Framework,
. ,
27.
ILDasm.exe, ,
(17.1).
. 17.1.
Feedback,
System.MulticastDelegate Framework Class Library (
MulticastDelegate).
System.MulticastDelegate System.Delegate,
, , System.Object.
, FCL . ,
MulticastDelegate, , Delegate. , Combine Remove ( , , ).
, Delegate.
MulticastDelegate,
Delegate,
.
, internal. public,
Feedback . ,
( ), -
441
. , ,
, .
MulticastDelegate,
, .
.17.1.
17.1. MulticastDelegate
_target
System.Object
, null. ,
,
. ,
,
this
_methodPtr
System.IntPtr
,
CLR
_invocationList
System.Object
null.
( )
, :
, .
, Program.FeedbackToConsole
p.FeedbackToFile. , ,
!
, , , ,
, .
object . IntPtr (
MethodDef MemberRef), , method. object
null.
_target _methodPtr . ,
null _invocationList.
, .
, .
fbStatic fbInstance Feedback, , .17.2:
Feedback fbStatic = new Feedback(Program.FeedbackToConsole);
Feedback fbInstance = new Feedback(new Program().FeedbackToFile);
442
17.
. 17.2. ,.
, , .
Counter:
private static void Counter(Int32 from, Int32 to, Feedback fb) {
for (Int32 val = from; val <= to; val++) {
// ,
if (fb != null)
fb(val);
}
}
. if , fb null. , . , fb
, Feedback; ,
, null. , fb,
(val). .
Invoke , , fb
. ,
fb(val);
, :
fb.Invoke(val);
ILDasm.exe Counter,
, , Invoke.
IL- Counter. IL_0009
Invoke Feedback.
.method private hidebysig static void Counter(int32 from,
int32 'to',
class Feedback fb) cil managed
{
// Code size 23 (0x17)
.maxstack 2
.locals init (int32 V_0)
( )
IL_0000:
IL_0001:
IL_0002:
IL_0004:
IL_0005:
IL_0007:
IL_0008:
IL_0009:
IL_000e:
IL_000f:
IL_0010:
IL_0011:
IL_0012:
IL_0013:
IL_0014:
IL_0016:
} // end
443
ldarg.0
stloc.0
br.s IL_0012
ldarg.2
brfalse.s IL_000e
ldarg.2
ldloc.0
callvirt instance void Feedback::Invoke(int32)
ldloc.0
ldc.i4.1
add
stloc.0
ldloc.0
ldarg.1
ble.s IL_0004
ret
of method Program::Counter
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);
}
}
( )
,
. (chaining) , , . ,
,
ChainDelegateDemo1. Console.WriteLine , fb1, fb2 fb3
(.17.3).
444
17.
. 17.3. , .
fb1, fb2 fb3
Feedback, fbChain, , ,
. fbChain null
. Combine
Delegate :
fbChain = (Feedback) Delegate.Combine(fbChain, fb1);
Combine ,
null fb1.
fb1, fbChain ,
fb1. .17.4.
fb Chain
. 17.4.
( )
445
Combine:
. 17.5.
Combine:
fbChain = (Feedback) Delegate.Combine(fbChain, fb3);
, , fbChain , , .17.6. ,
_target
_methodPtr, _invocationList
. ( 0 1) , .
( 2) ,
446
17.
FeedbackToFile (
fb3). , fbChain
. ,
_invocationList, .
. 17.6.
, , fbChain
Counter:
Counter(1, 2, fbChain);
Counter Invoke
Feedback. , . Invoke
, fbChain, ,
_invocationList null.
, , ,
. : FeedbackToConsole, FeedbackToMsgBox , ,
FeedbackToFile.
Invoke Feedback (
):
( )
447
Remove
Delegate. Chain
DelegateDemo1:
fbChain = (Feedback) Delegate.Remove(
fbChain, new Feedback(FeedbackToMsgBox));
Remove ( ), , (
fbChain). , _target _methodPtr (
Feedback). ,
, _invocationList,
, .
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);
448
17.
// .
// , , C#.
}
return result;
}
result.
( ); , Invoke.
C#
, C# += -= .
Delegate.Combine Delegate.Remove .
.
ChainDelegateDemo1 ChainDelegateDemo2 (. )
IL-code. , +=
-= ChainDelegateDemo2 .
IL-
ILDasm.exe. , C# += -= Combine
Remove Delegate .
, .
Invoke ,
. , . ,
,
. . . , ,
, . , .
GetInvocationList MulticastDelegate.
:
public abstract class MulticastDelegate : Delegate {
// ,
//
public sealed override Delegate[] GetInvocationList();
}
( )
449
GetInvocationList ,
MulticastDelegate. ,
- . , ;
. _invocationList null,
, .
, , :
using System;
using System.Reflection;
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);
450
17.
getStatus += new GetStatus(new Speaker().Volume);
//
Console.WriteLine(GetComponentStatusReport(getStatus));
}
//
private static String GetComponentStatusReport(GetStatus status) {
// ,
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
451
, .NET Framework ,
Microsoft . FCL
. .
MSCorLib.dll 50. :
public
public
public
public
public
public
delegate
delegate
delegate
delegate
delegate
delegate
void
void
void
void
void
void
TryCode(Object userData);
WaitCallback(Object state);
TimerCallback(Object state);
ContextCallback(Object state);
SendOrPostCallback(Object state);
ParameterizedThreadStart(Object obj);
?
:
, Object void.
.
.NET Framework ,
(
System), ,
16:
public
public
public
public
...
public
delegate
delegate
delegate
delegate
void
void
void
void
Action(); //
Action<T>(T obj);
Action<T1, T2>(T1 arg1, T2 arg2);
Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
delegate
delegate
delegate
delegate
TResult
TResult
TResult
TResult
Func<TResult>();
Func<T, TResult>(T arg);
Func<T1, T2, TResult>(T1 arg1, T2 arg2);
Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
;
. , ,
ref out, :
delegate void Bar(ref Int32 z);
452
17.
,
params,
-.
, , ,
.
12.
- . ,
:
button1.Click += new EventHandler(button1_Click);
button1_Click , :
void button1_Click(Object sender, EventArgs e) {
// ...
}
button1_Click ,
. EventHandler ,
button1_Click. CLR,
, . .
:
button1.Click += button1_Click;
, C#
. , , IL, CLR . ,
,
C#; .
1:
, C#
, . :
453
QueueUserWorkItem ThreadPool
WaitCallback, , , SomeAsyncTask.
, ,
, WaitCallback,
. IL-,
WaitCallback, ,
.
2:
SomeAsyncTask
QueueUserWorkItem ThreadPool. C#
, . ,
:
internal sealed class AClass {
public static void CallbackWithoutNewingADelegateObject() {
ThreadPool.QueueUserWorkItem( obj => Console.WriteLine(obj ), 5);
}
}
, QueueUserWorkItem (
) !
C# - (lambda expression)
=>. - , . -,
(
AClass). (anonymous function),
, .
,
ILDasm.exe.
, <CallbackWithoutNewingADelegateObject
>b__0, , Object,
void.
, <,
C# . ,
-
454
17.
, . , C#
<, CLR .
, , - .
ILDasm.exe , C#
System.Runtime.CompilerServices.CompilerGeneratedAttribute.
, , .
, =>.
-
(,
unsafe). , , .
, -
. ,
public, protected, internal, virtual, sealed, override abstract .
C# ( ):
internal sealed class AClass {
//
// : 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);
}
- WaitCallback:
void Object. , -
455
, obj =>.
Console.WriteLine
void. void, ,
WaitCallback.
, private;
, (
). ,
.
- ( CallbackWithoutNewingADe
legateObject ). ,
. :
internal sealed class AClass {
private static String sm_name; //
public static void CallbackWithoutNewingADelegateObject() {
ThreadPool.QueueUserWorkItem(
//
obj =>Console.WriteLine(sm_name+ ": " + obj),
5);
}
}
CallbackWithoutNewingADelegateObject , .
, ,
this.
, :
internal sealed class AClass {
private String m_name; //
//
public void CallbackWithoutNewingADelegateObject() {
ThreadPool.QueueUserWorkItem(
//
obj => Console.WriteLine(m_name+ ": " + obj),
5);
}
}
, -,
=>. , :
// ,
Func<String> f = () => "Jeff";
//
456
17.
//
Func<Int32, String> f2 = (Int32 n) => n.ToString();
Func<Int32, Int32, String> f3 =
(Int32 n1, Int32 n2) => (n1 + n2).ToString();
//
//
Func<Int32, String> f4 = (n) => n.ToString();
Func<Int32, Int32, String> f5 = (n1, n2) => (n1 + n2).ToString();
// ,
Func<Int32, String> f6 = n => n.ToString();
// ref/out ref/out
Bar b = (out Int32 n) => n = 5;
, Bar :
delegate void Bar(out Int32 z);
=>.
, .
-,
Func.
. , ThreadPool.QueueUserWorkItem
-, Console.WriteLine
( void).
, . ,
return, :
Func<Int32, Int32, String> f7 = (n1, n2) => {
Int32 sum = n1 + n2; return sum.ToString(); };
, , .
,
, .
.
, .
,
-.
, .
457
C# 2.0. ( C#3.0),
. -
, ,
. , ,
, C#2.0, .
-.
3:
, .
. :
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(
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# , . -
458
17.
- / ,
, . /
, .
, ,
. ,
.
, , . ( ):
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);
}
459
//
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 { }
//
public void <UsingLocalVariablesInTheCallbackCode>b__0(Object obj) {
Int32 num = (Int32) obj;
squares[num] = num * num;
if (Interlocked.Decrement(ref numToDo) == 0)
done.Set();
}
}
}
, , . .
, , ,
.
, Visual Studio - .
:
, -.
. , -
. - ,
, :
// String
String[] names = { "Jeff", "Kristin", "Aidan", "Grant" };
// 'a'
Char charToFind = 'a';
460
17.
names = Array.FindAll(names, name => name.IndexOf(charToFind) >= 0);
//
names = Array.ConvertAll(names, name => name.ToUpper());
//
Array.ForEach(names, Console.WriteLine);
,
. , fb Feedback (.
), :
fb(item); // item Int32
, . , ,
.
, . 11 EventSet
, .
.
,
.
, System.Reflection.MethodInfo Create
Delegate ,
.
:
public abstract class MethodInfo : MethodBase {
// , .
public virtual Delegate CreateDelegate(Type delegateType);
// , ;
// target 'this'.
public virtual Delegate CreateDelegate(Type delegateType, Object target);
}
, DynamicInvoke
Delegate, :
public abstract class Delegate {
//
public Object DynamicInvoke(params Object[] args);
}
461
API (. 23)
MethodInfo , . CreateDelegate , Delegate
delegateType.
, CreateDelegate target,
,
this.
DynamicInvoke System.Delegate
, , . DynamicInvoke
, .
, ;
ArgumentException. ,
.
CreateDelegate DynamicInvoke:
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 DelegateReflection {
public static void Main(String[] args) {
if (args.Length < 2) {
String usage =
@"Usage:" +
"{0} 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}
TwoInt32s Add 123 321" +
"{0}
TwoInt32s Subtract 123 321" +
"{0}
OneString NumChars \"Hello there\"" +
"{0}
OneString Reverse \"Hello there\"";
Console.WriteLine(usage, Environment.NewLine);
return;
}
// delType
Type delType = Type.GetType(args[0]);
if (delType == null) {
Console.WriteLine("Invalid delType argument: " + args[0]);
462
17.
return;
Delegate d;
try {
// Arg1
MethodInfo mi =
typeof(DelegateReflection).GetTypeInfo().GetDeclaredMethod(args[1]);
// ,
d = mi.CreateDelegate(delType);
}
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.");
}
}
// , 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) {
return new String(s1.Reverse().ToArray());
}
}
463
18.
Microsoft .NET
Framework (custom attributes).
, .
,
.
. .NET
Framework (Windows Forms, WPF, WCF ..),
. ,
.NET Framework.
465
.
;
.
.NET Framework (FCL) , . :
DllImport CLR ,
DLL-.
Serializable , .
AssemblyVersion .
Flags .
. 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
public
public
public
public
UInt32
UInt32
UInt32
UInt32
UInt32
OSVersionInfoSize = 0;
MajorVersion = 0;
MinorVersion = 0;
BuildNumber = 0;
PlatformId = 0;
StructLayout OSVERSIONINFO,
MarshalAs CSDVersion, DllImport GetVersionEx,
In Out ver GetVersionEx. -
466
18.
. , Visual
Basic .NET (<>).
CLR ,
.
: TypeDef (, , , ),
MethodDef (), ParamDef, FieldDef, PropertyDef, EventDef, AssemblyDef
ModuleDef. , 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(
[param: SomeAttr] //
Int32 SomeParam) { return SomeParam; }
[property: SomeAttr] //
public String SomeProp {
[method: SomeAttr] // get
get { return null; }
}
[event: SomeAttr] //
[field: SomeAttr] //
[method: SomeAttr] //
//
public event EventHandler
}
,
add remove
SomeEvent;
, , , , .
467
. (CLS) System.Attribute.
C# CLS- . .NET
Framework SDK : StructLayoutAttribute, MarshalAsAttribute, DllImportAttribute,
InAttribute OutAttribute . System.
Runtime.InteropServices,
. , System.Attribute, CLS- .
Attribute,
. , [DllImport(...)]
[DllImportAttribute(...)].
, .
. ,
. ,
. . ,
DllImport GetVersionEx:
[DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true)]
, - .
DllImportAttribute , String.
"Kernel32". (positional
parameters); .
?
DllImportAttribute
. "Kernel32", CharSet
SetLastError CharSet.Auto true .
, , (named
parameters); . , DllImportAttribute.
, . , ver
GetVersionEx In Out. , . C#
;
468
18.
.
, . , ,
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-.
Attribute. ,
. ,
. FlagsAttribute
.
. , , .
,
( ) . /, ( )
. ,
.
.
. ,
, .
469
, FlagsAttribute
, . .
, System.
AttributeUsageAttribute:
namespace System {
[AttributeUsage(AttributeTargets.Enum, Inherited = false)]
public class FlagsAttribute : System.Attribute {
public FlagsAttribute() {
}
}
}
AttributeUsageAttribute . , , , ,
, . AttributeUsage
,
.
.
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) {
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; }
}
470
18.
, 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 | Class | Struct | Enum |
Constructor | Method | Property | Field | Event |
Interface | Parameter | Delegate | ReturnValue |
GenericParameter
}
AttributeUsageAttribute ,
AllowMultiple Inherited.
. ,
Flags Serializable:
[Flags][Flags]
internal enum Color {
Red
}
,
( CS0579: Flags):
error CS0579: Duplicate 'Flags' attribute
471
, FCL
ConditionalAttribute. AllowMultiple
true. .
Inherited AttributeUsageAttribute ,
, ,
.
:
[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() { }
}
DerivedType DoSomething
Tasty, TastyAttribute .
DerivedType , SerializableAttribute FCL
.
, .NET Framework
, , , , ,
. , Inherited
true. ,
.
.
AttributeUsage, CLR , . , .
AttributeUsageAttribute.
, , , .
472
18.
,
, .
, ,
. : 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' Types
//
}
}
[Some("Jeff", Color.Red, new Type[] { typeof(Math), typeof(Console) })]
internal sealed class SomeType {
}
,
, .
, .
, .
, , .
.
473
,
, . ,
. ,
, ,
.
.
.
, ,
.
15, System.Enum
Flags ToString Format. ,
Flags , .
, (reflection). 23,
.
Microsoft,
Format Enum, :
public override String ToString() {
// FlagsAttribute?
if (this.GetType().IsDefined(typeof(FlagsAttribute), false)) {
// ; ,
//
...
} else {
// ; ,
//
...
}
...
}
IsDefined Type, ,
FlagsAttribute. IsDefined
true, , FlagsAttribute ,
Format , .
.
474
18.
, , (
), . !
FCL .
System.Type IsDefined, .
, ,
. System.Reflection.CustomAttribute
Extensions. CLS- .
: IsDefined,
GetCustomAttributes GetCustomAttribute.
. , (, , , , ,
, , , ,
), . , .
.18.1.
18.1. System.Reflection.CustomAttributeExtensions,
CLS-.
IsDefined
true , Attribute,
. , ( )
GetCustomAttributes
, .
()
, .
,
. ,
AllowMultiple true,
GetCustomAttribute
.
()
, .
, null.
System.Reflection.
AmbiguousMatchException. , AllowMultiple false
475
,
IsDefined .
, , , IsDefined .
GetCustomAttributes
GetCustomAttribute.
,
.
.
.
, ,
.
, .
System.Reflection , : Assembly, Module, ParameterInfo,
MemberInfo, Type, MethodInfo, ConstructorInfo, FieldInfo, EventInfo, PropertyInfo
*Builder. IsDefined
GetCustomAttributes.
GetCustomAttributes, , , Object (Object[])
Attribute (Attribute[]). , ,
, ,
CLS. , .
.NET Framework .
, , inherit,
Attribute, Type MethodInfo.
.
, , ,
Attribute.
476
18.
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));
// ,
var members =
from m in typeof(Program).GetTypeInfo().DeclaredMembers.OfType<MethodBase>()
where m.IsPublic
select m;
foreach (MemberInfo member in members) {
// ,
ShowAttributes(member);
}
}
private static void ShowAttributes(MemberInfo attributeTarget) {
var attributes = attributeTarget.GetCustomAttributes<Attribute>();
Console.WriteLine("Attributes applied to {0}: {1}",
attributeTarget.Name, (attributes.Count() == 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)
477
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.CLSCompliantAttribute
IsCompliant=True
System.STAThreadAttribute
Attributes applied to .ctor: None
, , , . , ,
, .
System.Attribute Equals Object, . ,
false. Equals
( Equals ).
478
18.
, true.
Equals ,
.
System.Attribute Match,
.
Equals .
Equals Match (
true , )
:
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
//
//
//
if
. , ,
Match
(this.GetType() != obj.GetType()) return false;
// obj
// . ,
//
AccountsAttribute other = (AccountsAttribute) obj;
//
//
//
if
, accounts 'this'
accounts others
((other.m_accounts & m_accounts) != m_accounts)
479
return false;
return true; //
}
public override Boolean Equals(Object obj) {
// Equals
// Object,
// if (!base.Equals(obj)) return false;
//
//
//
//
if
//
//
//
if
. , ,
Equals
(this.GetType() != obj.GetType()) return false;
// obj
// . ,
//
AccountsAttribute other = (AccountsAttribute) obj;
// 'this' other
if (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 { }
public sealed class Program {
public static void Main() {
CanWriteCheck(new ChildAccount());
CanWriteCheck(new AdultAccount());
//
// , AccountsAttribute
480
18.
CanWriteCheck(new Program());
:
ChildAccount types can NOT write checks.
AdultAccount types can write checks.
Program types can NOT write checks.
,
Attribute
, . , ,
, Attribute . ,
GetCustomAttribute(s) Attribute
, . CLR
( , , ). ,
set ,
. .
System.Reflection.CustomAttributeData.
GetCustomAttributes,
. :
481
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() {
}
[CLSCompliant(true)]
[STAThread]
public static void Main() {
// ,
ShowAttributes(typeof(Program));
482
18.
//
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();
483
:
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
484
18.
,
. ,
.
. ,
Microsoft Visual Studio (FxCopCmd.exe) System.Diagnostics.
CodeAnalysis.SuppressMessageAttribute,
. ,
. ,
SuppressMessage ,
. , , ,
.
, System.Diagnostics.
ConditionalAttribute , (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.
.
19. Null-
, null;
.
. . ,
32- , FCL Int32.
, null,
.
.NET Framework, (CLR)
Int32 null.
Microsoft ADO.NET ,
null. , , System.Data.SqlTypes null- -
. , SqlDecimal 38 ,
Decimal 29. SqlString
, String.
: Java java.util.Date ,
, null. CLR
System.DateTime .
Java
- CLR, . Java null, CLR , .
, 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); // ,
//
486
19. Null-
, , null. Nullable<T> ,
, ,
C# null-
487
,
Boolean. , T Nullable
null.
, null- Int32, :
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
C# null-
x y
Nullable<Int32> . , C# null- ,
.
C# .
x y , :
Int32? x = 5;
Int32? y = null;
C# Int32? Nullable<Int32>.
, null-
. C# null- . .
private static void ConversionsAndCasting() {
// Int32 Nullable<Int32>
Int32? a = 5;
// 'null' Nullable<Int32>
Int32? b = null;
// Nullable<Int32> Int32
Int32 c = (Int32) a;
//
488
19. Null-
// null-
Double? d = 5; // Int32->Double? (d 5.0 double)
Double? e = b; // Int32?->Double? (e 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) { /* */ } else { /* */ }
(b == null) { /* */ } else { /* */ }
(a != b) { /* */ } else { /* */ }
C#:
(+++, -, --, ! , ~). null,
null.
(+, -, *, /, %, &, |, ^, <<, >>). null,
.
& | ?.
SQL.
null, ,
null, null.
, null .
,
true, false null.
(==, !=). null,
. , .
null, .
(<, >, <=, >=). null , false.
null, .
C# null-
1
2
True
False
Null
true
false
null
& = true
& = false
& = null
| = true
| = true
| = true
& = false
& = false
& = false
| = true
| = false
| = null
& = null
& = false
& = null
| = true
| = null
| = null
489
, null-
. , :
private static Int32? NullableCodeSize(Int32? a, Int32? b) {
return a + b;
}
IL-,
null-
. C#:
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());
, . , ,
8. null-
, . , Point,
== !=:
using System;
internal struct Point {
private Int32 m_x, m_y;
public Point(Int32 x, Int32 y) { m_x = x; m_y = y; }
public static Boolean operator==(Point p1, Point p2) {
490
19. Null-
return (p1.m_x == p2.m_x) && (p1.m_y == p2.m_y);
null- Point,
:
internal static
public static
Point? p1 =
Point? p2 =
class Program {
void Main() {
new Point(1, 1);
new Point(2, 2);
:
Are points equal? False
Are points not equal? True
null
C# null- (null-coalescing
operator). ?? .
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();
CLR null-
491
null-
?. ?? . -,
:
Func<String> f = () => SomeMethod() ?? "Untitled";
, ,
:
Func<String> f = () => { var temp = SomeMethod();
return temp != null ? temp : "Untitled";};
-, ?? :
String s = SomeMethod1() ?? SomeMethod2() ?? "Untitled";
, ,
:
String s;
var sm1 = SomeMethod1();
if (sm1 != null) s = sm1;
else {
var sm2 = SomeMethod2();
if (sm2 != null) s = sm2;
else s = "Untitled";
}
CLR null-
CLR null- .
, GetType
.
null- CLR.
. CLR .
null-
Nullable<Int32>,
null. ,
Object,
492
19. Null-
CLR , null-
.
Nullable<T> null
null.
CLR . , Nullable<Int32>
5 Int32 .
:
// Nullable<T> null T
Int32? n = null;
Object o = n; // o null
Console.WriteLine("o is null={0}", o == null); // "True"
n = 5;
o = n; // o Int32
Console.WriteLine("o's 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
// , null
o = null;
// "" Nullable<Int32> Int32
a = (Int32?) o; // a = null
b = (Int32) o; // NullReferenceException
GetType null-
CLR null-
493
null-
n Nullable<Int32> IComparable<Int32>. Nullable<T>
Int32 IComparable<Int32>.
, CLR , ,
.
Int32? n = 5;
Int32 result = ((IComparable) n).CompareTo(5); //
//
Console.WriteLine(result); // 0
CLR
null- .
:
Int32 result = ((IComparable) (Int32) n).CompareTo(5); //
IV
20. . .. 496
21.
() . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..554
22. CLR . .. .. .. ..606
23. . .. .. .. .. .. .. .. .. 636
24. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 666
25.
WinRT. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 698
20.
(exception handling),
. cc
. , .
, , , .
,
. ,
, . , ,
, - .
, CLR,
.
Microsoft
, , . ,
, , , ,
,
. .
, ,
. , FileStream StringBuilder. , ,
.. ( , ,
..) .
.
, Read, Write, Flush, Append, Insert, Remove
.. ,
. :
internal sealed class Account {
public static void Transfer(Account from, Account to, Decimal amount) {
from -= amount;
to += amount;
}
}
497
, 1.
, . ,
, ,
"E". , . , ,
. , - .
- , / , / ,
, ,
. -
. .NET Framework
,
(exception handling).
,
. ,
: , .
, Read .
. ,
Read, , .
C# .
498
20.
,
. , ,
. ,
,
.
C#,
, . ,
.
.NET Framework
C#. , .NET
Framework (Structured Exception
Handling, SEH) Windows. SEH ,
Windows via C/C++ (Microsoft Press,2007).
, .
. try,
catch finally.
private void SomeMethod() {
try {
// ,
//
}
catch (InvalidOperationException) {
//
// InvalidOperationException
}
catch (IOException) {
//
// IOException
}
catch {
// .
//
//
throw;
}
finally {
// ,
// , try.
//
}
499
// , finally, , try
//
// catch,
}
. .
, try
finally try catch.
.
try
try , / . finally. try
, .
catch. catch
,
. try
catch finally; , C#
.
,
try. .
try ,
, ,
try.
catch
catch , .
try catch,
. try , CLR
catch.
, finally ( , , ). finally, ,
.
catch (catch type). C# System.Exception .
catch
InvalidOperationException ( ) IOException (, ,
). ( -
500
20.
) .
catch System.Exception, ,
, , .
catch CLR ,
. ,
( ) , , System.Exception (
).
,
.
, try ( ), catch
. CLR
, . catch ,
. .
catch CLR
finally, try,
, catch .
finally catch,
.
finally ,
catch.
. :
,
;
, ;
catch .
, , . CLR
:
catch, .
501
finally ( , ,
). finally . finally , , catch.
C# , , System.
Exception. catch
(, ,
). , ,
,
. , Exception
.
finally
finally 1. try. try , finally
:
private void ReadData(String pathname) {
FileStream fs = null;
try {
fs = new FileStream(pathname, FileMode.Open);
//
}
catch (IOException) {
// IOException
}
finally {
//
if (fs != null) fs.Close();
}
}
ThreadAbortException, finally. TerminateThread FailFast System.Environment,
finally . , Windows ,
.
1
502
20.
try , . ,
finally,
.
finally,
( ).
try finally,
. finally,
catch. , try
finally.
finally, ,
. , finally
. , , try. catch finally
( ) .
, .
.
, , . ,
,
( , ).
catch finally, CLR , finally.
,
try. ( ), . CLR , .
, , .
, .
. - ,
, .
. ,
, , :
void Method() {
try {
...
}
void Method() {
try {
...
}
catch (XxxException) {
...
}
catch (YyyException) {
...
}
catch {
...; throw;
}
finally {
...
}
503
handle (XxxException) {
...
}
handle (YyyException) {
...
}
compensate {
...; throw;
}
cleanup {
...
}
CLS- CLS-
, CLR,
Exception, (Common Language Specification, CLS). , CLR
,
CLS String, Int32 DateTime.
C# , Exception,
.
, , ,
Exception. CLR2.0 catch
CLS- . C# , , CLS- ,
, .
2.0, CLR RuntimeWrappedException, System.Runtime.CompilerServices .
Exception, CLS-
. Object,
WrappedException
. CLR2.0 CLS- RuntimeWrappedException,
. CLS CLS-. ,
Exception,
, .
2.0 CLS- :
504
20.
, CLR , catch ( ),
.
CLR2.0, catch , (CS1058: catch
. System.Runtime.
CompilerServices.RuntimeWrappedException):
CS1058: A previous catch clause already catches all exceptions. All non-exceptions
thrown will be wrapped in a System.Runtime.CompilerServices.RuntimeWrappedException
.
. ( CLR
System.Runtime.CompilerServices.RuntimeWrappedException),
( CLR ).
System.Exception
505
System.Exception
CLR
Int32 String. Microsoft , . ,
System.Exception.
CLS- .
CLS- , System.
Exception. C#
CLS- .
System.Exception ,
.20.1. ,
.
- .
20.1. System.Exception
Message
String
.
,
.
, ,
Data
IDictionary
. , ,
.
Source
String
StackTrace
String
, .
TargetSite
MethodBase
506
20.
20.1 ()
HelpLink
String
(, file://C:\
MyApp\Help.htm#MyExceptionHelp).
,
InnerException
Exception
, .
null. Exception GetBaseException,
HResult
Int32
32- ,
. , COM
API HRESULT,
CLR , Exception, HRESULT
, .
,
, .
CLR,
. , Exception, StackTrace
null. ,
, null.
CLR . catch , CLR ,
. catch StackTrace
, , CLR, ,
, , ,
.
System.Exception
507
CLR . CLR .
, , CLR :
private void SomeMethod() {
try { ... }
catch (Exception e) {
...
throw e; // CLR ,
// FxCop
}
}
,
throw
. :
private void SomeMethod() {
try { ... }
catch (Exception e) {
...
throw; // CLR .
// FxCop
}
}
, , CLR,
. , Windows .
Windows
, CLR ,
.
. , ,
:
private void SomeMethod() {
Boolean trySucceeds = false;
try {
...
trySucceeds = true;
}
finally {
if (!trySucceeds) { /* */ }
}
}
508
20.
, StackTrace, ,
catch.
System.Diagnostics.StackTrace. ,
.
, StackTrace.
StackTrace. StackTrace,
, Exception.
CLR
( pdb), ,
StackTrace System.Exception ToString System.
Diagnostics.StackTrace, .
.
,
.
. -, ,
, . -, JIT-
(inline) , ,
. ( C#)
/debug. , JIT-
.
.
JIT- System.Diagnostics.
DebuggableAttribute. C# . DisableOptimizations JIT-
. C# .
/debug. System.Runtime.CompilerServices.
MethodImplAttribute, ,
. , :
using System;
using System.Runtime.CompilerServices;
internal sealed class SomeType {
[MethodImpl(MethodImplOptions.NoInlining)]
public void SomeMethod() {
...
}
}
, FCL
509
, FCL
Framework Class Library ( System.Exception). ,
MSCorLib.dll, ;
( , 23).
System.Exception
System.AggregateException
System.ApplicationException
System.Reflection.InvalidFilterCriteriaException
System.Reflection.TargetException
System.Reflection.TargetInvocationException
System.Reflection.TargetParameterCountException
System.Threading.WaitHandleCannotBeOpenedException
System.Diagnostics.Tracing.EventSourceException
System.InvalidTimeZoneException
System.IO.IsolatedStorage.IsolatedStorageException
System.Runtime.CompilerServices.RuntimeWrappedException
System.SystemException
System.Threading.AbandonedMutexException
System.AccessViolationException
System.Reflection.AmbiguousMatchException
System.AppDomainUnloadedException
System.ArgumentException
System.ArgumentNullException
System.ArgumentOutOfRangeException
System.Globalization.CultureNotFoundException
System.Text.DecoderFallbackException
System.DuplicateWaitObjectException
System.Text.EncoderFallbackException
System.ArithmeticException
System.DivideByZeroException
System.NotFiniteNumberException
System.OverflowException
System.ArrayTypeMismatchException
System.BadImageFormatException
System.CannotUnloadAppDomainException
System.ContextMarshalException
System.Security.Cryptography.CryptographicException
System.Security.Cryptography.CryptographicUnexpectedOperationException
System.DataMisalignedException
System.ExecutionEngineException
System.Runtime.InteropServices.ExternalException
System.Runtime.InteropServices.COMException
System.Runtime.InteropServices.SEHException
System.FormatException
System.Reflection.CustomAttributeFormatException
System.Security.HostProtectionException
510
20.
System.Security.Principal.IdentityNotMappedException
System.IndexOutOfRangeException
System.InsufficientExecutionStackException
System.InvalidCastException
System.Runtime.InteropServices.InvalidComObjectException
System.Runtime.InteropServices.InvalidOleVariantTypeException
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
System.Collections.Generic.KeyNotFoundException
System.Runtime.InteropServices.MarshalDirectiveException
System.MemberAccessException
System.FieldAccessException
System.MethodAccessException
System.MissingMemberException
System.MissingFieldException
System.MissingMethodException
System.Resources.MissingManifestResourceException
System.Resources.MissingSatelliteAssemblyException
System.MulticastNotSupportedException
System.NotImplementedException
System.NotSupportedException
System.PlatformNotSupportedException
System.NullReferenceException
System.OperationCanceledException
System.Threading.Tasks.TaskCanceledException
System.OutOfMemoryException
System.InsufficientMemoryException
System.Security.Policy.PolicyException
System.RankException
System.Reflection.ReflectionTypeLoadException
System.Runtime.Remoting.RemotingException
System.Runtime.Remoting.RemotingTimeoutException
System.Runtime.InteropServices.SafeArrayRankMismatchException
System.Runtime.InteropServices.SafeArrayTypeMismatchException
System.Security.SecurityException
System.Threading.SemaphoreFullException
System.Runtime.Serialization.SerializationException
System.Runtime.Remoting.ServerException
System.StackOverflowException
System.Threading.SynchronizationLockException
System.Threading.ThreadAbortException
System.Threading.ThreadInterruptedException
System.Threading.ThreadStartException
System.Threading.ThreadStateException
511
System.TimeoutException
System.TypeInitializationException
System.TypeLoadException
System.DllNotFoundException
System.EntryPointNotFoundException
System.TypeAccessException
System.TypeUnloadedException
System.UnauthorizedAccessException
System.Security.AccessControl.PrivilegeNotHeldException
System.Security.VerificationException
System.Security.XmlSyntaxException
System.Threading.Tasks.TaskSchedulerException
System.TimeZoneNotFoundException
Microsoft System.Exception
, , System.SystemException System.ApplicationException, . , , CLR, SystemException,
, ,
ApplicationException. catch, CLR-, .
; Exception (IsolatedStorage
Exception), CLR- ApplicationException
(TargetInvocationException),
SystemException (FormatException). - SystemException
ApplicationException .
Microsoft ,
, , .
,
.
.
-, , Exception
. .
, , ,
,
. ,
FCL, , . ,
System.Exception.
512
20.
, ,
. ,
,
. , System.Exception
1.
,
.
, , ,
. , .
, ,
, .
.
, .
.
, , .
-, ,
.
, . .
, ,
.
,
.
. , , ,
.
,
( , FCL- FCL-
), . ,
, ,
. Microsoft
, FCL.
System.Exception , , , .
1
513
, . , , Exception,
, ,
.
, 24, Exception<TExceptionArgs>:
[Serializable]
public sealed class Exception<TExceptionArgs> : Exception, ISerializable
where TExceptionArgs : ExceptionArgs {
private const String c_args = "Args"; // ()
private readonly TExceptionArgs m_args;
public TExceptionArgs Args { get { return m_args; } }
public Exception(String message = null, Exception innerException = null)
: this(null, message, innerException) { }
public Exception(TExceptionArgs args, String message = null,
Exception innerException = null): base(message, innerException) {
m_args = args; }
// ; ,
// .
[SecurityPermission(SecurityAction.LinkDemand,
Flags=SecurityPermissionFlag.SerializationFormatter)]
private Exception(SerializationInfo info, StreamingContext context)
: base(info, context) {
m_args = (TExceptionArgs)info.GetValue(
c_args, typeof(TExceptionArgs));
}
// ; - ISerializable
[SecurityPermission(SecurityAction.LinkDemand,
Flags=SecurityPermissionFlag.SerializationFormatter)]
public override void GetObjectData(
SerializationInfo info, StreamingContext context) {
info.AddValue(c_args, m_args);
base.GetObjectData(info, context);
}
public override String Message {
get {
String baseMsg = base.Message;
return (m_args == null) ? baseMsg : baseMsg + " (" + m_args.Message + ")";
}
}
514
20.
ExceptionArgs,
TExceptionArgs. :
[Serializable]
public abstract class ExceptionArgs {
public virtual String Message { get { return String.Empty; } }
}
, . , ,
, :
[Serializable]
public sealed class DiskFullExceptionArgs : ExceptionArgs {
private readonly String m_diskpath; // ,
//
public DiskFullExceptionArgs(String diskpath) { m_diskpath = diskpath; }
// ,
//
public String DiskPath { get { return m_diskpath; } }
// Message
public override String Message {
get {
return (m_diskpath == null) ? base.Message : "DiskPath=" + m_diskpath;
}
}
}
, :
[Serializable]
public sealed class DiskFullExceptionArgs : ExceptionArgs { }
, :
public static void TextException() {
try {
throw new Exception<DiskFullExceptionArgs>(
new DiskFullExceptionArgs(@"C:\"), "The disk is full");
515
}
catch (Exception<DiskFullExceptionArgs> e) {
Console.WriteLine(e.Message);
}
}
Exception<TExceptionArgs>.
-,
System.Exception. , ,
. -,
, Visual Studio ,
Exception<T>, .
1975 .
BASIC,
. C,
. , ,
.
,
,
.
.
( new C++ malloc, HeapAlloc, VirtualAlloc
..), , ,
. , ,
516
20.
.
- .NET Framework
.
,
catch OutOfMemoryException.
, , , CLR . , .
,
,
. .
, . ,
, ,
, .
- . , , .
, :
Boolean f = "Jeff".Substring(1, 1).ToUpper().EndsWith("E");
,
, . ,
. , Win32 COM,
true false .
, . ,
:
;
;
;
;
;
;
;
,
-;
(closure) -
;
, ;
517
518
20.
.NET Framework
1. ,
, .
, : , . , , ,
, . ,
:
private static Object OneStatement(Stream stream, Char charToFind) {
return (charToFind + ": " + stream.GetType() + String.Empty
+ (stream.Position + 512M))
.Where(c=>c == charToFind).ToArray();
}
C#,
. IL-,
C# ( ,
, ):
.method private hidebysig static object OneStatement(
class [mscorlib]System.IO.Stream stream, char charToFind) cil managed {
.maxstack 4
.locals init (
[0] class Program/<>c__DisplayClass1 V_0,
[1] object[] V_1)
IL_0000: newobj instance void Program/<>c__DisplayClass1::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: ldarg.1
IL_0008: stfld char Program/<>c__DisplayClass1::charToFind
IL_000d: ldc.i4.5
IL_000e: newarr [mscorlib]System.Object
IL_0013: stloc.1
IL_0014: ldloc.1
IL_0015: ldc.i4.0
IL_0016: ldloc.0
IL_0017: ldfld char Program/<>c__DisplayClass1::charToFind
IL_001c: box [mscorlib]System.Char
IL_0021: stelem.ref
IL_0022: ldloc.1
IL_0023: ldc.i4.1
IL_0024: ldstr ": "
IL_0029: stelem.ref
IL_002a: ldloc.1
IL_002b: ldc.i4.2
,
Visual Studio, IntelliSense, ,
, , .
, .
1
519
IL_002c: ldarg.0
IL_002d:
callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
IL_0032: stelem.ref
IL_0033: ldloc.1
IL_0034: ldc.i4.3
IL_0035: ldsfld string [mscorlib]System.String::Empty
IL_003a: stelem.ref
IL_003b: ldloc.1
IL_003c: ldc.i4.4
IL_003d: ldarg.0
IL_003e: callvirt
instance int64 [mscorlib]System.IO.Stream::get_Position()
IL_0043: call
valuetype [mscorlib]System.Decimal
[mscorlib]System.Decimal::op_Implicit(int64)
IL_0048: ldc.i4
0x200
IL_004d: newobj
instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0052: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::
op_Addition
(valuetype [mscorlib]System.Decimal,
valuetype [mscorlib]System.Decimal)
IL_0057: box [mscorlib]System.Decimal
IL_005c: stelem.ref
IL_005d: ldloc.1
IL_005e: call string [mscorlib]System.String::Concat(object[])
IL_0063: ldloc.0
IL_0064: ldftn instance bool Program/<>c__DisplayClass1::<OneStatement>b__0(char)
IL_006a: newobj instance
void [mscorlib]System.Func`2<char, bool>::.ctor(object, native int)
IL_006f: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>
[System.Core]System.Linq.Enumerable::Where<char>(
class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
class [mscorlib]System.Func`2<!!0, bool>)
IL_0074: call !!0[] [System.Core]System.Linq.Enumerable::ToArray<char>
(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)
IL_0079: ret
}
, OutOfMemoryException
<>c__DisplayClass1 ( ),
Object[], Func, char Decimal. Concat, Where ToArray.
Decimal
, TypeInitializationException1.
op_Implicit op_Addition
Decimal, ,
OverflowException.
, System.Char, System.String, System.Type
System.IO.Stream
TypeInitializationException, .
1
520
20.
Position Stream.
, , OneStatement
, ,
. , Stream Marshal
ByRefObject, stream -,
.
,
AppDomainUnloadedException.
, ,
Microsoft. ,
Microsoft ,
, OneStatement . ?
, : catch , ,
.
, , , ,
, .
, . ,
.
.
,
. ,
. ,
( ),
. , , ,
,
, System.
Exception, . , ,
.
Account, Transfer
. ,
,
. System.Exception ,
: from, to ,
. , ,
. ,
, , .
521
, Transfer
System.Exception from.
- Transfer.
,
, . , , .
,
. , ,
, , Transfer - SecurityException
OutOfMemoryException. , Win32 : true false,
. ,
. , , GetLastError. System.Exception
Source, .
String, . ,
, Source , .
, StackTrace
Exception. - ,
.
,
:
CLR
catch finally. Transfer
:
public static void Transfer(Account from, Account to, Decimal amount) {
try { /* */ }
finally {
from -= amount;
// (- Thread.Abort/AppDomain.Unload)
//
to += amount;
}
}
finally!
.
System.Diagnostics.Contracts.Contract
. -
522
20.
/
. ( ). ,
. .
(CER) CLR . , try
catch finally . , CLR catch finally,
.
( FileLoadException ,
BadImageFormatException, InvalidProgramException, FieldAccessException,
MethodAccessException, MissingFieldException MissingMethodException),
( catch) ( finally).
OutOfMemoryException .
.
,
, ,
. ,
. Windows
( NTFS),
. , .NET
Framework .
P/Invoke. System.
Transactions.TransactionScope.
. , Monitor / :
public static class SomeType {
private static Object s_myLockObject = new Object();
public static void SomeMethod () {
Monitor.Enter(s_myLockObject); //
// ? ,
// !
try {
//
}
finally {
Monitor.Exit(s_myLockObject);
}
}
// ...
}
523
-
Enter Monitor. :
public static class SomeType {
private static Object s_myLockObject = new Object();
public static void SomeMethod () {
Boolean lockTaken = false; // ,
try {
// !
Monitor.Enter(s_myLockObject, ref lockTaken);
//
}
finally {
// ,
if (lockTaken) Monitor.Exit(s_myLockObject);
}
}
// ...
}
, .
30.
, , , , .
, .
, .
, ,
Unload AppDomain ( .22).
, , , FailFast
Environment:
public static void FailFast(String message);
public static void FailFast(String message, Exception exception);
try/finally
Finalize. .
FailFast ,
CriticalFinalizerObject, 21.
, .
Windows, ,
CLR . FailFast
Windows, .
.
524
20.
FCL- . ,
FCL-, FCL- .
, CLR.
,
.
, (, ),
. Microsoft Exchange Server
,
. Extensible Storage Engine,
Windows C:\Windows\System32\EseNT.dll.
.
,
.
.
,
,
.
,
. ,
.
, .
,
, . ,
. : ,
, .
, . , ,
. , ,
.
525
. , , (.
). ,
.
, ,
.
, ,
. , , .
,
. (,
) .
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 foreach
526
20.
try/finally .
( Finalize).
try,
finally. :
lock, finally
;
using, finally
Dispose;
foreach, finally
IEnumerator Dispose;
, finally
Finalize .
, 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 21,
lock 30.
catch. , , ,
, . ,
.
.
:
try {
// , , ,
// ...
}
527
catch (Exception) {
...
}
,
.
? : , . ,
,
. , ,
, , .
,
.
, CLR . . .
, , ,
.
, , ,
.
, , , . ,
, .
, FailFast System.
Environment.
, System.Exception catch ,
. (
) System.Exception ,
, .
Microsoft FxCopCmd.exe catch (Exception),
throw.
.
, , ,
.
528
20.
(.28). ,
, , CLR
, .
EndXxx, .
EndXxx , ,
. ,
, EndXxx,
.
, . , ,
. ( ):
public String CalculateSpreadsheetCell(Int32 row, Int32 column) {
String result;
try {
result = /* */
}
catch (DivideByZeroException) {
result = " : ";
}
catch (OverflowException) {
result = " : ";
}
return result;
}
,
.
. 0, CLR
DivideByZeroException. , .
.
, CLR
OverflowException, ,
.
, , . System.Exception
( ),
, try (
OutOfMemoryException StackOverflowException).
529
, ,
. , .
10 (, -
- Serializable
). ,
? ,
. ,
,
.
:
public void SerializeObjectGraph(FileStream fs,
IFormatter formatter, Object rootObj) {
//
Int64 beforeSerialization = fs.Position;
try {
//
formatter.Serialize(fs, rootObj);
}
catch { //
//
fs.Position = beforeSerialization;
//
fs.SetLength(fs.Position);
// : finally,
//
// ,
//
throw;
}
}
. , ,
, .
, . . # :
throw , .
530
20.
,
catch, . , C# , throw
.
.
. (
).
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);
// fs
phone = /* */
}
catch (FileNotFoundException e) {
// , ,
//
throw new NameNotFoundException(name, e);
}
catch (IOException e) {
// , ,
//
throw new NameNotFoundException(name, e);
}
finally {
if (fs != null) fs.Close();
}
return phone;
}
}
( ), PhoneBook ,
, . ,
- ,
FileNotFoundException IOException,
. ,
; , ,
531
, . GetPhoneNumber
NameNotFoundException.
, . ,
, .
,
, NameNotFoundException
.
FileNotFoundException IOException,
,
PhoneBook.
, .
-, , .
, . -, . FileNotFoundException
, StackTrace ,
FileStream. NameNotFoundException, ,
catch,
. ,
.
, PhoneBook .
PhoneBookPathname,
, . ,
, GetPhoneNumber ,
, . : GetPhoneNumber,
PhoneBook. ,
PhoneBook.
.
.
, Data :
private static void SomeMethod(String filename) {
try {
// - }
catch (IOException e) {
532
20.
// IOException
e.Data.Add("Filename", filename);
throw; //
}
}
: , , CLR,
TypeInitializationException. , CLR
1. DivideByZeroException,
. , . CLR DivideByZeroException
TypeInitializationException, ,
, .
, .
CLR
TargetInvocationException .
TargetInvocationException InnerException.
, , , :
private static void Reflection(Object o) {
try {
// DoSomething
var mi = o.GetType().GetMethod("DoSomething");
mi.Invoke(o, null); // DoSomething
}
catch (System.Reflection.TargetInvocationException e) {
// CLR TargetInvocationException
throw e.InnerException; //
}
}
, .
C# ( 5),
TargetInvocationException; .
.
8.
1
533
, CLR
catch, . catch
, (unhandled
exception). , CLR
.
, ,
.
, ,
.
. ,
,
. Microsoft
CLR, . Windows .
, Event Viewer
Windows LogsApplication, 20.1.
534
20.
, .20.2, , - .
535
Reliability Monitor. .20.3,
.20.2. ,
, CLR20r3.
20.2.
01
( 32 )
02
03
04
( 64 )
05
06
07
. MethodDef ( 0x06), , . ,
ILDasm.exe
08
IL- . ,
ILDasm.exe
09
( 32 )
Windows
,
Microsoft1. Windows
Error Reporting.
Windows Quality (http://WinQual.Microsoft.com).
Microsoft . ,
, VeriSignID (
Authenticode).
,
, . CLR,
, P/Invoke
Win32 SetErrorMode SEM_NOGPFAULTERRORBOX.
1
536
20.
, , -
.
, Microsoft
.
FCL ( . ):
UnhandledException System.App
Domain. Windows Store Microsoft Silverlight
.
Windows Store UnhandledException Windows.UI.Xaml.Application.
Windows Forms OnThreadException
System.Windows.Forms.NativeWindow,
System.Windows.Forms.Application ThreadException
System.Windows.Forms.Application.
Windows Presentation Foundation (WPF)
DispatcherUnhandledException System.Windows.Application,
UnhandledException UnhandledExceptionFilter System.
Windows.Threading.Dispatcher.
Silverlight UnhandledException System.
Windows.Application.
ASP.NET Web Form Error System.Web.
UI.TemplateControl. TemplateControl System.Web.
UI.Page System.Web.UI.UserControl. , Error System.Web.HTTPApplication.
Windows Communication Foundation ErrorHandlers
System.ServiceModel.Dispatcher.ChannelDispatcher.
, ,
- -. ,
,
, . ,
. ,
( , , Microsoft SQL Server),
.
, , . ,
,
.
537
CLR , ,
(Corrupted State Exceptions, CSE).
, CLR ,
. CLR
finally .
CSE- Win32.
EXCEPTION_ACCESS_VIOLATION
EXCEPTION_STACK_OVERFLOW
EXCEPTION_ILLEGAL_INSTRUCTION
EXCEPTION_IN_PAGE_ERROR
EXCEPTION_INVALID_DISPOSITION
EXCEPTION_NONCONTINUABLE_EXCEPTION
EXCEPTION_PRIV_INSTRUCTION
STATUS_UNWIND_CONSOLIDATE
,
, ,
System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions
Attribute. , System.Security.
SecurityCriticalAttribute. ,
, legacyCorruptedStateExceptionPolicy XML- true. CLR System.Runtime.InteropServices.SEHException.
EXCEPTION_ACCESS_VIOLATION System.
AccessViolationException, EXCEPTION_STACK_OVERFLOW
System.StackOverflowException.
EnsureSufficientExecutionStack
RuntimeHelper
( ).
, InsufficientExecutionStackException,
. EnsureSufficientExecutionStack
void. .
Microsoft Visual Studio :
Exceptions Debug , .20.4.
538
20.
. 20.4. Exceptions
, Visual Studio.
Common Language Runtime Exceptions, .20.5,
, Visual Studio.
. 20.5. CLR-, ,.
Exceptions Visual Studio
, .20.6, , System.Exception.
- Thrown,
. CLR
catch. , .
, ,
, ,
, .
Thrown , ,
-
539
. ,
, ,
.
,
Add. ,
.20.7.
540
20.
,
, . , .
, - . , ? ,
true false,
? enum?
. CLR
, .
.
( HRESULT,
..). ,
, ,
, , .
, .
.
++ , . ,
. , ,
, , ,
.
,
,
. , , , , ,
.
. ,
++ ,
,
.
, .
-,
. , , , ,
, , .
541
, ,
, .
, ,
.
, ,
.NET Framework. , , JIT-
x86, , JIT- IA64 JIT-
.NET Compact Framework.
JIT- Microsoft,
. .
, ,
, .
- . ,
.
, , Windows.
.20.8 , , .NET Framework.
- ,
.
542
20.
- .
, Microsoft ,
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);
, Boolean, ,
, Int32.
result. true, result
32- . 0,
.
: TryXxx
false .
. , TryParse Int32
ArgumentException. , OutOfMemoryException,
TryParse .
, - , . ,
, , . ,
.
, , , .
,
.
, -
,
TryXxx. , , , ,
TryXxx, . ,
,
, .
543
. , , , Notepad.exe Calc.exe. ,
Microsoft Office WinWord.exe, Excel.exe Outlook.
exe - .
(, -)
. , (, SQLServer)
.
CLR AppDomain (
22). .
,
, ( ),
1.
(Constrained Execution Region, CER) , . ,
,
. ,
, . (asynchronous exceptions). ,
CLR ,
, , IL- ..
, CLR .
catch finally, . ,
:
private static void Demo1() {
try {
Console.WriteLine("In try");
}
finally {
// Type1
Type1.M();
}
}
, AppDomain
( , ASP.NET SQL- ).
, ,
.
1
544
20.
:
In try
Type1's static ctor called
, try
catch finally.
:
private static void Demo2() {
// finally
RuntimeHelpers.PrepareConstrainedRegions(); //
// System.Runtime.CompilerServices
try {
Console.WriteLine("In try");
}
finally {
// Type2
Type2.M();
}
}
public class Type2 {
static Type2() {
Console.WriteLine("Type2's static ctor called");
}
// ,
// System.Runtime.ConstrainedExecution
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static void M() { }
}
:
Type2's static ctor called
In try
PrepareConstrainedRegions .
try, JIT- catch finally. JIT- ,
,
. ,
try.
545
JIT- . ,
ReliabilityContractAttribute Consistency
WillNotCorruptState Consistency.MayCorruptInstance, ,
, CLR
. ,
PrepareConstrainedRegions catch finally
, ,
ReliabillityContractAttribute.
:
public sealed class ReliabilityContractAttribute : Attribute {
public ReliabilityContractAttribute(
Consistency consistencyGuarantee, Cer cer);
public Cer Cer { get; }
public Consistency ConsistencyGuarantee { get; }
}
1. Cer Consistency
:
enum Consistency {
MayCorruptProcess, MayCorruptAppDomain,
MayCorruptInstance, WillNotCorruptState
}
enum Cer { None, MayFail, Success }
,
Consistency.WillNotCorruptState.
.
Cer.Success.
Cer.MayFail. ,
ReliabilityContractAttribute,
:
[ReliabilityContract(Consistency.MayCorruptProcess, Cer.None)]
Cer.None , CER-
. ,
. ,
, . CLR JIT .
,
. ,
, , ,
.
1
546
20.
(, ), , , ,
JIT- ,
. RuntimeHelpers:
public static void PrepareMethod(RuntimeMethodHandle method)
public static void PrepareMethod(RuntimeMethodHandle method,
RuntimeTypeHandle[] instantiation)
public static void PrepareDelegate(Delegate d);
public static void PrepareContractedDelegate(Delegate d);
, , CLR ,
, ReliabiltyContractAttribute.
- , .
StackOverflowException. CLR (hosted)
, StackOverflowException
Environment.FailFast.
, PreparedConstrainedRegions ,
48 .
StackOverflowException try.
ExecuteCodeWithGuaranteedCleanup
RuntimeHelper,
:
try finally
, :
public delegate void TryCode(Object userData);
public delegate void CleanupCode(Object userData, Boolean exceptionThrown);
CriticalFinalizerObject, .
(code contracts)
, , .
:
547
(preconditions) ;
(postconditions)
, ;
(object invariants) ,
.
, , , 1, . ,
.
, .
System.
Diagnostics.Contracts.Contract:
public static class Contract {
// : [Conditional("CONTRACTS_FULL")]
public static void Requires(Boolean condition);
public static void EndContractBlock();
// : Always
public static void Requires<TException>(
Boolean condition) where TException : Exception;
// : [Conditional("CONTRACTS_FULL")]
public static void Ensures(Boolean condition);
public static void EnsuresOnThrow<TException>(Boolean condition)
where TException : Exception;
// : Always
public static T Result<T>();
public static T OldValue<T>(T value);
public static T ValueAtReturn<T>(out T value);
// : [Conditional("CONTRACTS_FULL")]
public static void Invariant(Boolean condition);
// : Always
public static Boolean Exists<T>(
IEnumerable<T> collection, Predicate<T> predicate);
public static Boolean Exists(
Int32 fromInclusive, Int32 toExclusive, Predicate<Int32> predicate);
public static Boolean ForAll<T>(
IEnumerable<T> collection, Predicate<T> predicate);
public static Boolean ForAll(
Int32 fromInclusive, Int32 toExclusive,
Predicate<Int32> predicate);
Pex,
Microsoft Research: http://research.microsoft.com/en-us/projects/pex/.
1
548
20.
// :
// [Conditional("CONTRACTS_FULL")] [Conditional("DEBUG")]
public static void Assert(Boolean condition);
public static void Assume(Boolean condition);
// :
public static event EventHandler<ContractFailedEventArgs> ContractFailed;
}
[Conditional("CONTRACTS_FULL")], Helper
[Conditional("DEBUG")]. , -
, ,
. Always ,
. ,
Requires, Requires<TException>, Ensures, EnsuresOnThrow, Invariant, Assert
Assume ( ),
String.
, .
, CONTRACTS_FULL.
Visual Studio, http://msdn.microsoft.com/en-us/
devlabs/dd491992.aspx. Visual Studio ,
, . DevLabs
, Visual Studio.
(.20.9).
Perform Runtime Contract
Checking
Full. CONTRACTS_FULL
( )
.
ContractFailed Contract.
, ,
ContractFailedEventArgs, :
public sealed class ContractFailedEventArgs : EventArgs {
public ContractFailedEventArgs(ContractFailureKind failureKind,
String message, String condition, Exception originalException);
public
public
public
public
ContractFailureKind FailureKind
String Message
String Condition
Exception OriginalException
{
{
{
{
get;
get;
get;
get;
}
}
}
}
549
// SetHhandled
public void SetHandled(); // Handled true,
//
public Boolean Unwind { get; } //
//
public void SetUnwind(); //
//
,
SetUnwind threw
Unwind true,
ContractException
.
. , ,
( SetHandled) .
SetHandled , ,
, , , SetUnwind.
,
System.Diagnostics.Contracts.ContractException.
MSCorLib.dll, , catch
550
20.
. -
, ,
ContractException.
SetHandled SetUnwind , .
CLR , .
CLR
( , , Windows service application),
Environment.FailFast, . Assert On Contract Failure,
, .
ContractException.
, .
public sealed class Item { /* ... */ }
public sealed class ShoppingCart {
private List<Item> m_cart
= new List<Item>();
private Decimal m_totalCost = 0;
public ShoppingCart() {
}
public void AddItem(Item item) {
AddItemHelper(m_cart, item, ref m_totalCost);
}
private static void AddItemHelper(
List<Item> m_cart, Item newItem, ref Decimal totalCost) {
// :
Contract.Requires(newItem != null);
Contract.Requires(Contract.ForAll(m_cart, s => s != newItem));
// :
Contract.Ensures(Contract.Exists(m_cart, s => s == newItem));
Contract.Ensures(totalCost >= Contract.OldValue(totalCost));
Contract.EnsuresOnThrow<IOException>(
totalCost == Contract.OldValue(totalCost));
// - ( IOException)
m_cart.Add(newItem);
totalCost += 1.00M;
}
//
[ContractInvariantMethod]
private void ObjectInvariant() {
551
AddItemHelper .
, newItem null ,
. ,
,
. ,
AddItemHelper - IOException,
totalCost ,
. ObjectInvariant , m_totalCost .
, , , .
,
. , , ,
, ,
.
. ,
. ;
, . ,
.
,
, . ,
,
. , ,
, :
Contract.Requires(true);
( ), , .
,
, , //
, .
, , .
, . ,
. . ,
552
20.
.
C# Code Contract Rewriter
( CCRewrite.exe C:\Program Files (x86)\Microsoft\Contracts\
Bin) . Perform
Runtime Contract Checking Visual Studio
. IL-
, . , , CCRewrite.
exe IL-, .
CCRewrite.exe , [Contract
InvariantMethod]. ,
ObjectInvariant private ( ).
void. , CCRewrite.exe
IL- ObjectInvariant .
, , .
Finalize Dispose IDisposable CCRewrite.exe ,
. ,
[ContractInvariantMethod]; . CCRewrite.exe IL-
, ( )
.
Assert Assume . -,
.
:
. , , Code Contract
Checker (CCCheck.exe), C# IL-
.
, , Assert, .
, Assume.
. , :
internal sealed class SomeType {
private static String s_name = "Jeffrey";
public static void ShowFirstLetter() {
Console.WriteLine(s_name[0]); // :
// : index < this.Length
}
}
. , s_name
553
, ,
s_name , .
, ShowFirstLetter :
public static void ShowFirstLetter() {
Contract.Assert(s_name.Length >= 1); // :
//
Console.WriteLine(s_name[0]);
}
, , CCCheck.exe , s_name , .
.
- ; ,
.
, Assert
Assume. , s_name,
ShowFirstLetter :
public static void ShowFirstLetter() {
Contract.Assume(s_name.Length >= 1); // !
Console.WriteLine(s_name[0]);
}
CCCheck.exe ,
s_name , .
ShowFirstLetter
.
Code Contract Reference Assembly Generator
(CCRefGen.exe). CCRewrite.exe ,
.
CCRefGen.exe,
. Visual Studio , Contract Reference Assembly Build.
.Contracts.dll (, MSCorLib.Contracts.dll) IL-.
System.Diagnostics.Contracts.ContractReferenceAssemblyAttribute.
CCRewrite.exe CCCheck.exe
.
Code Contract Document Generator (CCDocGen.
exe) XML-,
C# /doc:file. XML-, CCDocGen.exe, Sandcastle
MSDN .
21.
()
,
,
.
CLR , .
,
.
, ,
, , . . -
.
, .
:
1. , (
new C#).
2. ,
.
.
3. , ( ).
4. .
5. . .
, ,
C++. , , , ,
.
555
,
, .
, , .
, ( C# unsafe), .
, . , - ,
, , .
, , , 4 ( )
. , ,
, : ,
, .
, .
, ,
. ,
, . (
Dispose), .
, , ,
. .
, , ,
, .
CLR
(managed heap). CLR , ,
NextObjPtr. ,
,
.
CLR ,
. ,
. 32-
1,5 , 64- 8 .
C# new CLR:
1) ,
( , );
2) , . :
556
21. ()
- . 32 32,
8, 64-
64, 16;
3) , ( ).
, , ,
NextObjPtr, . ( NextObjPtr
this), new .
NextObjPtr ,
, .
. 21.1 : , .
, NextObjPtr (
).
. 21.1.
.
, ,
, . ,
FileStream BinaryWriter. BinaryWriter, FileStream.
, ,
,
. , , ,
, . , ,
, , . ,
-,
.
, , . ,
, CLR .
, ,
, .
(Garbage Collection, GC).
557
new , .
CLR .
.
0.
, ,
.
. , Microsoft COM
(Component Object Model).
, .
, ,
. 0, .
,
. ,
,
.
0, , .
- , , CLR
.
,
;
. : ,
, .
(roots).
CLR ,
.
CLR. CLR , (marking). CLR
, 0.
, . CLR
, . null,
CLR .
, .
558
21. ()
CLR ,
. , ,
.
.21.2 , , , D F. .
D ,
, H, H .
.
. 21.2.
. ,
; ,
. ,
, .
, CLR , , , , (compacting
phase). CLR ,
. .
-, ;
, ,
. -,
,
. ,
.
, ,
.
, , . , ,
CLR ,
559
. ,
, ; .
NextObjPtr
, .
. .21.3 . CLR , ,
.
. 21.3.
CLR , , ,
.
new OutOfMemoryException.
, ;
, Windows ,
, .
. -, , ,
, . -,
.
, ,
.
- ,
. , ,
, .
.
560
21. ()
,
.
. ,
:
using System;
using System.Threading;
public static class Program {
public static void Main() {
// Timer, TimerCallback
// 2000
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 ? ,
.
561
, Microsoft
.
/debug C# System.Diagnostics.DebuggableAttribute
DisableOptimizations .
JIT- , ,
. JIT , t Main .
, , , t
, Timer, t, - .
Timer , TimerCallback
Main.
, ,
C# /debug.
TimerCallback ! , /optimize+ C# ,
.
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; , -
562
21. ()
, .
Main:
public static void Main() {
// Timer, TimerCallback 2000
Timer t = new Timer(TimerCallback, null, 0, 2000);
// , Enter
Console.ReadLine();
// t ReadLine
// (t
// Dispose)
t.Dispose();
}
, ( /debug+)
( ), , TimerCallback , . ,
, t, ,
Dispose (t Dispose
this). : ,
, .
,
. Timer -
. , Timer . .
, String .
. , ,
, Timer.
, .
.
563
,
. .
. ,
0. ,
,
. 21.4 , ().
.
. 21.4. :
0,
CLR 0.
0 , . ,
0. F .
, E ,
D, B. ,
(, D), 1. 1
. ,
.21.5.
. 21.5. : 0
1, 0
0 . . .21.6,
FK.
B, H J, .
. 21.6. 0 , 1
564
21. ()
, L 0
, .
, . ,
CLR 0; CLR
1.
, , 1. 1 ,
0. , . ,
. 0, ,
, . 1,
.
, 1 .
.
, , . ,
, . ,
JIT-, .
, ( )
.
, ,
01.
, Microsoft, , 0 1. Microsoft ,
, .
JIT- ,
, (write barrier method). , , , 1 2.
(card table). 128- . ,
1 2 . -
0, .
.
( ).
, 1 2.
1
565
, ,
, . , 1 .
1,
. , 1,
, . 1 ,
. , .21.7.
. 21.7. :
0 1 ( ),.
0
, 0, ,
1. 1, , , , .
0 ,
. ,
LO. G,
L M, . , .21.8.
. 21.8. 0 , .
1
, P 0
, .
1 ,
0, 1 (B G). .21.9.
. 21.9. :
0 1 ( );.
0
566
21. ()
, 1 . , 1
, . (
) PS,
0 (.21.10).
. 21.10. 0,.
1
0 . ,
, , . 0 ,
1 ( ). 1 0.
, .21.11.
. 21.11. :
1 2, 0.
1, 0
0 1,
1 2. ,
0 : . 2 , .
, 1
,
0.
: 0, 1 2. 3
1. CLR
. CLR ,
.
,
MaxGeneration System.GC 2.
567
, 0 .
, 0 .
, 0
, 0.
, ,
. , 0
, NextObjPtr 0,
. !
,
, .
, , ,
.
. ,
. ( , ),
, .
, , .
,
.
. , ,
.
, 0
, , .
0.
,
. , , OutOfMemoryException .
, 0, 1 2.
,
.
,
.
, !
GCNotification
0 2.
, ,
. . ,
, :
568
21. ()
, CLR , ,
0 . , :
Collect System.GC. ,
. Microsoft ,
.
.
Windows . CLR Win32 CreateMemoryResourceNotification QueryMemoryResourceNotification
569
. Windows
, CLR ,
.
. CLR . 22.
CLR. CLR ( , ,
). CLR ,
; ,
CLR ,
Windows
.
, .
CLR .
. 85000
1. CLR
:
.
,
.
OutOfMemoryException. CLR
.
2,
, .
2, .
(, XML JSON)
, / ,
.
.
, -
(, ).
, ,
. 85000 .
1
570
21. ()
CLR ,
.
:
. .
, .
, ,
.
.
. ,
( ), . .
.
.
.
;
.
. (,
ASP.NET SQL Server), CLR, . , CLR .
CLR
( , , 2 3), gcServer. :
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
, CLR GC-,
IsServerGC GCSettings,
:
using System;
using System.Runtime; // GCSettings
571
, :
( ) .
,
. , 0,
, ,
. 0
1, , 2, 0 , ,
.
,
.
, ,
. ,
, ,
,
. , , , .
,
, .
, ,
.
CLR ,
, gcConcurrent
(. 2 3). :
<configuration>
<runtime>
<gcConcurrent enabled="false"/>
</runtime>
</configuration>
GC- ,
GCLatencyMode GCSettings.
GCLatencyMode. .21.1.
572
21. ()
21.1. , GCLatencyMode
Batch ( )
Interactive (
)
LowLatency
, (, ),
2 -
SustainedLowLatency
.
2 .
, .
,
LowLatency .
, , Batch Interactive. LowLatency
2,
. , GC.Collect(), 2
. , Windows
CLR ( ).
LowLatency OutOfMemory
Exception. , , ,
Batch Interactive
(.20). ,
LowLatency
. .
( Interlocked).
LowLatency:
private static void LowLatencyDemo() {
GCLatencyMode oldMode = GCSettings.LatencyMode;
573
System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
try {
GCSettings.LatencyMode = GCLatencyMode.LowLatency;
//
}
finally {
GCSettings.LatencyMode = oldMode;
}
}
System.GC .
, , , , GC.MaxGeneration.
2.
,
Collect GC. , , GCCollectionMode () () .
Collect :
void Collect(Int32 generation, GCCollectionMode mode, Boolean blocking)
GCCollectionMode .21.2.
21.2. GCCollectionMode
Default
GC.Collect .
Forced,
CLR
Forced
Optimized
,
, .
Collect: , .
CLR .
574
21. ()
.
GCCollectionMode Optimized.
Default Forced .
, Collect,
, .
Collect ,
, , .
,
. -
Windows Form, .
Collect, ; , .
( , ) ( ) . , , .
, GC RegisterForFullGCNotification.
(WaitForFullGCApproach, WaitForFullGCComplete CancelFullGCNotification)
,
. GC.Collect
, . .NET Framework
SDK. , WaitForFullGCApproach WaitForFullGCComplete
, CLR .
,
. , GC
, .
Int32 CollectionCount(Int32 generation);
Int64 GetTotalMemory(Boolean forceFullCollection);
,
, , . , , ,
. , ,
.
575
, . , , 22.
.NET Framework
,
CLR.
PerfMon.exe Windows.
, PerfMon.
exe + ;
Add Counters, .21.12.
CLR
. , , Show Description.
PerfView.
ETW (Event Tracing for Windows) .
PerfView. ,
(SOS.dll), CLR. ,
, ,
, GCHandle
576
21. ()
, , ,
, .
, , ,
. ,
, , .
, System.IO.FileStream ( ) .
Read Write . , System.Threading.
Mutex , Windows ( ),
, Mutex.
, , , ;
, , . ,
, CLR (finalization),
,
. , (,
, , . .), .
CLR , ,
, .
System.Object
Finalize. ,
, Finalize ( ).
C# Microsoft ,
( , #
). #
(~):
internal sealed class SomeType {
//
~SomeType() {
//
}
}
ILDasm.exe, , # -
577
C++ , , C# ,
C++. ,
# (destructor).
, C++,
, .
, ,
C# ,
C++. CLR ,
C# .
Finalize ,
. ,
, Finalize
.
, ,
, . ,
. , , ,
, . ,
.
, ,
Finalize, .
Finalize ,
, . , CLR
Finalize. ,
Finalize, ,
Finalize; ,
. ,
Finalize. ,
, ;
.
Finalize CLR . , -
578
21. ()
1. Finalize (,
, ),
Finalize.
, ,
. Finalize , ; .
, Finalize
.
.
, Finalize Object;
FCL. Object
, .
,
.
, , , 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;
}
// Dispose
public void Dispose() { Dispose(true); }
// Dispose
// !
protected virtual void Dispose(Boolean disposing) {
// ,
// Dispose,
// ,
// ownsHandle false,
// , ,
, CLR .
1
//
//
//
//
//
}
579
ReleaseHandle
GC.SuppressFinalize(this),
ReleaseHandle true,
,
ReleaseHandleFailed Managed Debugging Assistant (MDA)
//
// !
~SafeHandle() { Dispose(false); }
// ,
//
protected abstract Boolean ReleaseHandle();
public void SetHandleAsInvalid() {
// , ,
// GC.SuppressFinalize(this),
}
public Boolean IsClosed {
get {
// , ,
}
}
public abstract Boolean IsInvalid {
//
// true,
// ( ,
// 0 @1)
get
}
//
//
public void DangerousAddRef(ref Boolean success) {...}
public IntPtr DangerousGetHandle() {...}
public void DangerousRelease() {...}
}
SafeHandle, ,
CriticalFinalizerObject, System.
Runtime.ConstrainedExecution.
CLR , . , CLR :
, Critical
FinalizerObject, CLR JIT-, .
,
580
21. ()
, .
, ,
. CLR
; ,
. ,
,
CLR.
CLR , CriticalFinalizer
Object , ,
CriticalFinalizerObject. ,
, , CriticalFinalizerObject, . ,
FileStream
, .
CLR , CriticalFinalizer
Object, (, Microsoft SQL Server Microsoft ASP.NET). ,
.
, SafeHandle : , , SafeHandle,
, ReleaseHandle
IsInvalid get.
Windows (32- 32- , 64- 64-
). SafeHandle IntPtr
handle.
0 1. Microsoft.Win32.SafeHandles
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;
}
}
}
581
SafeWaitHandle .
:
, , .
ReleaseHandle SafeRegistryHandle Win32-
RegCloseKey.
, .NET Framework , , ,
SafeProcessHandle, SafeThreadHandle, SafeTokenHandle, SafeLibraryHandle (
ReleaseHandle Win32- FreeLibrary), SafeLocalAllocHandle ( ReleaseHandle Win32- LocalFree)
..
( ) FCL.
,
, . Microsoft ,
.
,
ILDasm.exe IL-, .
.
, SafeHandle, . ,
SafeHandle . -,
582
21. ()
, 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,
.
. CreateEventBad
( ) ,
ThreadAbortException handle.
.
.
SafeHandle .
, CreateEventGood SafeWaitHandle,
IntPtr. CreateEventGood CLR Win32-
CreateEvent. , CLR
, SafeWaitHandle SafeHandle. CLR
SafeWaitHandle,
CreateEvent . SafeWaitHandle
,
ThreadAbortException.
.
SafeWaitHandle ,
.
, , SafeHandle, ,
.
, , -
583
.
. 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.
DangerousGetHandle.
CriticalHandle, System.Runtime.InteropServices . ,
SafeHandle, . CriticalHandle ( ). SafeHandle, CriticalHandle
CriticalHandleMinusOneIsInvalid CriticalHand
leZeroOrMinusOneIsInvalid. Microsoft ,
, ,
. , CriticalHandle,
.
,
, , SafeHandle ,
. ,
. System.
IO.FileStream. FileStream ,
584
21. ()
, . 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 (
Temp.dat, ):
The process cannot access the file "Temp.dat" because it is being used by
another process
!
Write Delete, SafeFileHandle
FileStream ,
Delete.
, 99 100 .
, , IDisposable,
:
public interface IDisposable {
void Dispose();
}
585
, dispose,
. Dispose ,
. Dispose, ,
.
586
21. ()
ObjectDisposedException (
):
, , FileStream, ;
.
, IDisposable,
, System.ObjectDisposedException.
Dispose ObjectDisposedException
.
Dispose. CLR ,
. , ,
. Dispose,
, , . .
587
, , . ,
( ), .
, Dispose, -
, ObjectDisposedException.
Dispose , ,
( ).
, Dispose
. , Dispose
. ,
Dispose , ,
.
Dispose. , finally,
.
:
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);
try {
//
fs.Write(bytesToWrite, 0, bytesToWrite.Length);
}
finally {
//
if (fs != null)
fs.Dispose();
}
//
File.Delete("Temp.dat");
}
}
. , C# using,
, .
:
588
21. ()
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.
using C#
, . Using statements
C# Programmers Reference.
System.IO.FileStream
.
. .
FileStream
System.IO.StreamWriter, :
FileStream fs = new FileStream("DataFile.dat", FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
sw.Write("Hi there");
// Dispose
sw.Dispose();
589
// . StreamWriter.Dispose FileStream
// FileStream
: StreamWriter
Stream,
FileStream. StreamWriter
Stream. StreamWriter . StreamWriter
Stream.
BinaryWriter Dispose
( StreamWriter IDisposable, using C#). BinaryWriter
Stream 1.
, , , Dispose?
, , . . FileStream
, . StreamWriter
, .
, StreamWriter , .
Microsoft?
,
, . Microsoft : StreamWriter
,
FileStream. , StreamWriter, . Microsoft
,
, Dispose.
StreamWriter,
leaveOpen.
1
590
21. ()
, , , .
.
, ,
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);
591
public HandleCollector(
String name, Int32 initialThreshold, Int32 maximumThreshold);
public void Add();
public void Remove();
public
public
public
public
, ,
, . ,
, .
HandleCollector:
using System;
using System.Runtime.InteropServices;
public static class Program {
public static void Main() {
MemoryPressureDemo(0); // 0
MemoryPressureDemo(10 * 1024 * 1024); // 10 M
//
}
HandleCollectorDemo();
592
21. ()
//
GC.Collect();
593
:
MemoryPressureDemo, size=0
BigNativeResource create.
BigNativeResource create.
BigNativeResource create.
BigNativeResource create.
BigNativeResource create.
BigNativeResource create.
BigNativeResource create.
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 destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource destroy.
BigNativeResource 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.
594
21. ()
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
BigNativeResource
destroy.
destroy.
create.
create.
create.
destroy.
destroy.
create.
create.
destroy.
destroy.
destroy.
destroy.
HandleCollectorDemo
LimitedResource create. Count=1
LimitedResource create. Count=2
LimitedResource create. Count=3
LimitedResource destroy. Count=3
LimitedResource destroy. Count=2
LimitedResource destroy. Count=1
LimitedResource create. Count=1
LimitedResource create. Count=2
LimitedResource destroy. Count=2
LimitedResource create. Count=2
LimitedResource create. Count=3
LimitedResource destroy. Count=3
LimitedResource destroy. Count=2
LimitedResource destroy. Count=1
LimitedResource create. Count=1
LimitedResource create. Count=2
LimitedResource destroy. Count=2
LimitedResource create. Count=2
LimitedResource destroy. Count=1
LimitedResource destroy. Count=0
, . ,
, .
.
, new
. ,
(finalization list) ,
. ,
,
.
595
.21.13 .
, . C, E, F, I J ,
,
.
. 21.13.
System.Object , CLR .
System.Object, .
Object .
, B, E, G, H, I J .
.
,
(freachable queue)
. , .
.21.14.
, B, G H ,
. , E, I
J, , .
CLR ,
. ,
. (
) .
, ,
596
21. ()
.
, , . ,
.
:
A
E I J
. 21.14. , .
, , CLR , ,
.
,
,
.
, ,
. , f finalization, :
,
. , reachable,
, .
, , .
, , . ,
.
, , . ,
, , ,
. ,
, , .
597
,
,
.
, , , .
,
, CLR ,
.
, ,
, ,
. , , .
, , , , .
, ( ). .21.15
.
. 21.15.
CLR GC-
(GChandle table),
. .
, .
System.Runtime.InteropServices.GCHandle.
598
21. ()
// 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);
// , GCHandles
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();
,
Alloc GCHandle, ,
GCHandleType, , /
. GCHandleType :
public enum GCHandleType {
Weak = 0, //
WeakTrackResurrection = 1 //
Normal = 2, //
Pinned = 3 //
}
.
Weak . ,
, .
, , , - .
599
WeakTrackResurrection .
, ,
. , ( )
, , , .
Normal .
, (),
. , , (). Alloc,
GCHandleType, , GCHandleType.Normal.
Pinned .
, (),
. , ,
(). ,
. , ,
.
Alloc GCHandle GC ,
, . ,
GCHandleType. Alloc
GCHandle. GCHandle , IntPtr, .
GC-, GCHandle Free (
, IntPtr).
GC-.
1. (
). GC-,
Normal Pinned (
, ).
2. GC-
Weak. , () null.
3. .
, .
, .
4. GC-
WeakTrackResurrection. ( ,
600
21. ()
),
() null.
5. , ,
. ,
, ,
. Pinned ( ),
, , .
,
. Normal Pinned, .
.
Normal ,
, .
,
, . , Alloc
GCHandle Normal.
GCHandle IntPtr .
, IntPtr
GCHandle, Target, ( ).
, Free GCHandle,
( ,
).
, , .
, . Pinned
.
String Win32. String Pinned,
-
. , String , ,
String, .
P/Invoke CLR
Pinned ,
. GCHandle
Pinned -
. GCHandle .
601
, .
-.
, , . Alloc
GCHandle, Pinned.
GCHandle AddrOfPinnedObject.
IntPtr Pinned
. ,
.
,
Pinned. -
Free GCHandle,
. -
, .
.
,
fixed C#. :
unsafe public static void Go() {
// ,
for (Int32 x = 0; x < 10000; x++) new Object();
IntPtr originalMemoryAddress;
Byte[] bytes = new Byte[1000]; //
//
// Byte[]
fixed (Byte* pbytes = bytes) { originalMemoryAddress = (IntPtr) pbytes; }
//
// , Byte[]
GC.Collect();
// Byte[]
//
fixed (Byte* pbytes = bytes) {
Console.WriteLine("The Byte[] did{0} move during the GC",
(originalMemoryAddress == (IntPtr) pbytes) ? " not" : null);
}
}
fixed C# ,
GC-.
pbytes.
, null , , ,
, . C# IL-,
602
21. ()
pbytes fixed.
IL-, pbytes
null. ,
.
Weak WeakTrackResurrection ,
. Weak , ,
.
WeakTrackResurrection .
Weak ,
WeakTrackResurrection .
, A B. B A ,
, . , , A B
, .
A Alloc GCHandle, B Weak. A
GCHandle, B.
, B, . A B,
Target GCHandle.
, null, , B
. A
B . Target
null, , B , A
B. , A Free
GCHandle, GCHandle.
- GCHandle ,
System WeakReference:
public sealed class WeakReference<T> : ISerializable where T : class {
public WeakReference(T target);
public WeakReference(T target, Boolean trackResurrection);
public void SetTarget(T target);
public Boolean TryGetTarget(out T target);
}
603
; ,
GCHandle, Normal Pinned, . WeakReference<T>
. - WeakReference
GCHandle.
, ,
. : , ,
. ,
, , ,
, . . , ,
, , .
, . , , 0
. , ,
.
,
,
. , ,
, , ,
. CLR ,
. Win32- GlobalMemoryStatusEx dwMemoryLoad MEMORYSTATUSEX. , 80, ,
: , ,
.
-
. , .
System.Runtime.CompilerServices.ConditionalWeakTable<TKey,TValue>
. :
public sealed class ConditionalWeakTable<TKey, TValue>
where TKey : class where TValue : class {
public ConditionalWeakTable();
public void Add(TKey key, TValue value);
public TValue GetValue(
TKey key, CreateValueCallback<TKey, TValue> createValueCallback);
public Boolean TryGetValue(TKey key, out TValue value);
public TValue GetOrCreateValue(TKey key);
public Boolean Remove(TKey key);
604
21. ()
.
Add, key , value ,
.
Add ArgumentException.
,
. ,
,
, . , ,
.
, WeakReference
, ; , .
ConditionalWeakTable ,
, .
WeakReference,
, . ConditionalWeakTable ,
XAML.
.
, ConditionalWeakTable.
GCWatch ,
String.
:
internal static class ConditionalWeakTableDemo {
public static void Main() {
Object o = new Object().GCWatch("My Object created at " + DateTime.Now);
GC.Collect(); //
GC.KeepAlive(o); // , o,
o = null; // , o,
GC.Collect(); //
Console.ReadLine();
}
}
internal static class GCWatcher {
// . String
// - - MarshalByRefObject
private readonly static ConditionalWeakTable<Object,
NotifyWhenGCd<String>> s_cwt =
new ConditionalWeakTable<Object, NotifyWhenGCd<String>>();
private sealed class NotifyWhenGCd<T> {
private readonly T m_value;
internal NotifyWhenGCd(T value) { m_value = value; }
public override string ToString() { return m_value.ToString(); }
~NotifyWhenGCd() { Console.WriteLine("GC'd: " + m_value); }
}
public static T GCWatch<T>(this T @object, String tag) where T : class {
s_cwt.Add(@object, new NotifyWhenGCd<String>(tag));
return @object;
}
}
605
22. CLR
CLR
.NET Framework Microsoft Windows. ,
, Windows .
PE (portable executable), Windows (EXE)
(DLL).
Microsoft CLR COM-, DLL.
CLR COM-
COM- (GUID).
CLR
607
608
22. CLR
GetRuntime
ICLRRuntimeInfo, GetInterface ICLRRuntimeHost. , -
:
609
, Windows- CLR.
. .NET Framework 4.0
Windows- CLR.
CLR - 1.0,
1.1 2.0. . , Microsoft Office Outlook
,
.NET Framework.
, .NET Framework 4.0,
2.0 4.0 Windows-, ,
.NET Framework2.0 4.0, , .
.NET Framework . ,
CLR , ClrVer.exe.
Windows- CLR . AddRef
Release ICLRRuntimeHost.
, Windows .
COM- CLR (AppDomain),
. (default AppDomain),
Windows-.
, , COM , CLR .
. .
, , . ,
. ,
.
, (marshalby-reference) (marshal-by-value).
,
, .
.
. CLR . CLR
.
610
22. CLR
.
,
. , ,
.
. . ,
CLR . ,
, ,
.
Windows
. ,
.
, , Windows . , Windows
. Win32- CreateProcess ,
.
, , Windows-.
, ,
.
.22.1 Windows-,
COM- CLR, (, ,
Windows-).
, (
4). , (
, JIT-).
, . (
) : MyApp.exe, TypeLib.dll System.dll,
: Wintellect.dll System.dll.
, System.dll .
System.dll,
; , ,
. ,
, IL- JIT-,
,
.
611
Windows-
MSCorEE.dll ( )
Clr.dll ( CLR)
, , ; CLR
, . CLR .
, ,
.
. MSCorLib.dll, Microsoft.
System.Object, System.Int32 ,
.NET Framework. CLR,
.
MSCorLib.dll , .
. ,
-
: , ,
. .
612
22. CLR
, ,
.
.
,
. ,
, ,
. , , ,
,
. , .
, CLR:
private static void Marshalling() {
// ,
AppDomain adCallingThreadDomain = Thread.GetDomain();
// ,
//
String callingDomainName = adCallingThreadDomain.FriendlyName;
Console.WriteLine(
"Default AppDomain's friendly name={0}", callingDomainName);
// , Main.
String exeAssembly = Assembly.GetEntryAssembly().FullName;
Console.WriteLine("Main assembly={0}", exeAssembly);
// ,
AppDomain ad2 = null;
// 1.
//
Console.WriteLine("{0}Demo #1", Environment.NewLine);
// ( )
ad2 = AppDomain.CreateDomain("AD #2", null, null);
MarshalByRefType mbrt = null;
// ,
//
// ( )
mbrt = (MarshalByRefType)
ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");
Console.WriteLine("Type={0}", mbrt.GetType()); // CLR
//
// , -
Console.WriteLine(
613
614
22. CLR
//
try {
// ;
Console.WriteLine("Returned object created " + mbvt.ToString());
Console.WriteLine("Successful call.");
}
catch (AppDomainUnloadedException) {
Console.WriteLine("Failed call.");
}
// 3.
//
Console.WriteLine("{0}Demo #3", Environment.NewLine);
// (
// , )
ad2 = AppDomain.CreateDomain("AD #2", null, null);
// ,
//
// ( )
mbrt = (MarshalByRefType)
ad2.CreateInstanceAndUnwrap(exeAssembly, "MarshalByRefType");
// ,
//
NonMarshalableType nmt = mbrt.MethodArgAndReturn(callingDomainName);
// ...
}
//
public sealed class MarshalByRefType : MarshalByRefObject {
public MarshalByRefType() {
Console.WriteLine("{0} ctor running in {1}",
this.GetType().ToString(), Thread.GetDomain().FriendlyName);
}
public void SomeMethod() {
Console.WriteLine("Executing in " + Thread.GetDomain().FriendlyName);
}
public MarshalByValType MethodWithReturn() {
Console.WriteLine("Executing in " + Thread.GetDomain().FriendlyName);
MarshalByValType t = new MarshalByValType();
return t;
}
public NonMarshalableType MethodArgAndReturn(String callingDomainName) {
// : callingDomainName [Serializable]
Console.WriteLine("Calling from '{0}' to '{1}'.",
callingDomainName, Thread.GetDomain().FriendlyName);
615
//
[Serializable]
public sealed class MarshalByValType : Object {
private DateTime m_creationTime = DateTime.Now;
// : DateTime [Serializable]
public MarshalByValType() {
Console.WriteLine("{0} ctor running in {1}, Created on {2:D}",
this.GetType().ToString(),
Thread.GetDomain().FriendlyName,
m_creationTime);
}
//
// [Serializable]
public sealed class NonMarshalableType : Object {
public NonMarshalableType() {
Console.WriteLine("Executing in " + Thread.GetDomain().FriendlyName);
}
}
, :
Default AppDomain's friendly name= Ch22-1-AppDomains.exe
Main assembly=Ch22-1-AppDomains, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
Demo #1
MarshalByRefType ctor running in AD #2
Type=MarshalByRefType
Is proxy=True
Executing in AD #2
Failed call.
Demo #2
MarshalByRefType ctor running in AD #2
Executing in AD #2
MarshalByValType ctor running in AD #2, Created on Friday, August 07, 2009
Is proxy=False
Returned object created Friday, August 07, 2009
Returned object created Friday, August 07, 2009
Successful call.
Demo #3
MarshalByRefType ctor running in AD #2
616
22. CLR
, CLR.
Marshalling AppDomain,
,
. Windows . .
CLR, Windows .
Windows- ,
. CLR .
CLR,
, GetDomain System.Threading.Thread
, CurrentDomain
System.AppDomain.
String,
.
. CLR -
, .
Marshalling
FriendlyName System.AppDomain.
, Marshalling (
), Main,
Marshalling . : Program ,
MarshalByRefType, MarshalByValType NonMarshalableType.
.
1.
617
CreateDomain; ,
.
:
String . "AD #2".
System.Security.Policy.Evidence ,
CLR . null, , .
System.Security.PermissionSet,
( , IPermission),
PermissionSet CreateDomain, PermissionSet.
System.AppDomainSetup ,
CLR . null,
. , AppDomainSetup,
, CreateDomain
AppDomainSetup.
CreateDomain . , .
, ,
. CLR
; ,
.
, ,
, .
CreateInstanceAndUnwrap AppDomain. : String, ,
( ad2), String, ,
. CreateInstanceAndUnwrap
. (
CreateInstanceAndUnwrap)
,
(MarshalByRefType). ,
MarshalByRefType
, CreateInstanceAndUnwrap
MarshalByRefType.
618
22. CLR
CreateInstanceAndUnwrap,
.
, . CLR
(), , .
CreateInstanceAndUnwrap , , ! CreateInstanceAndUnwrap
.
, MarshalByRefType
System.MarshalByRefObject . , Create
InstanceAndUnwrap ,
MarshalB yR efO bject , CLR . ,
( ) (
CreateInstanceAndUnwrap).
-
, CLR
(proxy). , ,
(, ). ,
.
, .
,
-. ( - GCHandle, . GCHandle
21).
CreateInstanceAndUnwrap
, , - ,
-.
mbrt .
CreateInstanceAndUnwrap MarshalByRefType.
CLR , , . , -
GetType, ,
MarshalByRefType.
, , ,
CreateInstanceAndUnwrap, -.
619
IsTransparentProxy
System.Runtime.Remoting.RemotingService ,
, CreateInstanceAndUnwrap.
IsTransparentProxy true, , .
, SomeMethod.
mbrt -,
. -
.
. GCHandle
- ,
SomeMethod.
, . -, SomeMethod Thread.GetDomain().
FriendlyName. AD #2 (
), ,
AppDomain.CreateDomain AD #2 . , Call Stack
[AppDomain Transition]
(.22.2).
SomeMethod SomeMethod
, , .
620
22. CLR
,
. ,
. ,
.
.
Unload
AppDomain , CLR
.
. mbrt
-;
-
( ).
- SomeMethod,
, . ,
, , ,
SomeMethod AppDomainUnloadedException,
.
, CLR Microsoft ,
. ,
. , ,
.
.
, MarshalByRefObject, -. , , MarshalByRefObject,
JIT- , - (
), FieldGetter
FieldSetter System.Object. ;
, .
, MarshalByRefObject,
, CLR .
, , , 1.
CLR (
), FieldGetter FieldSetter .
,
.
1
621
, , :
private sealed class NonMBRO : Object
{ public Int32 x; }
private sealed class MBRO
: MarshalByRefObject { public Int32 x; }
private static void FieldAccessTiming(){
const Int32 count = 100000000;
NonMBRO nonMbro = new NonMBRO();
MBRO mbro = new MBRO();
Stopwatch sw = Stopwatch.StartNew();
for (Int32 c = 0; c < count; c++) nonMbro.x++;
Console.WriteLine("{0}", sw.Elapsed); // 00:00:00.4073560
sw = Stopwatch.StartNew();
for (Int32 c = 0; c < count; c++) mbro.x++;
Console.WriteLine("{0}", sw.Elapsed); // 00:00:02.5388665
}
NonMBRO, Object,
0,4 , MBRO,
MarshalByRefObject, 2,54 . ,
6 !
MarshalByRefObject - .
,
. ,
-,
. ,
, , .
, ,
, . ,
. ,
, .
CLR (lease manager).
, CLR 5.
, (deactivated) .
,
2 .
CLR
System.Runtime.Remoting.RemotingException.
622
22. CLR
.
. CreateInstanceAndUnwrap
MarshalByRefType.
CLR , mbrt ( ) .
MethodWithReturn.
, ,
MarshalByValType.
MarshalByValType System.MarshalByRefObject,
, CLR ;
.
MarshalByValType
[Serializable] MethodWithReturn
. , () ().
24.
( ), CLR
, . CLR
. CLR
( ), . CLR
,
. , CLR
. MethodWithReturn ;
.
CLR
(, AppBase ). CLR
. , ,
.
623
, . ,
( ), .
, , MethodWithReturn,
-, IsTrasparentProxy System.Runtime.Remoting.
RemotingService, ,
MethodWithReturn. ,
IsTrasparentProxy false, ,
, .
, ToString.
mbvt ,
. , Call Stack
: [AppDomain Transition] .
, ,
, ToString. 1 ,
, ,
, .
3.
1 2. , CreateInstanceAndUnwrap
MarshalByValType. mbrt .
MethodArgAndReturn, . CLR
, . , , MarshalByRefObject,
CLR .
[Serializable], CLR (
) ,
, MethodArgAndReturn.
System.String .
System.String MarshalByRefObject, ,
CLR . , System.String
[Serializable], CLR ,
. , String CLR
. String , CLR
624
22. CLR
; .
String,
String . 141.
MethodArgAndReturn ,
.
NonMarshalableType .
NonMarshalableType System.MarshalByRefObject
[Serializable], MethodArgAndReturn . . , MethodArgAndReturn
SerializationException.
, .
CLR
. ,
. : Unload AppDomain (
). CLR
.
1. CLR , -
.
2. CLR , . CLR ,
, ThreadAbortException (
).
finally, .
, ThreadAbortException,
CLR; , .
,
CLR .
1
, System.String .
, , String,
. CLR .
625
3. , , CLR
-,
, . , , ,
. AppDomainUnloadedException.
4. CLR , ,
.
, .
5. CLR . ,
AppDomain.Unload, ; AppDomain.Unload
.
. ,
AppDomain.Unload,
, CLR
ThreadAbortException ( ).
, AppDomain.Unload CLR 10,
. ,
AppDomain.Unload, ,
CannotUnloadAppDomainException, (
) .
, AppDomain.Unload, , CLR
, . ThreadAbortException
, .
, . CannotUnloadAppDomainException, ,
, .
626
22. CLR
- .
,
. .
,
MonitoringEnabled AppDomain true.
. ;
MonitoringEnabled false ArgumentException.
AppDomain:
MonitoringSurvivedProcessMemorySize. Int64
,
CLR.
.
MonitoringTotalAllocatedMemorySize. Int64
, .
.
MonitoringSurvivedMemorySize. Int64 ,
. .
MonitoringTotalProcessorTime. TimeSpan , .
,
:
private sealed class AppDomainMonitorDelta : IDisposable {
private AppDomain m_appDomain;
private TimeSpan m_thisADCpu;
private Int64 m_thisADMemoryInUse;
private Int64 m_thisADMemoryAllocated;
static AppDomainMonitorDelta() {
// ,
AppDomain.MonitoringIsEnabled = true;
}
public AppDomainMonitorDelta(AppDomain ad) {
m_appDomain = ad ?? AppDomain.CurrentDomain;
m_thisADCpu = m_appDomain.MonitoringTotalProcessorTime;
m_thisADMemoryInUse = m_appDomain.MonitoringSurvivedMemorySize;
627
m_thisADMemoryAllocated =
m_appDomain.MonitoringTotalAllocatedMemorySize;
AppDomainMonitorDelta:
private static void AppDomainResourceMonitoring() {
using (new AppDomainMonitorDelta(null)) {
// 10 ,
//
var list = new List<Object>();
for (Int32 x = 0; x < 1000; x++) list.Add(new Byte[10000]);
// 20 ,
//
for (Int32 x = 0; x < 2000; x++) new Byte[10000].GetType();
// 5
Int64 stop = Environment.TickCount + 5000;
while (Environment.TickCount < stop) ;
}
}
:
FriendlyName=03-Ch22-1-AppDomains.exe, CPU=5031.25ms
Allocated 30,159,496 bytes of which 10,085,080 survived GCs
, ,
CLR catch. , ,
628
22. CLR
.
; .
FirstChanceException AppDomain.
CLR :
FirstChanceException, , . CLR
catch. - ,
. , CLR
( ).
, , CLR
FirstChanceException, .
, .
, CLR .
: CLR,
CLR . ,
, , . , ,
CLR .
, NT Service, Windows Forms
Windows Presentation Foundation (WPF) (self-hosted) EXE-.
, Windows ,
CLR, (EXE-). CLR, .
, CLR .
,
, , (Main).
CLR , .
. , , CLR .
, .
629
Main Windows-
( ).
CLR
. , ,
.
- Silverlight
CLR Microsoft Silverlight
.NET Framework . Silverlight , , Silverlight CLR (CoreClr.dll) (
Internet Explorer
Windows). Silverlight . ,
Silverlight .
Silverlight (sandbox)
- .
630
22. CLR
.
JIT- , .
-, ASP.NET CLR . , . ,
Windows- -,
. -
- -.
ASP.NET -
-. , ASP.NET
, , ( ), ,
. ASP.NET ,
(shadow copying).
, ,
. , CLR. , ,
, ,
.
631
CLR.
CLR.
, .
System.AppDomainManager
CLR . ,
. , System.
AppDomainManager, .
(GAC), .
CLR ,
AppDomainManager. , AppDomainSetup AppDomainManagerAssembly AppDomainManagerType
String. AppDomainManagerAssembly
, , AppDomainManager.
AppDomainManagerType .
, AppDomainManager appDomainManagerAssembly
appDomainManagerType XML- .
ICLRControl SetAppDomainManagerType ,
GAC ,
AppDomainManager1.
, AppDomainManager.
,
. , AppDomainManager,
. ,
. , CLR ,
AppDomainManager. ,
, .
-
CLR, . ( ):
1
AppDomainManager ,
.
632
22. CLR
CLR ,
( . ).
CLR . ,
.
CLR .
, .
CLR Windows-.
,
.
CLR , .
. ,
finally .
. , , catch
finally. , (Critical Execution Region, CER), .
(escalation policy),
CLR . , SQL , CLR
.
, CLR .
, CLR .
. (critical region) . , , , , , , Monitor.
Enter, WaitOne Mutex AcquireReaderLock
AcquireWriterLock ReaderWriterLock1. AutoResetEvent,
ManualResetEvent Semaphore
, .
, CLR ,
, .
.
,
. .
.
BeginCriticalRegion EndCriticalRegion
Thread, . .
.
1
633
,
, CLR
.
, CLR
.
- . .
,
. , ,
, . , ,
. ,
, .
, , , .
?
, . , . ,
. , ?
(, ),
, .
. .22.3 -,
- .
( ).
1. .
2. .
3. ,
, ,
-.
4. try (
, MarshalByRefObject). (, ), .
5. . ,
634
22. CLR
. 22.3.
. -,
Abort Thread .
AbortRequested . -
, (safe
place). , ,
( ) . , ,
. (.21).
, , catch finally,
.
, AbortRequested
ThreadAbortException. , , finally . , , ThreadAbortException
635
. ,
, .
ThreadAbort
Exception,
. :
ThreadAbortException, ?
CLR . ThreadAbortException, CLR catch
.
CLR : CLR ThreadAbortException catch,
? catch
ResetAbort Thread. CLR
ThreadAbortException catch.
:
ThreadAbortException ResetAbort Thread?
, SecurityPermission ControlThread, true.
, ,
, , .
, - : ThreadAbortException,
catch finally, ,
. .
, CLR
, , CLR
. ,
ThreadAbortException catch - .
, catch CLR ThreadAbortException.
.
catch finally ,
- .
.
, Thread Abort: ,
Object, . ThreadAbortException,
ExceptionState, ,
. , Abort, , ThreadAbortException.
.
23.
, ,
, . , ,
, ,
-,
(add-ins), .
, , , ,
-. .
CLR
, 22.
. , , .
, , CLR,
, , ,
, , .
637
, JIT- IL- , ,
IL-. JIT-
TypeRef AssemblyRef , . AssemblyRef
. JIT- (
), , ,
(
). ,
( ,
).
CLR , Load
System.Reflection.Assembly. ,
.
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.
638
23.
Load System.AppDomain.
Assembly, ,
. ,
. , . Load
AppDomain , . :
. ,
, CLR. ,
CLR ,
.
Load AppDomain . ,
System.Assembly System.MarshalByRefObject,
. CLR .
,
FileNotFoundException. ,
Load System.AppDomain.
Load
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);
//
}
. ,
Load Assembly,
; LoadFrom. Load ,
LoadFrom , LoadFrom.
639
, ,
LoadFrom Assembly,
.
, LoadFrom URL-:
Assembly a = Assembly.LoadFrom(@"http://Wintellect.com/SomeAssembly.dll");
URL- CLR ,
.
, .
, Internet Explorer ( Work Offline ( ) File ()),
, .
UnsafeLoadFrom, -,
.
. LoadFrom Load, , CLR
, , .
, , LoadFrom .
Microsoft Visual
Studio LoadFile Assembly.
.
,
,
. LoadFile CLR ,
AssemblyResolve
.
,
( ), , ReflectionOnlyLoadFrom
, , ReflectionOnlyLoad Assembly.
:
public class Assembly {
public static Assembly ReflectionOnlyLoadFrom(String assemblyFile);
public static Assembly ReflectionOnlyLoad(String assemblyString);
//
}
640
23.
ReflectionOnlyLoadFrom , GAC -
. ReflectionOnlyLoad GAC, , ,
codeBase. Load ,
, ,
. ,
AppDomain
ApplyPolicy.
ReflectionOnlyLoadFrom ReflectionOnlyLoad
CLR - , InvalidOperationException.
,
, ,
.
,
,
ReflectionOnlyAssemblyResolve AppDomain, , (
ApplyPolicy AppDomain); CLR .
, ReflectionOnlyLoadFrom
ReflectionOnlyLoad Assembly,
.
. , CLR
. , ,
,
. CLR
,
. , ,
. . 22.
, , ReflectionOnlyLoadFrom
ReflectionOnlyLoad, . ,
. CLR , , ,
,
, .
- ,
.
EXE-, DLL-.
. EXE-.
641
DLL-,
EXE- Microsoft .NET Framework.
DLL- Visual Studio
DLL- Build Action
Embedded Resource. C# DLL EXE-, .
CLR ,
.
ResolveAssembly
. :
private static Assembly ResolveEventHandler(Object sender, ResolveEventArgs args) {
String dllName = new AssemblyName(args.Name).Name + ".dll";
var assem = Assembly.GetExecutingAssembly();
String resourceName = assem.GetManifestResourceNames().FirstOrDefault(rn =>
rn.EndsWith(dllName));
if (resourceName == null) return null;
// Not found, maybe another handler will find it
using (var stream = assem.GetManifestResourceStream(resourceName)) {
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return Assembly.Load(assemblyData);
}
}
, ,
DLL-, AssemblyResolve,
DLL-
Load,
Byte[]. DLL ,
, ,
.
, . , , .. System.Reflection ,
.
.
, ,
,
642
23.
, .
System.Reflection , ,
. ,
(.18) .
,
IL-. ,
, ILDasm.exe Microsoft.
, , CLR.
. FCL
, ,
, ,
, .
. ,
. ,
FCL (.24) , ,
.
, .
Microsoft Visual Studio , ,
- Windows Forms .
,
.
,
, ,
.
Win32- LoadLibrary GetProcAddress. , ,
(late binding) (early binding), ,
.
, ,
. .
643
. ,
. ,
int Type.GetType("int"); , null,
CLR int System.Int32.
.
,
. ,
System.Reflection.
, .
.
,
. , CLR
, . , CLR
.
/. ,
, .
, .
, ,
( )
.
, . ,
,
, ( ), , .
, , .
,
,
, , .
.
.
.
644
23.
,
, , .
FCL .
ExportedTypes Assembly. ,
:
using System;
using System.Reflection;
public static class Program {
public static void Main() {
String dataAssembly = "System.Data, version=4.0.0.0, " +
"culture=neutral, PublicKeyToken=b77a5c561934e089";
LoadAssemAndShowPublicTypes(dataAssembly);
}
private static void LoadAssemAndShowPublicTypes(String assemId) {
//
Assembly a = Assembly.Load(assemId);
// ,
//
foreach (Type t in a.ExportedTypes) {
//
Console.WriteLine(t.FullName);
}
}
}
Type
System.Type. System.
Type .
( ).
, System.Object
GetType. CLR
Type.
Type, , ,
:
private static Boolean AreObjectsTheSameType(Object o1, Object o2) {
return o1.GetType() == o2.GetType();
}
645
GetType ( ).
System.Type ReflectionOnlyGetType.
, GetType, ,
, .
System.TypeInfo DeclaredNestedTypes
GetDeclaredNestedTypes.
System.Reflection.Assembly GetType, DefinedTypes ExportedTypes.
Microsoft , ,
.
, ,
. FCL Backus-Naur
Form Grammar for Type Names. MakeArrayType,
MakeByRefType, MakeGenericType MakePointerType Type TypeInfo.
,
Type . Type
, ,
. C# typeof,
,
, :
646
23.
if , o FileInfo,
, FileInfo. , ,
.
is as C#.
, Type , .
TypeInfo, .
Type TypeInfo GetTypeInfo
System.Reflection.IntrospectionExtensions:
Type typeReference = ...; // : o.GetType() typeof(Object)
TypeInfo typeDefinition = typeReference.GetTypeInfo();
, TypeInfo
Type AsType TypeInfo.
TypeInfo typeDefinition = ...;
Type typeReference = typeDefinition.AsType();
TypeInfo CLR , , , . ,
, ( Type). TypeInfo
. , IsPublic, IsSealed, IsAbstract,
IsClass, IsValueType .., , . ( Assembly, AssemblyQualifiedName, FullName, Module .)
, , .
BaseType . ,
TypeInfo, FCL.
, Exception
- ExceptionTree ( . )
,
,
System.Exception. , , ,
, 20.
647
}
return sb;
648
23.
// .
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,
, . , Type, : ,
.
CreateInstance, ,
. -, , ,
. -, , .
-,
System.Runtime.Remoting.ObjectHandle ( System.
MarshalByRefObject).
ObjectHandle , ,
, ,
, .
, Unwrap ObjectHandle.
, .
, -
-. .
CreateInstanceFrom System.Activator. Activator
CreateInstanceFrom. CreateInstance , , .
LoadFrom (
Load) Assembly. CreateInstanceFrom
Type, ObjectHandle,
.
649
System.AppDomain. AppDomain
( ), : CreateInstance, CreateInstanceAndUnwrap, Create
IntanceFrom CreateInstanceFromAndUnwrap.
Activator , ,
, . ,
Unwrap, , .
Invoke System.Reflection.ConstructorInfo.
TypeInfo
ConstructorInfo, Invoke.
, .
.
,
( , System.Array) ( System.
MulticastDelegate ). ,
CreateInstance Array (
). CreateInstance Type, . CreateInstance
. CreateDelegate Delegate (
).
CreateDelegate Type, .
,
.
, MakeGenericType
Type, , . Type
. :
using System;
using System.Reflection;
650
23.
, :
Dictionary`2[System.String,System.Int32]
. ,
, (add-in) . ,
, ,
.
.
, , .
,
,
MSCorLib.dll. ,
. ,
(.3), .
,
. ,
. , ,
. - ,
(.3).
651
, 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.
HostSDK.dll:
using System;
using Wintellect.HostSDK;
public sealed class AddIn_A : IAddIn {
public AddIn_A() {
}
public String DoSomething(Int32 x) {
return "AddIn_A: " + x.ToString();
652
23.
( )
Host.exe. HostSDK.dll.
, ,
, dll,
, EXE- . Microsoft
MEF (Managed Extensibility Framework) ,
,
.
, MEF, .
using
using
using
using
using
System;
System.IO;
System.Reflection;
System.Collections.Generic;
Wintellect.HostSDK;
653
.
. , ,
,
. ,
, MarshalByRefObject.
MarshalByRefObject . ( ) ( ),
,
.
, ,
. ,
,
.
( ) , ;
.
,
.
,
.
ILDasm, FxCop
Windows Forms Web Forms, Visual Studio.
.
, ,
.
654
23.
, , , , . FCL System.Reflection.MemberInfo
, , . MemberInfo
,
(.23.1).
. 23.1.
,
.
, . DeclaredMembers, ,
MemberInfo;
. (, , ,
..) ( ToString).
using System;
using System.Reflection;
public static class Program {
public static void Main() {
// ,
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly a in assemblies) {
655
.
:
Assembly: mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
Type: System.Object
MethodInfo: System.String ToString()
MethodInfo: Boolean Equals(System.Object)
MethodInfo: Boolean Equals(System.Object, System.Object)
MethodInfo: Boolean ReferenceEquals(System.Object, System.Object)
MethodInfo: Int32 GetHashCode()
MethodInfo: System.Type GetType()
MethodInfo: Void Finalize()
MethodInfo: System.Object MemberwiseClone()
MethodInfo: 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.Generic.IComparer`1[T]
MethodInfo: Int32 Compare(T, T)
Type: System.Collections.IEnumerator
MethodInfo: Boolean MoveNext()
MethodInfo: System.Object get_Current()
MethodInfo: Void Reset()
PropertyInfo: System.Object Current
Type: System.IDisposable
656
23.
MemberInfo , . .23.1 ( )
MemberInfo, . , System.
Type MemberInfo, Type .
23.1. , ,
MemberInfo
Name
String
DeclaringType
Type
Module
Module
CustomAttributes
, IEnumer
able<CustomAttri
buteData>
, , .
.
Assembly MemberInfo, ,
, DeclaredMembers,
. DeclaredMembers, -
657
, TypeInfo ,
: GetDeclaredNestedType, GetDeclaredField,
GetDeclaredMethod, GetDeclaredPropert GetDeclaredEvent.
TypeInfo, FieldInfo, MethodInfo, PropertyInfo
EventInfo . GetDeclaredMethods, MethodInfo ,
.
.23.2 ,
. (AppDomain)
, , (Assembly)
, (Assembly) (Module) .
, (Type)
( , , , , ).
,
. , ,
Namespace.
FieldInfo #1
AppDomain
Assembly #1
Assembly #2
FieldInfo #2
Module #1
Module #2
Type #1
Type #2
ConstructorInfo #1
ConstructorInfo #2
MethodInfo #1
MethodInfo #2
PropertyInfo #1
PropertyInfo #2
EventInfo #1
EventInfo #2
. 23.2. ,
( ,
). , , -
/ GetParameters, ParameterInfo,
658
23.
. ReturnParameter,
ParameterInfo .
, GetGenericArguments. ,
, ,
GetCustomAttributes.
, , .
.
. .23.2 ,
.
23.2.
FieldInfo
GetValue , SetValue
ConstructorInfo
Invoke
MethodInfo
Invoke
PropertyInfo
EventInfo
AddEventHandler add,
RemoveEventHandler remove
659
MethodInfo
AddEventHandler RemoveEventHandler EventInfo.
-
. SomeType
: (m_someField), (SomeType), Int32 ,
(ToString), (SomeProp) (SomeEvent).
SomeType
SomeType.
-.
BindToMemberThenInvokeTheMember .
BindToMemberCreateDelegateToMemberThenInvokeTheMember ,
. ,
.
UseDynamicToBindAndInvokeTheMember
# dynamic (.5) .
,
,
.
.
using
using
using
using
System;
System.Reflection;
Microsoft.CSharp.RuntimeBinder;
System.Linq;
// .
// , , ,
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");
m_someField = value;
}
public event EventHandler SomeEvent;
660
23.
UseDynamicToBindAndInvokeTheMember(t);
Console.WriteLine();
661
//
EventInfo ei = obj.GetType().GetTypeInfo().GetDeclaredEvent("SomeEvent");
EventHandler eh = new EventHandler(EventCallback); // . ei.EventHandlerType
ei.AddEventHandler(obj, eh);
ei.RemoveEventHandler(obj, eh);
}
//
private static void EventCallback(Object sender, EventArgs e) { }
private static void BindToMemberCreateDelegateToMemberThenInvokeTheMember(Type t) {
Console.WriteLine("BindToMemberCreateDelegateToMemberThenInvokeTheMember");
// ( )
Object[] args = new Object[] { 12 }; //
Console.WriteLine("x before constructor called: " + args[0]);
Object obj = Activator.CreateInstance(t, args);
Console.WriteLine("Type: " + obj.GetType().ToString());
Console.WriteLine("x after constructor returns: " + args[0]);
// : .
//
MethodInfo mi = obj.GetType().GetTypeInfo().GetDeclaredMethod("ToString");
var toString = mi.CreateDelegate<Func<String>>(obj);
String s = toString();
Console.WriteLine("ToString: " + s);
//
PropertyInfo pi = obj.GetType().GetTypeInfo().GetDeclaredProperty("SomeProp");
var setSomeProp = pi.SetMethod.CreateDelegate<Action<Int32>>(obj);
try {
setSomeProp(0);
}
catch (ArgumentOutOfRangeException) {
Console.WriteLine("Property set catch.");
}
setSomeProp(2);
var getSomeProp = pi.GetMethod.CreateDelegate<Func<Int32>>(obj);
Console.WriteLine("SomeProp: " + getSomeProp());
//
EventInfo ei = obj.GetType().GetTypeInfo().GetDeclaredEvent("SomeEvent");
var addSomeEvent = ei.AddMethod.CreateDelegate<Action<EventHandler>>(obj);
addSomeEvent(EventCallback);
var removeSomeEvent =
ei.RemoveMethod.CreateDelegate<Action<EventHandler>>(obj);
removeSomeEvent(EventCallback);
}
private static void UseDynamicToBindAndInvokeTheMember(Type t) {
Console.WriteLine("UseDynamicToBindAndInvokeTheMember");
662
23.
// (dynamic )
Object[] args = new Object[] { 12 }; //
Console.WriteLine("x before constructor called: " + args[0]);
dynamic obj = Activator.CreateInstance(t, args);
Console.WriteLine("Type: " + obj.GetType().ToString());
Console.WriteLine("x after constructor returns: " + args[0]);
//
try {
obj.m_someField = 5;
Int32 v = (Int32)obj.m_someField;
Console.WriteLine("someField: " + v);
}
catch (RuntimeBinderException e) {
// ,
Console.WriteLine("Failed to access field: " + e.Message);
}
//
String s = (String)obj.ToString();
Console.WriteLine("ToString: " + s);
//
try {
obj.SomeProp = 0;
}
catch (ArgumentOutOfRangeException) {
Console.WriteLine("Property set catch.");
}
obj.SomeProp = 2;
Int32 val = (Int32)obj.SomeProp;
Console.WriteLine("SomeProp: " + val);
//
obj.SomeEvent += new EventHandler(EventCallback);
new EventHandler(EventCallback);
obj.SomeEvent =
}
}
internal static class ReflectionExtensions {
// ,
public static TDelegate CreateDelegate<TDelegate>(this MethodInfo mi,
Object target = null) {
return (TDelegate)(Object)mi.CreateDelegate(typeof(TDelegate), target);
}
}
, :
BindToMemberThenInvokeTheMember
x before constructor called: 12
Type: SomeType
x after constructor returns: 24
663
someField: 33
ToString: 33
Property set catch.
SomeProp: 2
BindToMemberCreateDelegateToMemberThenInvokeTheMember
x before constructor called: 12
Type: SomeType
x after constructor returns: 24
ToString: 0
Property set catch.
SomeProp: 2
UseDynamicToBindAndInvokeTheMember
x before constructor called: 12
Type: SomeType
x after constructor returns: 24
Failed to access field: 'SomeType.m_someField' is inaccessible due to
its protection level
ToString: 0
Property set catch.
SomeProp: 2
: SomeType
Int32. ,
Int32.
BindToMemberThenInvokeTheMember GetType Type, "System.Int32&".
(&) , .
( .
FCL). ,
MakeByRefType Type.
(
Type) (, MemberInfo), .
. , :
Type , MemberInfo, . ,
,
.
CLR
. CLR ,
. CLR
664
23.
. ,
Type - MemberInfo, ,
, . FCL
( System): RuntimeTypeHandle,
RuntimeFieldHandle RuntimeMethodHandle. IntPtr; ( ).
IntPtr , ,
.
Type MemberInfo
, . ,
.
Type RuntimeTypeHandle,
GetTypeHandle Type, Type.
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()) {
665
//
if (t.IsGenericTypeDefinition) continue;
MethodBase[] mb = t.GetMethods(c_bf);
methodInfos.AddRange(mb);
//
Console.WriteLine("# of methods={0:N0}", methodInfos.Count);
Show("After building cache of MethodInfo objects");
// RuntimeMethodHandles
// MethodInfo
List<RuntimeMethodHandle> methodHandles =
methodInfos.ConvertAll<RuntimeMethodHandle>(mb => mb.MethodHandle);
Show("Holding MethodInfo and RuntimeMethodHandle cache");
GC.KeepAlive(methodInfos); //
methodInfos = null; //
Show("After freeing MethodInfo objects");
methodInfos = methodHandles.ConvertAll<MethodBase>(
rmh=> 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");
}
}
:
Heap
# of
Heap
Heap
Heap
Heap
Heap
24.
(serialization)
. , (deserialization).
:
( )
.
ASP.NET
.
. Windows Forms Windows
Presentation Foundation (WPF).
,
.
,
. .NET Framework , . (.22).
, , .
, , .
, .
,
(, ), , , in out,
.
, .NET Framework
. , .NET Framework.
, ,
, .NET Framework.
, .NET Framework.
, , ,
. , , -
667
. , .NET Framework ,
,
. , ,
, .
CLR,
CLR ,
public, protected, internal private,
. CLR XML System.Runtime.Serialization.
NetDataContractSerializer. .NET Framework , CLR-
CLR- . System.Xml.
Serialization.XmlSerializer System.Runtime.Serialization.DataContractSerializer.
:
using
using
using
using
System;
System.Collections.Generic;
System.IO;
System.Runtime.Serialization.Formatters.Binary;
668
24.
//
MemoryStream stream = new MemoryStream();
//
BinaryFormatter formatter = new BinaryFormatter();
//
formatter.Serialize(stream, objectGraph);
//
return stream;
}
private static Object DeserializeFromMemory(Stream stream) {
//
BinaryFormatter formatter = new BinaryFormatter();
//
return formatter.Deserialize(stream);
}
}
, ! SerializeToMemory System.
IO.MemoryStream. ,
. BinaryFormatter (
System.Runtime.Serialization.Formatters.Binary). (formatter) ( System.
Runtime.Serialization.IFormatter), . FCL :
BinaryFormatter ( ) SoapFormatter
( System.Runtime.Serialization.Formatters.
Soap System.Runtime.Serialization.Formatters.
Soap.dll).
Serialize
, -, -, -, . - ,
.
, System.IO.Stream.
, MemoryStream, FileStream,
NetworkStream ..
669
Serialize :
Int32, String, DateTime, Exception, List<String>, Dictionary<Int32, DateTime>
.. , objectGraph, , ,
. , objectGraph -
, , ,
. Serialize .
, ,
.
Serialize . -
, .
. , ,
. .
SerializeToMemory
Serialize MemoryStream .
, . ,
, , ..
DeserializeFromStream -
. .
BinaryFormatter, Deserialize.
-
.
Deserialize ,
, , .
Deserialize ,
.
, () :
private static Object DeepClone(Object original) {
//
using (MemoryStream stream = new MemoryStream()) {
//
BinaryFormatter formatter = new BinaryFormatter();
// " -"
formatter.Context = new StreamingContext(StreamingContextStates.Clone);
//
670
24.
formatter.Serialize(stream, original);
//
stream.Position = 0;
//
// ( )
return formatter.Deserialize(stream);
}
}
. -,
,
. , ,
SoapFormatter, BinaryFormatter. Deserialize
, System.Runtime.Serialization.
SerializationException.
-,
. , :
[Serializable] internal sealed class Customer { /* ... */ }
[Serializable] internal sealed class Order { /* ... */ }
:
private static List<Customer> s_customers = new List<Customer>();
private static List<Order> s_pendingOrders = new List<Order>();
private static List<Order> s_processedOrders = new List<Order>();
:
private static void SaveApplicationState(Stream stream) {
//
BinaryFormatter formatter = new BinaryFormatter();
//
formatter.Serialize(stream, s_customers);
formatter.Serialize(stream, s_pendingOrders);
formatter.Serialize(stream, s_processedOrders);
}
, ,
:
private static void RestoreApplicationState(Stream stream) {
//
671
(
)
= (List<Customer>) formatter.Deserialize(stream);
= (List<Order>)
formatter.Deserialize(stream);
= (List<Order>)
formatter.Deserialize(stream);
, , .
. BinaryFormatter ,
( ), , , . ,
Load System.Reflection.Assembly (
23).
,
. , , .
,
, . ,
, , SerializationException
. , ,
.
Assembly.LoadFrom,
. .
,
Load Assembly LoadFrom. CLR
SerializationException. .
.
, ,
Assembly.LoadFrom,
, System.ResolveEventHandler,
Deserialize
AssemblyResolve System.AppDomain. ( Deserialize
, .) ,
, CLR ResolveEventHandler.
.
.
Assembly.LoadFrom,
ResolveEventHandler.
672
24.
, .
,
, ,
.
, . . , :
internal struct Point { public Int32 x, y; }
private
Point
using
new
}
, Serialize System.Runtime.
Serialization.SerializationException. , Point
, . System.SerializableAttribute,
( ,
System, System.Runtime.Serialization):
[Serializable]
internal struct Point { public Int32 x, y; }
, , Point .
,
. ,
Serialize SerializationException.
, . , ,
. , ,
SerializationException.
- . , .
, , MemoryStream.
, MemoryStream
- ( ).
673
SerializableAttribute
(), (),
() ( , ,
SerializableAttribute). .
, Person ,
Employee :
[Serializable]
internal class Person { ... }
internal class Employee : Person { ... }
SerializableAttribute
Employee:
[Serializable]
internal class Person { ... }
[Serializable]
internal class Employee : Person { ... }
.
,
SerializableAttribute , ;
,
,
. System.Object
SerializableAttribute.
. ,
. ,
, public, protected, internal private.
(, ),
.
, ,
, . , .
SerializableAttribute (, , ..) -
674
24.
1. ,
. :
, . , , Windows (, , , , , ,
..).
, Windows
.
. , , ,
.
System.
NonSerializedAttribute , ( , System, System.
Runtime.Serialization):
[Serializable]
internal class Circle {
private Double m_radius;
[NonSerialized]
private Double m_area;
Circle ,
m_radius. m_area , NonSerializedAttribute. ,
. ,
.
, Circle :
Circle c = new Circle(10);
C# , [Serializable], . , , ,
,
.
1
675
m_area , 314,159.
-
m_radius, 10. ,
Circle . m_radius 10,
m_area 0, 314,159!
, :
[Serializable]
internal class Circle {
private Double m_radius;
[NonSerialized]
private Double m_area;
public Circle(Double radius) {
m_radius = radius;
m_area = Math.PI * m_radius * m_radius;
}
[OnDeserialized]
private void OnDeserialized(StreamingContext context) {
m_area = Math.PI * m_radius * m_radius;
}
Circle System.
Runtime.Serialization.OnDeserializedAttribute1. -
. ,
.
Circle OnDeserialized
m_radius,
m_area. 314,159.
OnDeserializedAttribute
System.Runtime.Serialization
OnSerializingAttribute, OnSerializedAttribute OnDeserializingAttribute,
. ,
:
[Serializable]
public class MyType {
Int32 x, y; [NonSerialized] Int32 sum;
System.Runtime.Serialization.OnDeserialized
,
OnDeserialization System.Runtime.Serialization.
IDeserializationCallback.
1
676
24.
, , StreamingContext ( )
void. . private,
; ,
private-.
, OnSerializing.
,
OnSerialized. , OnDeserializing,
,
OnDeserialized.
, , OnDeserialized ,
.
,
OnDeserialized .
.
,
.
677
, (Hashtable Dictionary), -.
OnDeserialized. (
), (
). ,
, -.
-
. Dictionary .
,
,
SerializationException , .
,
. , System.
Runtime.Serialization.OptionalFieldAttribute.
OptionalFieldAttribute , . ,
SerializationException,
.
.
,
.
FCL
FormatterServices System.Runtime.Serialization.
.
,
SerializableAttribute:
1. GetSerializableMembers
FormatterServices:
public static MemberInfo[] GetSerializableMembers(
Type type, StreamingContext context);
(
NonSerializedAttribute) .
MemberInfo .
2. System.Reflection.MemberInfo GetObjectData FormatterServices:
public static Object[] GetObjectData(Object obj, MemberInfo[] members);
678
24.
Object,
. Object MemberInfo . Object
, MemberInfo .
3.
.
4. ,
- .
,
SerializableAttribute:
1. - . ,
( ).
SerializationException, .
,
GetTypeFromAssembly FormatterServices
:
public static Type GetTypeFromAssembly(Assembly assem, String name);
System.Type,
.
2. GetUninitializedObject
FormatterServices:
public static Object GetUninitializedObject(Type type);
, . null 0.
1. , , MemberInfo, GetSerializableMembers
FormatterServices. ,
.
2. - Object.
3. , MemberInfo, Object
PopulateObjectMembers FormatterServices:
public static Object PopulateObjectMembers(
Object obj, MemberInfo[] members, Object[] data);
,
. .
679
, OnSerializing, OnSerialized,
OnDeserializing, OnDeserialized, NonSerialized OptionalField.
, . ,
, , .
,
System.Runtime.Serialization.ISerializable,
:
public interface ISerializable {
void GetObjectData(SerializationInfo info, StreamingContext context);
}
GetObjectData .
,
.
ISerializable , , GetObjectData
. , ,
. ,
ISerializable . ,
, ,
.
ISerializable
. GetObjectData
.
, . GetObjectData
:
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter =
true)]
.
ISerializable,
System.
Runtime.Serialization.SerializationInfo,
.
680
24.
SerializationInfo GetObjectData .
GetObjectData ,
, SerializationInfo.
AddValue SerializationInfo.
, ,
AddValue.
, Dictionary<TKey,
TValue> ISerializable IDeserializationCallback, :
[Serializable]
public class Dictionary<TKey, TValue>: ISerializable,
IDeserializationCallback {
// ( )
private SerializationInfo m_siInfo; //
// ( ISerializable)
//
[SecurityPermissionAttribute(
SecurityAction.Demand, SerializationFormatter = true)]
protected Dictionary(SerializationInfo info, StreamingContext context) {
681
//
// SerializationInfo OnDeserialization
m_siInfo = info;
}
//
[SecurityCritical]
public virtual void GetObjectData(
SerializationInfo info, StreamingContext context) {
info.AddValue("Version", m_version);
info.AddValue("Comparer", m_comparer, typeof(IEqualityComparer<TKey>));
info.AddValue("HashSize", (m_ buckets == null) ? 0 : m_buckets.Length);
if (m_buckets != null) {
KeyValuePair<TKey, TValue>[] array =
new KeyValuePair<TKey, TValue>[Count];
CopyTo(array, 0);
info.AddValue(
"KeyValuePairs", array, typeof(KeyValuePair<TKey, TValue>[]));
}
}
// , /
public virtual void IDeserializationCallback.OnDeserialization(
Object sender) {
if (m_siInfo == null) return; // ,
//
Int32 num = m_siInfo.GetInt32("Version");
Int32 num2 = m_siInfo.GetInt32("HashSize");
m_comparer = (IEqualityComparer<TKey>)
m_siInfo.GetValue("Comparer", typeof(IEqualityComparer<TKey>));
if (num2 != 0) {
m_buckets = new Int32[num2];
for (Int32 i = 0; i < m_buckets.Length; i++) m_buckets[i] = -1;
m_entries = new Entry<TKey, TValue>[num2];
m_freeList = -1;
KeyValuePair<TKey, TValue>[] pairArray = (
KeyValuePair<TKey, TValue>[]) m_siInfo.GetValue(
"KeyValuePairs", typeof(KeyValuePair<TKey, TValue>[]));
if (pairArray == null)
ThrowHelper.ThrowSerializationException(
ExceptionResource.Serialization_MissingKeys);
for (Int32 j = 0; j < pairArray.Length; j++) {
if (pairArray[j].Key == null)
ThrowHelper.ThrowSerializationException(
ExceptionResource.Serialization_NullKey);
Insert(pairArray[j].Key, pairArray[j].Value, true);
}
} else { m_buckets = null; }
682
24.
m_version = num;
m_siInfo = null;
AddValue String . ,
Boolean, Char, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single,
Double, Decimal DateTime. , AddValue
Object, , String. GetObjectData
,
.
AddValue. ,
ISerializable, GetObjectData. , AddValue; ,
ISerializable, GetObjectData.
, -
, .
SerializationInfo -.
, GetObjectData :
System.Runtime.Serialization.StreamingContext. GetObjectData ,
, .
, , . .
-,
( GetUninitializedObject System.Runtime.
Serialize.FormatterServices).
0 null. ,
ISerializable.
, GetObjectData.
, sealed, private.
. protected, .
, ,
.
SerializationInfo,
, .
683
. , ,
.
Get
, AddValue .
, GetObjectData AddValue
Int32, GetInt32 .
- , ,
IFormatterConvert
-.
SerializationInfo ,
IFormatterConverter. , IFormatterConverter.
BinaryFormatter SoapFormatter Microsoft System.Runtime.Serialization.FormatterConverter.
IFormatterConverter .
FormatterConverter System.
Convert , Int32
Int64.
FormatterConverter ChangeType Convert
( ) IConvertible. . ,
, ,
IConvertible. ,
FormatterConverter
Get,
-.
Get
GetEnumerator, System.Runtime.
Serialization.SerializationInfoEnumerator ,
SerializationInfo. System.Runtime.Serialization.
SerializationEntry.
, ,
, GetObjectData ISerializable, . ISerializable,
GetObjectData
. , ISerializable,
.
684
24.
, ,
,
ISerializable . GetObjectData, , .
, . ,
.
,
, .
SerializationInfo.
, , .
(,
), OnDeserialized
OnDeserialization IDeserializationCallback ( Dictionary). .
OnDeserialized OnDeserialization
. , , ,
, OnDeserialized
IDeserializationCallback, .
,
ISerializable,
, ISerializable ,
.
.
ISerializable,
GetObjectData .
, ,
, ISerializable.
,
SerializationInfo.
.
public protected, , .
, GetObjectData
ISerializable ,
:
685
[Serializable]
internal class Base {
protected String m_name = "Jeff";
public Base() { /* */ }
}
[Serializable]
internal class Derived : Base, ISerializable {
private DateTime m_date = DateTime.Now;
public Derived() { /* */ }
// , SerializationException.
// , .
[SecurityPermissionAttribute(
SecurityAction.Demand, SerializationFormatter = true)]
private Derived(SerializationInfo info, StreamingContext context) {
//
Type baseType = this.GetType().BaseType;
MemberInfo[] mi = FormatterServices.GetSerializableMembers(
baseType, context);
//
for (Int32 i = 0; i < mi.Length; i++) {
//
FieldInfo fi = (FieldInfo)mi[i];
fi.SetValue(this, info.GetValue(
baseType.FullName + "+" + fi.Name, fi.FieldType));
}
// ,
m_date = info.GetDateTime("Date");
}
[SecurityPermissionAttribute(
SecurityAction.Demand, SerializationFormatter = true)]
public virtual void GetObjectData(
SerializationInfo info, StreamingContext context) {
//
info.AddValue("Date", m_date);
//
Type baseType = this.GetType().BaseType;
MemberInfo[] mi = FormatterServices.GetSerializableMembers(
baseType, context);
//
for (Int32 i = 0; i < mi.Length; i++) {
//
info.AddValue(baseType.FullName + "+" + mi[i].Name,
((FieldInfo)mi[i]).GetValue(this));
}
}
686
24.
Base , SerializableAttribute .
Derived,
ISerializable. ,
String m_name. AddValue SerializationInfo
.
.
, GetObjectData AddValue
m_name Base, "Base+m_name".
-
, :
, ,
.. , , , . , ,
Windows-, ,
.
,
. ,
, ,
.
StreamingContext. ,
, (.24.1).
24.1. StreamingContext
State
StreamingContextStates
,
/
Context
Object
687
StreamingContext
State / . .24.2.
24.2. StreamingContextStates
CrossProcess
0x0001
CrossMachines
0x0002
File
0x0004
.
,
Persistence
0x0008
, .
,
Remoting
0x0010
.
,
Other
0x0020
Clone
0x0040
. ,
, ,
CrossAppDomain
0x0080
All
0x00FF
, , , ,
. IFormatter ( BinaryFormatter,
SoapFormatter)
StreamingContext Context. Context, StreamingContextStates
All, null.
688
24.
Streaming
Context, StreamingContextStates, -
,
. Context
StreamingContext Serialize Deserialize.
DeepClone , ,
/
.
.NET Framework
. , , .
, :
(, System.DBNull System.Reflection.Missing)
.
(singleton).
DBNull,
.
DBNull.
(, System.Type, System.Reflection.Assembly
, MemberInfo)
, , ..
MemberInfo. ,
. . , MemberInfo,
.
.
, , CLR , CLR
, (proxy) .
,
. - , ,
.
:
689
//
[Serializable]
public sealed class Singleton : ISerializable {
//
private static readonly Singleton theOneObject = new Singleton();
//
public String Name = "Jeff";
public DateTime Date = DateTime.Now;
//
private Singleton() { }
// ,
public static Singleton GetSingleton() { return theOneObject; }
// , Singleton
// .
[SecurityPermissionAttribute(
SecurityAction.Demand, SerializationFormatter = true)]
void ISerializable.GetObjectData(
SerializationInfo info, StreamingContext context) {
info.SetType(typeof(SingletonSerializationHelper));
//
}
[Serializable]
private sealed class SingletonSerializationHelper : IObjectReference {
// , ( )
public Object GetRealObject(StreamingContext context) {
return Singleton.GetSingleton();
}
}
// . ,
//
}
Singleton ,
. ,
:
private static void SingletonSerializationTest() {
// Singleton
Singleton[] a1 = { Singleton.GetSingleton(), Singleton.GetSingleton() };
Console.WriteLine("Do both elements refer to the same object? "
+ (a1[0] == a1[1])); // "True"
using (var stream = new MemoryStream()) {
BinaryFormatter formatter = new BinaryFormatter();
//
690
24.
formatter.Serialize(stream, a1);
stream.Position = 0;
Singleton[] a2 = (Singleton[])formatter.Deserialize(stream);
// , , :
Console.WriteLine("Do both elements refer to the same object? "
+ (a2[0] == a2[1])); // "True"
Console.WriteLine("Do all elements refer to the same object? "
+ (a1[0] == a2[0])); // "True"
}
}
, .
, .
SingletonSerializationTest ,
Singleton. GetSingleton Singleton. Singleton. WriteLine
"True", , .
SingletonSerializationTest Serialize . ,
Singleton ISerializable , GetObjectData, SetType
SingletonSerializationHelper.
Singleton SingletonSerializationHelper.
AddValue , -
. , , , ,
.
SingletonSerializationTest
Deserialize . -
SingletonSerializationHelper,
( ,
Singleton , ISerializable ).
SingletonSerializationHelper, , System.Runtime.Serialization.IObjectReference.
FCL :
public interface IObjectReference {
Object GetRealObject(StreamingContext context);
}
691
GetRealObject, , .
SingletonSerializationHelper GetRealObject
Singleton.
Deserialize a2 ,
Singleton . SingletonSerializationHelper,
,
.
WriteLine "True", ,
a2 .
,
.
, . ,
. ?
,
.
.
, ,
.
,
, .
,
. , .
System.Runtime.
Serialization.ISerializationSurrogate, FCL :
public interface ISerializationSurrogate {
void GetObjectData(Object obj, SerializationInfo info,
StreamingContext context);
Object SetObjectData(Object obj, SerializationInfo info,
StreamingContext context, ISurrogateSelector selector);
}
692
24.
. ,
DateTime,
. -,
, ? , ,
.
DateTime, FCL,
, DateTime.
:
internal sealed class UniversalToLocalTimeSerializationSurrogate :
ISerializationSurrogate {
public void GetObjectData(
Object obj, SerializationInfo info, StreamingContext context) {
//
info.AddValue("Date", ((DateTime)obj).ToUniversalTime().ToString("u"));
}
public Object SetObjectData(Object obj, SerializationInfo info,
StreamingContext context, ISurrogateSelector selector) {
//
return DateTime.ParseExact(
info.GetString("Date"), "u", null).ToLocalTime();
}
}
GetObjectData
ISerializable. : , . GetObjectData
DateTime, -
, (
/)
SerializationInfo.
DateTime SetObjectData.
SerializationInfo.
,
/ DateTime
.
SetObjectData, Object, .
( GetUninitializedObject FormatterServices)
, .
0 null, .
SetObjectData ,
SerializationInfo, null.
SetObjectData
693
.
,
, SetObjectData.
UniversalToLocalTimeSerializationSurrogate
DateTime. obj
DateTime.
( ),
SetObjectData obj DateTime
.
/ DateTime ISerializationSurrogate? UniversalToLocalTimeSerializationSurrogate:
private static void SerializationSurrogateDemo() {
using (var stream = new MemoryStream()) {
// 1.
IFormatter formatter = new SoapFormatter();
// 2. SurrogateSelector
SurrogateSelector ss = new SurrogateSelector();
// 3. DateTime
ss.AddSurrogate(typeof(DateTime), formatter.Context,
new UniversalToLocalTimeSerializationSurrogate());
// . AddSurrogate
//
// 4.
formatter.SurrogateSelector = ss;
// DateTime
//
DateTime localTimeBeforeSerialize = DateTime.Now;
formatter.Serialize(stream, localTimeBeforeSerialize);
// ,
// ,
stream.Position = 0;
Console.WriteLine(new StreamReader(stream).ReadToEnd());
//
// DateTime
stream.Position = 0;
DateTime localTimeAfterDeserialize =
(DateTime)formatter.Deserialize(stream);
//
Console.WriteLine(
"LocalTimeBeforeSerialize ={0}", localTimeBeforeSerialize);
694
24.
Console.WriteLine(
"LocalTimeAfterDeserialize={0}", localTimeAfterDeserialize);
}
}
. Serialize
, SurrogateSelector. GetObjectData ISerializationSurrogate,
-.
Deserialize
SurrogateSelector, SetObjectData ISerializationSurrogate,
.
SurrogateSelector -. AddSurrogate Type StreamingContext ,
ISerializationSurrogate .
Type/StreamingContext ,
AddSurrogate ArgumentException.
StreamingContext
: DateTime, /
DateTime .
BinaryFormatter , -
.
ISerializationSurrogate GetSurrog
ateForCyclicalReference FormatterServices.
ISerializationSurrogate, AddSurrogate
SurrogateSelector. GetSurrogateForCyclicalReference
SetObjectData ,
obj,
null obj. ( ) , UniversalToLocalTimeSeriali
zationSurrogate SerializationSurrogateDemo,
.
SurrogateSelector . ,
SurrogateSelector ,
. SurrogateSelector ,
1 2.
695
, . SurrogateSelector ISurrogateSelector,
. .
ISurrogateSelector:
public interface ISurrogateSelector {
void ChainSelector(ISurrogateSelector selector);
ISurrogateSelector GetNextSelector();
ISerializationSurrogate GetSurrogate(
Type type, StreamingContext context, out ISurrogateSelector selector);
}
/
.
696
24.
. ISerializationSurrogate ,
. , ISerializationSurrogate,
.
,
. , :
. ,
, .
, .
, ,
.
.
System.Runtime.Serialization.SerializationBinder.
, SerializationBinder.
, 1.0.0.0 Ver1.
Ver1ToVer2SerializationBinder
Ver2:
internal sealed class Ver1ToVer2SerializationBinder : SerializationBinder {
public override Type BindToType(String assemblyName, String typeName) {
// Ver1 1.0.0.0 Ver2
// , Ver1
AssemblyName assemVer1 = Assembly.GetExecutingAssembly().GetName();
assemVer1.Version = new Version(1, 0, 0, 0);
// Ver1 v1.0.0.0 Ver2
if (assemblyName == assemVer1.ToString() && typeName == "Ver1")
return typeof(Ver2);
//
return Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));
}
}
Ver1
ToVer2SerializationBinder
Binder . Deserialize.
BindToType,
697
, . BindToType
, , .
SerializationBinder / BindToName.
:
public virtual void BindToName(Type serializedType,
out string assemblyName, out string typeName)
, , .
( out) , .
null null (
), .
25.
WinRT
WinRT
DirectX XAML
C/C++
CRT
XAML
C#/VB
699
FCL
JS
WinJS
Chakra
CLR
Windows 8
WinRT
XAML
. 25.1. WinRT ,.
Microsoft
700
25. WinRT
Windows.*.winmd, %WinDir%\System32\WinMetadata.
Windows.winmd,
Windows SDK:
%ProgramFiles(x86)%\Windows Kits\8.0\References\CommonConiguration\Neutral\Windows.
winmd
Windows Runtime , , ,
, , .
WinRT . .NET Framework :
CLR CLR ( , ).
WinRT , CLR
.NET Framework.
.NET Framework API, FCL. .NET
Framework ,
WinRT CLR
CLR. .NET Framework .
CLR
WinRT
WinRT , CLR.
CLR WinRT,
CLR.
CLR WinRT .
CLR ( ),
FCL. WinRT, CLR
FCL, http://msdn.microsoft.com/
en-us/library/windows/apps/hh995050.aspx.
WinRT
WinRT CLR.
WinRT CLR.
. .winmd , WinRT. -
CLR WinRT
701
, Wintellect.WindowsStore.winmd
WinRT, Wintellect.WindowsStore
. Windows , , ,
. , WinRT
.
. WinRT .
CLR WinRT, , WinRT
System.Object; WinRT
, ToString, GetHashCode, Equals GetType.
WinRT C# System.Object,
WinRT . , ToString.
. WinRT
: , , 16-, 32 64-
, , 16-
, void1. , CLR,
.
. WinRT -; , WinRT ,
2. (, JavaScript)
, WinRT , , .
WinRT, , JavaScript.
WinRT, Windows, XAML ( ).
, JavaScript,
HTML CSS.
. WinRT ( ),
(interoperability
boundary) COM. CLR, WinRT
,
( WinRT)3. , WinRT
. CLR
WinRT
CLR, .
WinRT .
, WinRT
.
3
, 32-
.
1
2
702
25. WinRT
CLR.
Point, Rect, Size TimeSpan,
Windows.Foundation.
Null- . WinRT API
null- ( ). CLR WinRT
Windows.Foundation.IReference<T> CLR System.Nullable<T>.
.
32- . C#, int uint. , 32- ,
.
.
WinRT WinRT- .
. WinRT . ,
JavaScript , , . , JavaScript
, .
JavaScript .
, WinRT
.
. WinRT
WinRT- . WinRT
, .
. WinRT
WinRT- .
WinRT CCW
, CCW WinRT. WinRT BeginInvoke
EndInvoke.
. WinRT ,
WinRT. WinRT (
), WinRT TypedEventHandler, sender ( System.Object).
public delegate void TypedEventHandler<TSender, TResult>(TSender sender,
TResult args);
CLR WinRT
703
704
25. WinRT
, WinRT, . ,
DataWriter StoreAsync.
. WinRT API . WinRT ,
.
WinRT API, ,
API1. ,
, . ,
.
.
. WinRT API CLR CCW CCW WinRT API.
CCW ,
. ,
, WinRT API
. .25.1
WinRT .NET.
25.1. WinRT CLR
WinRT (
(Windows.Foundation.
Collections)
CLR
( System.Collections.
Generic)
IIterable<T>
IEnumerable<T>
IVector<T>
IList<T>
IVectorView<T>
IReadOnlyList<T>
IMap<K, V>
IDictionary<TKey, TValue>
IMapView<K, V>
IReadOnlyDictionary<TKey, TValue>
IKeyValuePair<K, V>
KeyValuePair<TKey, TValue>
, CLR
,
, , API , Sort
System.Array. , (C, C++, C#, Visual Basic JavaScript)
, WinRT .
1
.NET Framework
705
.NET Framework
CLR WinRT .NET
Framework, . ,
: ,
WinRT .NET Framework,
CLR WinRT API.
.
, http://
msdn.microsoft.com/en-us/library/windows/apps/hh995050.aspx
CLRandtheWindowsRuntime.docx.
1
706
25. WinRT
.NET Framework
707
IAsyncInfo
Id (UInt32)
Status (AsyncStatus)
ErrorCode (Exception)
Cancel()
Close()
AsyncStatus
Started
Completed, Canceled, Error
IAsyncAction
Completed (delegate)
GetResults
(void)
IAsyncActionWithProgress<TProgress>
Completed (delegate)
GetResults
(void)
Progress
(delegate)
IAsyncOperation<TResult>
Completed (delegate)
GetResults
(TResult)
IAsyncOperationWithProgress<TResult, TProgress>
Completed (delegate)
GetResults
(TResult)
Progress
(delegate)
. 25.2. WinRT, .
-
.NET Framework
System.Threading.Tasks. 27,
- 28. , C#
async await, ,
.
WinRTAsyncIntro.
708
25. WinRT
C# await GetAwaiter
IAsyncOperation<StorageFile>, GetFileAsync.
GetAwaiter,
. , .NET Framework
System.Runtime.WindowsRuntime.dll , WinRT IAsyncXxx.
namespace System {
public static class WindowsRuntimeSystemExtensions {
public static TaskAwaiter GetAwaiter(this IAsyncAction source);
public static TaskAwaiter GetAwaiter<TProgress>(this
IAsyncActionWithProgress<TProgress> source);
public static TaskAwaiter<TResult> GetAwaiter<TResult>(this
IAsyncOperation<TResult> source);
public static TaskAwaiter<TResult> GetAwaiter<TResult, TProgress>(
this IAsyncOperationWithProgress<TResult, TProgress> source);
}
}
TaskCompletionSource
IAsyncXxx ,
TaskCompletionSource
. TaskAwaiter, ,
C#.
TaskAwaiter ,
SynchronizationContext (. 28), .
, C#, Result TaskCompletionSource.Task;
(StorageFile ),
OperationCanceledException
. .
WinRT API . ,
, , .
.NET Framework
709
. ,
GetAwaiter
AsTask,
WindowsRuntimeSystemExtensions.
namespace System {
public static class WindowsRuntimeSystemExtensions {
public static Task AsTask<TProgress>(this
IAsyncActionWithProgress<TProgress> source,
CancellationToken cancellationToken, IProgress<TProgress> progress);
public static Task<TResult> AsTask<TResult, TProgress>(
this IAsyncOperationWithProgress<TResult, TProgress> source,
CancellationToken cancellationToken, IProgress<TProgress> progress);
//
}
}
, .
WinRT API
, :
using System; // AsTask WindowsRuntimeSystemExtensions
using System.Threading; // CancellationTokenSource
internal sealed class MyClass {
private CancellationTokenSource m_cts = new CancellationTokenSource();
// :
// :
private async void MappingWinRTAsyncToDotNet(WinRTType someWinRTObj) {
try {
// , XxxAsync
// IAsyncOperationWithProgress<IBuffer, UInt32>
IBuffer result = await someWinRTObj.XxxAsync(...)
.AsTask(m_cts.Token, new Progress<UInt32>(ProgressReport));
/* ... */
}
catch (OperationCanceledException) { /* ... */ }
catch (SomeOtherException) { /* ... */ }
}
private void ProgressReport(UInt32 progress) { /* ... */ }
public void Cancel() { m_cts.Cancel(); } //
}
, , AsTask
WinRT IAsyncXxx .NET Framework Task,
await.
710
25. WinRT
AsTask. ,
.
public static Task<TResult> AsTask<TResult, TProgress>(
this IAsyncOperationWithProgress<TResult, TProgress> asyncOp,
CancellationToken ct = default(CancellationToken),
IProgress<TProgress> progress = null) {
// CancellationTokenSource
ct.Register(() => asyncOp.Cancel());
// ,
//
asyncOp.Progress = (asyncInfo, p) => progress.Report(p);
// TaskCompletionSource
//
var tcs = new TaskCompletionSource<TResult>();
// TaskCompletionSource.
// , ,
// TaskCompletionSource.
asyncOp.Completed = (asyncOp2, asyncStatus) => {
switch (asyncStatus) {
case AsyncStatus.Completed: tcs.SetResult(asyncOp2.GetResults()); break;
case AsyncStatus.Canceled: tcs.SetCanceled(); break;
case AsyncStatus.Error: tcs.SetException(asyncOp2.ErrorCode); break;
}
};
}
return tcs.Task;
WinRT .NET
.NET Framework , System.
IO.Stream , , LINQ. WinRT, WinRT IStorageFile IStorageFolder,
.NET Framework, , Stream,
, System.IO.Wi
ndowsRuntimeStorageExtensions.
namespace System.IO { // System.Runtime.WindowsRuntime.dll
public static class WindowsRuntimeStorageExtensions {
public static Task<Stream> OpenStreamForReadAsync(this IStorageFile file);
public static Task<Stream> OpenStreamForWriteAsync(this IStorageFile file);
public static Task<Stream> OpenStreamForReadAsync(this
IStorageFolder rootDirectory,
String relativePath);
public static Task<Stream> OpenStreamForWriteAsync(this
.NET Framework
711
IStorageFolder rootDirectory,
String relativePath, CreationCollisionOption creationCollisionOption);
}
}
WinRT StorageFile .NET Framework
XElement.
async Task<XElement> FromStorageFileToXElement(StorageFile file) {
using (Stream stream = await file.OpenStreamForReadAsync()) {
return XElement.Load(stream);
}
}
, System.IO.WindowsRuntimeStreamExtensions
, WinRT (,
IRandomAccessStream, IInputStream IOutputStream) .NET Framework
Stream, .
namespace System.IO { // System.Runtime.WindowsRuntime.dll
public static class WindowsRuntimeStreamExtensions {
public static Stream AsStream(this IRandomAccessStream winRTStream);
public static Stream AsStream(this IRandomAccessStream winRTStream,
Int32 bufferSize);
public static Stream AsStreamForRead(this IInputStream winRTStream);
public static Stream AsStreamForRead(this IInputStream winRTStream,
Int32 bufferSize);
public static Stream AsStreamForWrite(this IOutputStream winRTStream);
public static Stream AsStreamForWrite(this IOutputStream winRTStream,
Int32 bufferSize);
: , .NET
Framework, . , WinRT .NET Framework,
WinRT .
,
- (,
XML).
712
25. WinRT
CLR WinRT
, , ,
. CLR
WinRT . ,
WinRT
. ,
WinRT , .
.NET Framework
(Byte[]) (, MemoryStream).
, MemoryStream WinRT , WinRT IBuffer; ,
, ,
WinRT API. WinRT IBuffer :
namespace Windows.Storage.Streams {
public interface IBuffer {
UInt32 Capacity { get; } // ( )
UInt32 Length { get; set; } //
} //
}
.NET Framework
713
, IBuffer ;
,
. , , , WinRT
, (, JavaScript C#).
, IBuffer CLR
WinRT API. COM IBufferByteAccess. :
COM ( ), WinRT. .NET
Framework COM RCW,
:
namespaceSystem.Runtime.InteropServices.WindowsRuntime {
[Guid("905a0fefbc5311df8c49001e4fc686da")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
internalinterfaceIBufferByteAccess {
unsafeByte*Buffer { get; }
}
}
, Byte[]
WinRT, IBuffer , AsBuffer Byte[] .
714
25. WinRT
, Byte[] ,
IBuffer; Byte[] ,
. ,
MemoryStream, Byte[],
GetWindowsRuntimeBuffer, MemoryStream , IBuffer.
, .
:
private async Task ByteArrayAndStreamToIBuffer(IRandomAccessStream winRTStream,
Int32 count) {
Byte[] bytes = new Byte[count];
await winRTStream.ReadAsync(bytes.AsBuffer(), (UInt32)bytes.Length,
InputStreamOptions.None);
Int32 sum = bytes.Sum(b => b); //
// Byte[]
using (var ms = new MemoryStream())
using (var sw = new StreamWriter(ms)) {
sw.Write("This string represents data in a stream");
sw.Flush();
UInt32 bytesWritten = await
winRTStream.WriteAsync(ms.GetWindowsRuntimeBuffer());
}
}
AsBuffer GetWindowsRuntimeBuffer
, ,
IBuffer. CLR CCW
WinRT API. WinRT API Buffer IBufferByteAccess
, , WinRT API
. , WinRT API COM
Release IBufferByteAccess.
WinRT API, IBuffer, , , , . ,
WindowsRuntimeBufferExtensions.
namespaceSystem.Runtime.InteropServices.WindowsRuntime {
public static class WindowsRuntimeBufferExtensions {
WinRT C#
715
WinRT C#
WinRT C#. WinRT C#
C/C++, C#/Visual Basic, JavaScript
. , ,
. , WinRT C#,
,
CLR. , WinRT
,
CLR.
, C#
WinRT, C/C++. , , C/C++,
/ .
716
25. WinRT
WinRT,
, CLR , ,
-
JIT- . WinRT (
, Windows) .
, C++ ,
,
.NET Framework . , Bing Maps C++
DirectX, - C#.
, , WinRT, C#,
Windows Store, HTML CSS, JavaScript
-, WinRT.
FCL HTML/JavaScript.
, HTML JavaScript,
,
. , - CLR .
WinRT C# Microsoft Visual
Studio Windows Runtime Component.
, C#
/t:winmdobj .winmdobj.
IL- ,
. , WinRT , CLR,
add remove . ,
add remove .
.winmdobj, WinMD
(WinMDExp.exe), .winmdobj,
.pdb .xml (doc). WinMDExp.exe , WinRT (.
). , .winmdobj; IL-
. , CLR WinRT. , .NET Framework
IList<String> WinRT IVector<String>.
WinMDExp.exe .winmd, .
.winmd ILDasm.exe. ILDasm.exe , -
WinRT C#
717
/project ,
WinRT .NET Framework.
WinRT C#. , , .
WinRT C#, .
System;
System.Collections.Generic;
System.Linq;
System.Runtime.InteropServices.WindowsRuntime;
System.Threading;
System.Threading.Tasks;
Windows.Foundation;
Windows.Foundation.Metadata;
//
// "Windows"
namespace Wintellect.WinRTComponents {
// [Flags] // int; uint
public enum WinRTEnum : int { //
None, // int uint
NotNone
}
// ,
718
25. WinRT
// String .
// .
public struct WinRTStruct {
public Int32 ANumber;
public String AString;
public WinRTEnum AEnum; //
} // 32-
// WinRT-
// ( BeginInvoke/EndInvoke)
public delegate String WinRTDelegate(Int32 x);
// , ,
// .
public interface IWinRTInterface {
// Nullable<T> IReference<T>
Int32? InterfaceProperty { get; set; }
}
// [Version(#)]
// (1) COM,
// WinMDExp.exe.
[Version(1)]
// Object, ,
// , WinRT,
// WinRT
public sealed class WinRTClass : IWinRTInterface {
//
#region ,
public static String StaticMethod(String s) { return "Returning " + s; }
public static WinRTStruct StaticProperty { get; set; }
// JavaScript 'out' ;
//
public static String OutParameters(out WinRTStruct x, out Int32 year) {
x = new WinRTStruct { AEnum = WinRTEnum.NotNone, ANumber = 333,
AString = "Jeff" };
year = DateTimeOffset.Now.Year;
return "Grant";
}
#endregion
// , out/ref
public WinRTClass(Int32? number) { InterfaceProperty = number; }
public Int32? InterfaceProperty { get; set; }
// ToString
public override String ToString() {
return String.Format("InterfaceProperty={0}",
InterfaceProperty.HasValue ? InterfaceProperty.Value.ToString() :
WinRT C#
719
"(not set)");
720
25. WinRT
//
private EventRegistrationTokenTable<WinRTDelegate> m_manualEvent = null;
// add remove
public event WinRTDelegate ManualEvent {
add {
// ( ,
// )
return EventRegistrationTokenTable<WinRTDelegate>
.GetOrCreateEventRegistrationTokenTable(ref m_manualEvent)
.AddEventHandler(value);
}
remove {
EventRegistrationTokenTable<WinRTDelegate>
.GetOrCreateEventRegistrationTokenTable(ref m_manualEvent)
.RemoveEventHandler(value);
}
}
public String RaiseManualEvent(Int32 number) {
WinRTDelegate d = EventRegistrationTokenTable<WinRTDelegate>
.GetOrCreateEventRegistrationTokenTable(ref
m_manualEvent).InvocationList;
return (d == null) ? "No callbacks registered" : d(number);
}
#endregion
#region Asynchronous methods
//
// IAsync[Action|Operation](WithProgress)
// : DataTimeOffset
// Windows.Foundation.DateTime
public IAsyncOperationWithProgress<DateTimeOffset, Int32>
DoSomethingAsync() {
// Run
// System.Runtime.InteropServices.WindowsRuntime.AsyncInfo
// ,
// .
return AsyncInfo.Run<DateTimeOffset, Int32>(DoSomethingAsyncInternal);
}
//
// .NET
private async Task<DateTimeOffset> DoSomethingAsyncInternal(
CancellationToken ct, IProgress<Int32> progress) {
for (Int32 x = 0; x < 10; x++) {
//
ct.ThrowIfCancellationRequested();
if (progress != null) progress.Report(x * 10);
await Task.Delay(1000); //
}
WinRT C#
721
return DateTimeOffset.Now; //
}
public IAsyncOperation<DateTimeOffset> DoSomethingAsync2() {
// ,
// AsAsync[Action|Operation]
// System.WindowsRuntimeSystemExtensions
// ( AsyncInfo.Run )
return DoSomethingAsyncInternal(default(CancellationToken),
null).AsAsyncOperation();
}
#endregion
//
// [Version(#)], WinMDExp.exe
// COM. ,
// COM .
[Version(2)]
public void NewMethodAddedInV2() {}
}
}
JavaScript
WinRT.
function () {
//
var WinRTComps = Wintellect.WinRTComponents;
// WinRT
var s = WinRTComps.WinRTClass.staticMethod(null); // JavaScript "null"!
var struct = { anumber: 123, astring: "Jeff", aenum:
WinRTComps.WinRTEnum.notNone };
WinRTComps.WinRTClass.staticProperty = struct;
s = WinRTComps.WinRTClass.staticProperty; //
// ,
//
var s = WinRTComps.WinRTClass.outParameters();
var name = s.value; //
var struct = s.x; // 'out'
var year = s.year; // 'out'
// WinRT
var winRTClass = new WinRTComps.WinRTClass(null);
s = winRTClass.toString(); // ToString()
//
try { winRTClass.throwingMethod(); }
catch (err) { }
//
var a = [1, 2, 3, 4, 5];
722
25. WinRT
26. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. 724
27.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 747
28. -. .. ..787
29.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..820
30.
. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..854
26.
, (threads)1.
, Microsoft Windows ,
,
(CLR-) Windows-, ,
Windows, .NET Framework, , .
, Windows CLR . ,
, ,
.
Windows ?
. , ,
, . ,
, . , 16- Windows ,
.
.
, ,
.
, Reset
. ,
( ),
, .
Microsoft , 16 Windows ,
, , , .
, , ,
- (streams). . .
725
.
WindowsNT. .
Windows .
(process). , .
; , .
,
.
; ,
. .
,
, ,
,
.
?
? ,
.
( ),
, ,
. .
, Windows. Windows- ( ).
, , ( )
!
; Windows
, . ,
(, ) , .
, ,
() ( ).
. .
726
26.
727
,
.
Windows 5 6 ,
.
, Microsoft Visual Studio
470DLL-! ,
470 DLL. Visual
Studio . ,
1.
, ,
. -
(context switching).
- . ,
( ).
Windows
. ,
(quantum). Windows .
:
1. , .
2. , . , Windows .
- - .
3.
.
,
,
. Windows 30. .
1
C#
DllMain, DLL-
DLL_THREAD_ATTACH DLL_THREAD_DETACH.
, Win32- DisableThreadLibraryCalls
. ,
, .
728
26.
,
.
- , Windows
. ,
, ,
. , ,
, . . ,
,
.
, . .
, ,
, ,
. , ,
, . ,
, , . 30
.
. ,
. , , . ,
.
Windows
( ), . .
, , , - (,
, , . .). , Notepad ,
. Windows
, . 5,
Win32-, Windows . , ( ).
. , ,
, .
729
CLR , , ,
( , )
. ,
. Windows
. ,
, .
,
,
, . . ,
, Windows
.
,
,
( ).
, . ,
, .
. Windows
,
.
.
Windows CLR,
,
.
!
,
.
,
.. :
, ,
.
, .
Windows Microsoft ,
730
26.
.
. , - Windows .NET Framework,
-
. Windows
, . , .26.1 , Performance
().
. 26.1.
,
55, , 55.
. , 864! , ,
4.
, 15,7,
.
,
, 5%. 95%
864 , , .
, ?
, . , -
731
. 26.2.
, 105 , 1% , Explorer 47 0% ,
Microsoft Visual Studio (Devenv.exe) 36, 0% , Outlook,
24 0% .. ?
Windows, ,
.
, , , EXE- DLL- ..
.
,
. .
, .
, . , .
Select Columns ( ).
1
732
26.
, .
,
, 1.
,
, 100. 100 Outlook, 24
. 2400, ,
TEB, , ..
. ,
Microsoft , Windows ,
1 .
.
,
. . , , ,
, .
. -
;
.
, . -
,
.
. -
, ,
. , . ,
,
, .
Notepad.exe
. File () Open (),
File Open ( ),
. 31 ! ,
. !
1
CLR- Windows-
733
. ? .
:
. . ,
, .
, , .
-
.
, -
.
. ( Intel)
. , ,
. Windows
,
, .
- ,
, .
, Windows .
.
,
.
.
Intel, 1030%.
. , .
, .
. , . Intel 80. ,
! , Intel
.
CLR- Windows-
CLR Windows ,
V ,
, CLR. -
734
26.
, Windows CLR.
, Windows via C/C++ (Microsoft
Press, 2007).
.NET Framework CLR
, CLR ,
Windows. 2005 CLR
, CLR-
Windows-, .NET Framework
. , System.Environment
CurrentManagedThreadId, CLR- ,
System.Diagnostics.ProcessThread Id Windows- . BeginThreadAffinity
EndThreadAffinity System.Thread
, CLR- Windows-.
Windows Store Microsoft
API, , (. ! ) , Microsoft Windows
Apps. , System.Thread Windows Store
- API (, Start, IsBackground, Sleep, Suspend,
Resume, Join, Interrupt, Abort, BeginThreadAffinity EndThreadAffinity).
, , , . 2630 APIs ,
, Windows Store.
, API Windows Store.
,
. ,
( Windows Store - System.Thread).
CLR (thread pool).
.
, .
, ,
. :
735
(
). ,
, ,
.
, ,
.
.
, ,
- , CLR .
, , ;
.
Abort Thread,
22.
System.
Threading.Thread,
. :
start , .
ParameterizedThreadStart:1
delegate void ParameterizedThreadStart(Object obj);
Thread ,
.
, ,
Start Thread, (),
.
,
:
Thread , ThreadStart,
.
- . Object
void,
, 27.
1
736
26.
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
Windows, :
Main thread: starting a dedicated thread to do an asynchronous operation
In ComputeBoundOp: state=5
Main thread: Doing other work here...
:
( ). Windows
737
, .
,
. , ,
. ,
, .
( ).
Windows , ,
. ,
,
. ,
. , ,
27 28.
. , , .
, . , ,
100%. ,
. -, 100
. -,
, , , 100%. , , , .
,
, . ,
,
.
, , , . .
, , . ,
,
, , ,
.
. .
, , 5% -
738
26.
. , , .
80- , ,
. ,
!
.
, ,
.
, .
, , ,
. , ,
.
, Visual Studio .
,
.
-- , () .
.
.
, Visual Studio Build,
. ,
, .
. ,
. ,
. .
,
. .
:
, ,
-.
,
, ,
, .
.
739
,
. , Windows.
,
.
Windows ,
,
. ,
. .26.3
Microsoft Spy++, .
, 317681.
, . Windows .
.
Windows
, . ,
- , ,
.
. 26.3. Spy++
, 25,
. .
1
740
26.
:
- ? ,
1
? : .
, Windows
. , .
, . Windows Microsoft
: , , ..
.
, - CLR . ,
, JIT- , .
( )
31 ( ). , ,
. 31 .
,
.
31
.
(starvation), ,
. , 31 30 . ,
.
, .
5 ,
, ( )
.
(zero page thread),
. .
.
,
.
741
,
.
.
, , ,
. Windows
: Idle ( ), Lowest ( ), Below Normal ( ), Normal (), Above Normal ( ), Highest ( )
Time-Critical ( ). .
, , .
, ,
. ,
742
26.
31. . .
,
.26.1.
26.1.
Time-Critical
15
15
15
15
15
31
Highest
10
12
15
26
Above Normal
11
14
25
Normal
10
13
24
Below Normal
12
23
Lowest
11
22
Idle
16
Idle
Below
Normal
Normal
Above
Normal
High
Realtime
743
, Windows
- . .
,
; .
, .
, ,
, ,
.. , - , .
,
.
Windows (Windows Explorer), Windows
.
.
Windows ,
.
, .
Windows, Normal. , .
,
. , ASP.
NET ,
. Silverlight, -, ,
Microsoft SQL Server.
Priority Thread,
(Lowest, BelowNormal, Normal, AboveNormal Highest),
ThreadPriority . ,
Windows , CLR
Idle Time-Critical. CLR
Idle, . , 21,
Time-Critical. ,
: .26.1
(Highest) (Lowest).
744
26.
, . , ,
100%, ,
. ,
,
- . ,
, , . , 8 ,
. ,
.
.
System.Diagnostics Process
ProcessThread (, ,
Windows Store).
Windows. ,
, .
System.Diagnostics.
.
, , Silverlight ASP.NET.
, AppDomain
Thread, CLR .
,
.
CLR (foreground) (background).
CLR
.
.
,
, ,
.
,
. , , ,
.
745
CLR . ,
,
. ,
, CLR ,
.
, .
:
using System;
using System.Threading;
public static class Program {
public static void Main() {
// ( )
Thread t = new Thread(Worker);
//
t.IsBackground = true;
t.Start(); //
// 10
//
Console.WriteLine("Returning from Main");
}
private static void Worker() {
Thread.Sleep(10000); // 10
// ,
//
Console.WriteLine("Returning from Worker");
}
}
.
,
Thread, .
. ,
, .
.
, .
, ,
, .
, ,
.
746
26.
?
. , ,
. CLR,
.
, .
27 ,
. 28 ,
CLR -.
- , . ,
. , , 29 30.
, ,
- Windows NT 3.1, 1992.
- .NET ,
. (
Wintellect Power Threading Library) . CLR, Silverlight CLR Compact
Framework. ,
http://Wintellect.com/PowerThreading.aspx.
.
27.
, . , , , , ,
, - ,
. ,
.
. ,
Performance (). 100%
( ), , .
, ( ) . , ,
, ,
. -
Microsoft Windows ,
, .
.
, -, ,
.
. , , ,
.
,
. ,
, -,
, -,
.
CLR
,
. ,
748
27.
,
. ,
CLR ,
, .
CLR , , CLR.
CLR, .
CLR . .
,
.
. , . ,
.
,
. , .
,
.
, , .
.
,
, .
( CLR) , . ,
, , , .
,
,
, .
.
,
.
.
ThreadPool:
static Boolean QueueUserWorkItem(WaitCallback callBack);
static Boolean QueueUserWorkItem(WaitCallback callBack, Object state);
749
.
callback ,
.
state ( ).
QueueUserWorkItem null. , ,
.
System.Threading.WaitCallback, :
delegate void WaitCallback(Object state);
WaitCallback TimerCallback ( ),
ParameterizedThreadStart ( 25) .
, ,
ThreadPool.QueueUserWorkItem System.Threading.
Timer System.Threading.Thread.
:
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) {
//
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
750
27.
, :
Main thread: queuing an asynchronous operation
In ComputeBoundOp: state=5
Main thread: Doing other work here...
. Windows , ,
.
, CLR ( ).
20.
. ( , Principal
Thread Windows), (System.
Threading.HostExecutionContextManager)
(. LogicalSetData LogicalGetData System.Runtime.
Remoting.Messaging.CallContext). , .
.
, , .
CLR
. ,
,
.
. , ,
751
,
.
ExecutionContext System.Threading
. :
public sealed class ExecutionContext : IDisposable, ISerializable {
[SecurityCritical] public static AsyncFlowControl SuppressFlow();
public static void RestoreFlow();
public static Boolean IsFlowSuppressed();
//
}
,
. .
, , SuppressFlow [SecurityCritical],
(, Microsoft Silverlight). ,
, .
,
.
, (, Windows).
,
CLR-1:
public static void Main() {
// Main
CallContext.LogicalSetData("Name", "Jeffrey");
//
//
ThreadPool.QueueUserWorkItem(
state => Console.WriteLine("Name={0}",
CallContext.LogicalGetData("Name")));
// Main
ExecutionContext.SuppressFlow();
// .
//
ThreadPool.QueueUserWorkItem(
(.24). , , ,
.
1
752
27.
:
Name=Jeffrey
Name=
ThreadPool.QueueUserWorkItem,
Task (. ), - ( 28).
.NET .
(cooperative), . , , ,
, , ,
.
, . , ,
.
FCL,
.
System.Threading.CancellationTokenSource.
:
public sealed class CancellationTokenSource : IDisposable { //
public CancellationTokenSource();
public Boolean IsCancellationRequested { get; }
public CancellationToken Token { get; }
public void Cancel(); // Cancel false
public void Cancel(Boolean throwOnFirstException);
...
}
, .
CancellationTokenSource ( )
753
CancellationToken ( )
Token. , .
CancellationToken:
public struct CancellationToken { //
public static CancellationToken None { get; } //
Boolean IsCancellationRequested { get; } //
//
public void ThrowIfCancellationRequested(); //
//
,
Task
,
Task
// WaitHandle CancellationTokenSource
public WaitHandle WaitHandle { get; }
// GetHashCode, Equals, == !=
public Boolean CanBeCanceled { get; } //
public CancellationTokenRegistration Register(
Action<Object> callback, Object state,
Boolean useSynchronizationContext); //
//
}
CancellationToken ,
: Cancellation
TokenSource.
IsCancellationRequested CancellationToken, ,
, . , .
:
internal static class CancellationDemo {
public static void Main() {
CancellationTokenSource cts = new CancellationTokenSource();
// CancellationToken
ThreadPool.QueueUserWorkItem(o => Count(cts.Token, 1000));
Console.WriteLine("Press <Enter> to cancel the operation.");
Console.ReadLine();
cts.Cancel(); // Count ,
// Cancel
// Cancel , ...
Console.ReadLine();
}
private static void Count(CancellationToken token, Int32 countTo) {
for (Int32 count = 0; count <countTo; count++) {
if (token.IsCancellationRequested) {
754
27.
Console.WriteLine("Count is cancelled");
break; //
}
Console.WriteLine(count);
Thread.Sleep(200); //
}
Console.WriteLine("Count is done");
}
}
,
CancellationToken, None
CancellationToken.
CancellationToken, - CancellationTokenSource (
null). CancellationTokenSource
, Cancel. ,
IsCancellationRequested CancellationToken false. CanBeCanceled.
true CancellationToken,
Token CancellationTokenSource.
, CancellationTokenSource.
Register
CancellationToken Action<Object> ,
,
Boolean, ,
SynchronizationContext . useSynchronizationContext false, ,
Cancel , . true
SynchronizationContext, ,
. SynchronizationContext 28.
,
CancellationTokenSource, , Register,
(, SynchronizationContext ,
useSynchronizationContext true).
Register
,
755
,
InnerExceptions AggregateException.
, ,
, . , StackTrace
.
, Cancel:
Canceled 2
Canceled 1
756
27.
, CancellationTokenSource,
CancellationTokenSource.
. :
// CancellationTokenSource
var cts1 = new CancellationTokenSource();
cts1.Token.Register(() => Console.WriteLine("cts1 canceled"));
// CancellationTokenSource
var cts2 = new CancellationTokenSource();
cts2.Token.Register(() => Console.WriteLine("cts2 canceled"));
// CancellationTokenSource,
// cts1 ct2
var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(
cts1.Token, cts2.Token);
linkedCts.Token.Register(() => Console.WriteLine("linkedCts canceled"));
// CancellationTokenSource ( cts2)
cts2.Cancel();
// , CancellationTokenSource
Console.WriteLine("cts1 canceled={0}, cts2 canceled={1}, linkedCts={2}",
cts1.IsCancellationRequested, cts2.IsCancellationRequested,
linkedCts.IsCancellationRequested);
:
linkedCts canceled
cts2 canceled
cts1 canceled=False, cts2 canceled=True, linkedCts=True
. , ,
. .
,
. , CancellationTokenSource
.
CancellationTokenSource , , CancelAfter
CancellationTokenSource.
public sealed class CancellationTokenSource : IDisposable { //
public CancellationTokenSource(Int32 millisecondsDelay);
public CancellationTokenSource(TimeSpan delay);
757
QueueUserWorkItem ThreadPool
.
. ,
. Microsoft
(tasks),
System.Threading.Tasks.
,
QueueUserWorkItem ThreadPool:
ThreadPool.QueueUserWorkItem(ComputeBoundOp, 5); // QueueUserWorkItem
new Task(ComputeBoundOp, 5).Start(); //
Task.Run(() => ComputeBoundOp(5)); //
Task
Start . , Task Start . ,
Task - ,
Start. Task
Start ,
Run Task, .
Task
Action Action<Object>, , . , Object, Task
, .
Run Func<TResult> Action,
.
CancellationToken, Task (
).
TaskCreationOptions, .
, . TaskCreationOptions
:
[Flags, Serializable]
public enumTaskCreationOptions {
None = 0x0000, //
// ,
//
PreferFairness = 0x0001,
// ,
758
27.
// .
LongRunning = 0x0002,
// :
AttachedToParent = 0x0004,
// ,
// , .
DenyChildAttach = 0x0008,
//
// .
HideScheduler
= 0x0010
}
, ,
TaskScheduler; AttachedToParent,
DenyChildAttach HideScheduler,
TaskScheduler. .
. Sum, n
:
private static Int32 Sum(Int32 n) {
Int32 sum = 0;
for (; n > 0; n--)
checked { sum += n; } // n System.OverflowException
return sum;
}
759
Wait ,
Task, . ,
Wait, .
, ( TaskScheduler)
, Wait. . Task
. (
), (
).
. , Wait
,
, (deadlock)!
, , .
Wait Result
System.AggregateException.
AggregateException (
,
, ). InnerExceptions,
ReadOnlyCollection<Exception>.
InnerException, AggregateException
System.Exception. , 0
InnerExceptions AggregateException
System.OverflowException, (Sum).
AggregateException GetBaseException
Exception. , (,
). AggregateException
Flatten, AggregateException,
InnerExceptions ,
.
, Handle,
AggregateException .
.
true, , , false.
Handle ,
AggregateException. , Flatten Handle
.
,
Task. . WaitAny
Task. Int32 ,
760
27.
, . -, 1.
CancellationToken OperationCanceledException.
Wait Result
Exception Task, . ,
,
. UnobservedTaskException
TaskScheduler.
CLR.
UnobservedTaskExceptionEve
ntArgs, AggregateException.
CancellationTokenSource.
, Sum,
CancellationToken:
private static Int32 Sum(CancellationTokenct, Int32 n) {
Int32 sum = 0;
for (; n > 0; n--) {
// OperationCanceledException
// Cancel CancellationTokenSource,
//
ct.ThrowIfCancellationRequested();
checked { sum += n; } // n
// System.OverflowException
}
return sum;
}
ThrowIfCancellationRequested CancellationToken, ,
.
IsCancellationRequested CancellationToken , .
761
CancellationTokenSource OperationCanceledException. ,
, QueueUserWorkItem
ThreadPool,
. , , . .
CancellationTokenSource Task:
CancellationTokenSource cts = new CancellationTokenSource();
Task<Int32> t = new Task<Int32>(() => Sum(cts.Token, 10000), cts.Token);
t.Start();
// CancellationTokenSource, Task
cts.Cancel(); // ,
try {
// Result
// AggregateException
Console.WriteLine("The sum is: " + t.Result); // Int32
}
catch (AggregateException x) {
// OperationCanceledException
// AggregateException,
//
x.Handle(e => e is OperationCanceledException);
// ,
Console.WriteLine("Sum was canceled");
}
Task CancellationToken ,
Task ( ).
CancellationToken , 1.
( Start),
. ,
Task CancellationToken, .
- CancellationToken,
Task, .
-
CancellationToken (, ,
).
InvalidOperationException.
1
762
27.
. Wait Result , , ,
. ,
.
. ,
:
// Task
Task<Int32> t = Task.Run(() => Sum(CancellationToken.None, 10000));
// ContinueWith Task,
//
Task cwt = t.ContinueWith(task => Console.WriteLine(
"The sum is: " + task.Result));
, , Sum, ,
( ),
. , ; -
, , .
, Sum ContinueWith. , , ContinueWith
Sum ,
.
, ContinueWith
Task ( cwt).
(, Wait,
Result ContinueWith), ,
.
, Task
ContinueWith.
ContinueWith Task. , ContinueWith .
, ContinueWith TaskContinuationOptions. None, PreferFairness,
LongRunning, AttachedToParent,DenyChildAttach HideScheduler
TaskCreationOptions.
TaskContinuationOptions:
[Flags, Serializable]
public enumTaskContinuationOptions {
None = 0x0000, //
// ,
763
//
PreferFairness = 0x0001,
// ,
// .
LongRunning = 0x0002,
// :
AttachedToParent = 0x0004,
// ,
// , .
DenyChildAttach = 0x0008,
//
// .
HideScheduler = 0x0010,
// .
LazyCancellation = 0x0020,
// , , ,
// , ContinueWith.
// , , ContinueWith,
// ContinueWith
ExecuteSynchronously = 0x80000,
// , ContinueWith
NotOnRanToCompletion = 0x10000,
NotOnFaulted = 0x20000,
NotOnCanceled = 0x40000,
//
OnlyOnCanceled = NotOnRanToCompletion | NotOnFaulted,
OnlyOnFaulted = NotOnRanToCompletion | NotOnCanceld,
OnlyOnRanToCompletion = NotOnFaulted | NotOnCanceled,
}
ContinueWith TaskContinuationOptions.OnlyOn
Canceled , . , TaskContinuationOptions.OnlyOnFaulted
, ,
.
TaskContinuationOptions.OnlyOnRanToCompletion ,
,
. ,
. Task
. , :
764
27.
//
Task<Int32> t = Task.Run(() => Sum(10000));
// ContinueWith Task,
//
t.ContinueWith(task => Console.WriteLine("The sum is: " + task.Result),
TaskContinuationOptions.OnlyOnRanToCompletion);
t.ContinueWith(task => Console.WriteLine("Sum threw: " + task.Exception),
TaskContinuationOptions.OnlyOnFaulted);
t.ContinueWith(task => Console.WriteLine("Sum was canceled"),
TaskContinuationOptions.OnlyOnCanceled);
, -:
Task<Int32[]> parent = new Task<Int32[]>(() => {
var results = new Int32[3]; //
// 3
new Task(() => results[0] = Sum(10000),
TaskCreationOptions.AttachedToParent).Start();
new Task(() => results[1] = Sum(20000),
TaskCreationOptions.AttachedToParent).Start();
new Task(() => results[2] = Sum(30000),
TaskCreationOptions.AttachedToParent).Start();
//
// ( )
return results;
});
//
varcwt = parent.ContinueWith(
parentTask => Array.ForEach(parentTask.Result, Console.WriteLine));
// ,
parent.Start();
Task. - . TaskCreationOptions.AttachedToParent
. Task ContinueWith
TaskContinuationOptions.AttachedToParent, , , .
765
Task , .
: Int32 (
Id Task), Int32, , , TaskScheduler,
, ,
, ( AsyncState Task),
ExecutionContext ManualResetEventSlim.
, Task , .
CancellationToken, ContinueWithTask,
Task , ,
. ,
. ,
ThreadPool.QueueUserWorkItem.
Task Task<TResult> IDisposable,
Task Dispose.
ManualResetEventSlim,
, Task Task<TResult>, , Dispose. ,
Dispose Task;
.
, Task Int32,
. . Id ( )
Int32,
.
.
, Task Microsoft
Visual Studio.
, . Visual Studio
Parallel Tasks Parallel Stacks.
, ,
. CurrentId
Task, Int32,
null (Int32?). ,
, Visual Studio Watch Immediate.
Parallel Tasks Parallel Stacks.
CurrentId , , null.
766
27.
, ,
Status Task.
TaskStatus, :
public enum TaskStatus {
// , :
Created, //
//
WaitingForActivation, //
//
WaitingToRun, // ,
Running, //
// ,
WaitingForChildrenToComplete,
// :
RanToCompletion,
Canceled,
Faulted
}
767
Task, ContinueWith.
.
Task,
.
,
(task factory), . System.
Threading.Tasks TaskFactory TaskFactory<TResult>.
System.Object;
.
, ,
TaskFactory. , TaskFactory<TResult>, TResult
.
,
. , CancellationToken, TaskScheduler,
TaskCreationOptions TaskContinuationOptions,
.
TaskFactory:
Task parent = new Task(() => {
varcts = new CancellationTokenSource();
vartf = new TaskFactory<Int32>(cts.Token,
TaskCreationOptions.AttachedToParent,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Default);
// 3
varchildTasks = new[] {
tf.StartNew(() => Sum(cts.Token, 10000)),
tf.StartNew(() => Sum(cts.Token, 20000)),
tf.StartNew(() => Sum(cts.Token, Int32.MaxValue)) //
// OverflowException
};
// ,
//
for (Int32 task = 0; task <childTasks.Length; task++)
childTasks[task].ContinueWith(
t => cts.Cancel(), TaskContinuationOptions.OnlyOnFaulted);
//
//
//
tf.ContinueWhenAll(
childTasks,
768
27.
TaskFactory<Int32>,
Task. , Task
CancellationTokenSource,
,
.
Task, StartNew TaskFactory,
.
. , , .
TaskFactory ContinueWhenAll,
, .
TaskFactory,
.
,
CancellationToken
CancellationToken.None. .
, ,
, .
769
ContinueWhenAll ContinueWhenAny
TaskFactory TaskFactory<TResult> TaskContinuationOption: NotOnRanToCompletion, NotOnFaulted NotOnCanceled.
, OnlyOnCanceled, OnlyOnFaulted
OnlyOnRanToCompletion. ContinueWhenAll ContinueWhenAny ,
.
,
TaskScheduler. TaskScheduler
Visual Studio. FCL TaskScheduler : . ,
( ).
Default
TaskScheduler.
Windows Forms, Windows Presentation Foundation (WPF), Silverlight
Windows Store. , ,
, ..
. From
CurrentSynchronizationContext TaskScheduler.
Windows Forms
:
internal sealed class MyForm : Form {
private readonly TaskScheduler m_syncContextTaskScheduler;
public MyForm() {
m_syncContextTaskScheduler =
TaskScheduler.FromCurrentSynchronizationContext();
//
private readonly TaskScheduler m_syncContextTaskScheduler =
TaskScheduler.FromCurrentSynchronizationContext();
private CancellationTokenSource m_cts;
protected override void OnMouseClick(MouseEventArgs e) {
770
27.
if (m_cts != null) { // ,
m_cts.Cancel();
m_cts = null;
} else { // ,
Text = "Operation running";
m_cts = new CancellationTokenSource();
//
//
Task<Int32> t = Task.Run(() => Sum(m_cts.Token, 20000), m_cts.Token);
//
//
t.ContinueWith(task => Text = "Result: " + task.Result,
CancellationToken.None,
TaskContinuationOptions.OnlyOnRanToCompletion,
m_syncContextTaskScheduler);
t.ContinueWith(task => Text = "Operation canceled",
CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled,
m_syncContextTaskScheduler);
t.ContinueWith(task => Text = "Operation faulted",
CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted,
m_syncContextTaskScheduler);
}
base.OnMouseClick(e);
}
}
. , , GUI
.
.
InvalidOperationException.
, ,
. ,
GUI-,
.
Text.
( Sum) , .
.
,
, TaskScheduler. Microsoft
Parallel
771
For Parallel
:
//
Parallel.For(0, 1000, i => DoWork(i));
:
//
foreach (var item in collection) DoWork(item);
:
//
Parallel.ForEach(collection, item => DoWork(item));
772
27.
:
//
Parallel.Invoke(
() => Method1(),
() => Method2(),
() => Method3());
Parallel
. , , . ,
,
, ,
, ,
for foreach. ,
. - , Parallel
AggregateException.
, , for Parallel.For, foreach Parallel.ForEach.
Parallel ,
. , ,
, . , ,
.
, .
,
.
, Parallel
,
. , , .
, -
. ,
773
Parallel
, .
, For, ForEach Invoke Parallel
, ParallelOptions.
:
public class ParallelOptions{
public ParallelOptions();
//
public CancellationTokenCancellationToken { get; set; }
// CancellationToken.None
//
// ,
public Int32MaxDegreeOfParallelism { get; set; }
// -1 ( )
//
public TaskSchedulerTaskScheduler { get; set; }
// TaskScheduler.Default
}
For ForEach,
:
(localInit)
.
body , .
(localFinally )
,
. , body .
, :
private static Int64 DirectoryBytes(String path, String searchPattern,
SearchOptionsearchOption) {
var files = Directory.EnumerateFiles(path, searchPattern, searchOption);
Int64 masterTotal = 0;
ParallelLoopResult result = Parallel.ForEach<String, Int64>(
files,
() => { // localInit:
774
27.
// : 0
return 0; // taskLocalTotal 0
},
(file, loopState, index, taskLocalTotal) => { // body:
//
//
Int64 fileLength = 0;
FileStreamfs = null;
try {
fs = File.OpenRead(file);
fileLength = fs.Length;
}
catch (IOException) { /* , */ }
finally { if (fs != null) fs.Dispose(); }
return taskLocalTotal + fileLength;
},
taskLocalTotal => { // localFinally:
//
Interlocked.Add(ref masterTotal, taskLocalTotal);
});
}
return masterTotal;
taskLocalTotal) . ,
.
Interlocked.Add ( 28).
, ,
.
Interlocked.Add.
, .
, , body
ParallelLoopState:
public class ParallelLoopState{
public void Stop();
public BooleanIsStopped { get; }
public void Break();
public Int64? LowestBreakIteration{ get; }
ParallelLoopState
775
. Stop ,
IsStopped true. Break
, . ,
ForEach 100, Break.
. ,
. LowestBreakIteration
, Break.
, null.
IsException true,
.
, ShouldExitCurrentIteration,
, . true, Stop Break,
CancellationTokenSource ( CancellationToken
ParallelOption)
.
For ForEach Parallel ParallelLoop
Result, :
public struct ParallelLoopResult{
// false
public Boolean IsCompleted { get; }
public Int64? LowestBreakIteration{ get; }
}
IsCompleted true, , ,
. IsCompleted false,
LowestBreakIteration null, , -
Stop. ,
LowestBreakIteration, null, , -
Break. LowestBreakIteration
Int64 .
AggregateException.
Microsoft (Language Integrated Query,
LINQ) . ,
. -
776
27.
(sequential query).
(Parallel LINQ),
(parallel query).
( , ),
.
Parallel,
.
Parallel LINQ System.
Linq.ParallelEnumerable ( System.Core.dll),
System.Linq. ,
LINQ-,
Where, Select, SelectMany, GroupBy, Join, OrderBy, Skip, Take ..
System.Linq.ParallelQuery<T>.
( IEnumerable IEnumerable<T>)
( ParallelQuery ParallelQuery<T>),
AsParallel ParallelEnumerable,
1:
public static ParallelQuery<TSource> AsParallel<TSource>(
this IEnumerable<TSource> source)
public static ParallelQuery AsParallel(this IEnumerablesource)
.
, :
private static void ObsoleteMethods(Assembly assembly) {
var query =
from type in assembly.GetExportedTypes().AsParallel()
from method in type.GetMethods(BindingFlags.Public |
BindingFlags.Instance | BindingFlags.Static)
let obsoleteAttrType = typeof(ObsoleteAttribute)
where Attribute.IsDefined(method, obsoleteAttrType)
orderbytype.FullName
let obsoleteAttrObj = (ObsoleteAttribute)
Attribute.GetCustomAttribute(method, obsoleteAttrType)
select String.Format("Type={0}\nMethod={1}\nMessage={2}\n",
ParallelQuery<T> ParallelQuery.
777
, .
AsSequential ParallelEnumerable:
public static IEnumerable<TSource> AsSequential<TSource>(
this ParallelQuery<TSource> source)
ParallelQuery<T> IEnumerable<T>,
.
LINQ- , foreach ( ). ,
.
ForAll ParallelEnumerable:
static void ForAll<TSource>(
this ParallelQuery<TSource> source, Action<TSource> action)
.
:
//
query.ForAll(Console.WriteLine);
Console.WriteLine
, Console
, ,
. ,
- . ForAll
, .
LINQ- , .
AsOrdered
ParallelEnumerable. , .
. , : Distinct, Except, Intersect, Union, Join,
GroupBy, GroupJoin ToLookup.
AsOrdered, .
: OrderBy ,
OrderByDescending, ThenBy ThenByDescending.
, ,
AsUnordered.
778
27.
Enumerable, :
, WithCancellation Cancellation
Token, .
WithDegreeOfParallelism , -
; ,
, . ,
.
, , ,
. -, , ,
.
, .
,
- .
Parallel LINQ . . :
Concat, ElementAt(OrDefault), First(OrDefault), Last(OrDefault), Skip(While),
Take(While) Zip. , Select(Many) Where,
, .
,
WithExecutionMode ParallelExecutionMode:
public enum ParallelExecutionMode {
Default = 0, //
ForceParallelism = 1 //
}
, Parallel LINQ , , .
WithMergeOptions ,
ParallelMergeOptions:
779
,
. NotBuffered ,
. FullyBuffered , .
AutoBuffered. ,
, .
, , . Parallel LINQ
:
http://blogs.msdn.com/pfxteam/archive/2009/05/28/9648672.aspx;
http://blogs.msdn.com/pfxteam/archive/2009/06/13/9741072.aspx.
System.Threading Timer,
. ,
, ,
. 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);
780
27.
state
; , null. dueTime
CLR ( ) . 32
, 64- TimeSpan.
, dueTime 0. period
() .
Timeout.Infinite(-1), .
Timer.
.
QueueUserWorkItem ThreadPool, , .
, .
. , period
Timeout.Infinite. .
Change , period Timeout.Infinite.
Change:
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);
}
Timer Dispose,
notifyObject .
Dispose:
public sealed class Timer : MarshalByRefObject, IDisposable {
public Boolean Dispose();
public Boolean Dispose(WaitHandle notifyObject);
}
Timer ,
. , ,
.
21.
781
,
, .
internal static class TimerDemo {
private static Timer s_timer;
public static void Main() {
Console.WriteLine("Checking status every 2 seconds");
// , . ,
// s_timer,
// Status
s_timer = new Timer(Status, null, Timeout.Infinite, Timeout.Infinite);
// , s_timer ,
// ; , Change Status
// NullReferenceException
s_timer.Change(0, Timeout.Infinite);
Console.ReadLine(); //
}
//
// TimerCallback
private static void Status(Object state) {
//
Console.WriteLine("In Status at {0}", DateTime.Now);
Thread.Sleep(1000); // (1 )
// 2
s_timer.Change(2000, Timeout.Infinite);
// ,
//
}
}
Delay Task C# async await (. 28).
:
internal static class DelayDemo {
public static void Main() {
Console.WriteLine("Checking status every 2 seconds");
Status();
Console.ReadLine(); //
}
//
private static async void Status() {
while (true) {
782
27.
FCL ,
, .
Timer System.Threading. . .
Timer System.Windows.Forms. Windows
(.Win32- SetTimer).
Windows
(WM_TIMER).
. ,
, .
.
DispatcherTimer System.Windows.Threading.
Timer System.
Windows.Forms Silverlight WPF.
DispatcherTimer Windows.UI.XAML.
Timer System.Windows.
Forms Windows Store.
Timer System.Timers. ,
, Timer System.Threading.
CLR . System.Timers.Timer
Component System.ComponentModel, Visual Studio.
, ,
Visual Studio. FCL ,
Microsoft .
, , System.Threading.
Timer. System.Timers.Timer
783
(
).
, -.
,
CLR . .
- ,
. , .
, ,
.
, ,
CLR. , .
CLR , . ,
, .
1000 ,
1001. 1000, , ,
.
, .
.
? -
.
- , , CLR
. 1000,
32- , 2 ,
.
Win32 CLR,
1,5 .
(TEB) 1
784
27.
. 27.1 ,
. ThreadPool.QueueUserWorkItem Timer .
.
,
, ,
. ,
.
( Default
TaskScheduler)1. Task
.
, .
, ,
Task . ,
. .
, ,
, TaskScheduler,
.
1
785
. ,
, .
. 27.1. CLR
, ,
. ,
.
,
. , ,
, , , . ,
.
, ( )
. .
, , (,
, TEB).
, ,
SetMinThreads ThreadPool.
( ), , .
(affinity mask) . -
786
27.
, ,
.
, ,
( ), .
.
28.
-
, , , . -,
. , ,
, .
, ,
-.
- Windows
, Microsoft Windows -. .28.1
.
. ,
, ,
,
.
,
FileStream. Read . Read
FileStream / , Win32
ReadFile (1). ,
- (I/O Request Packet, IRP) (2). , ,
, Byte[], ,
, ..
ReadFile Windows, IRP- (3).
,
-, IRP-
788
28. -
(4).
- . IRP-
, , ,
- (5).
. 28.1. - Windows
:
- , , , Windows ,
(6).
, ,
(Thread Environment Block, TEB) , .
. , , .
- Windows
,
, (7, 8 9).
Read FileStream Int32,
.
, Byte[], Read.
- Windows
789
-,
. .
, .
, , .
, . , -
( ), !
, .
,
, ,
. , .
-
Windows (.28.2). ,
, CLR . - FileStream,
FileOptions.Asynchronous, Windows,
.
BeginRead,
Read. ReadAsync Task<Int32>,
, Win32- ReadFile (1),
IRP-, , (2), Windows (3). Windows IRP- IRP-
(4), ,
BeginRead (5, 6 7). , IRP-, ReadAsync ,
Byte[].
,
? ReadAsync Task<Int32>.
, ContinueWith , ,
. C#,
(
-).
IRP- (a),
CLR- (b). - IRP (c)1. IRP-
.
1
790
28. -
, Byte[]
.
. 28.2. - Windows
, ,
. , . ,
, .
, ,
.
,
. ,
, .
, ,
!
, ,
. . ,
( -
- Windows
791
) -
1.
( -, Thread.Sleep ,
) Windows ,
. . ,
,
.
, ,
,
. , . , ,
, .
. , ,
, ,
.
CLR-
Windows, - (I/OCompletion Port).
CLR. , ,
IRP-. Windows via
C/C++ (Microsoft Press, 2007).
- .
, CLR .
, , .
, CLR . , ,
. , ,
, .
, 100%.
,
. . ,
. , Windows
, ,
.
1
792
28. -
. ,
, .
Windows .
, ,
. -
, .
. , 10.
5. (
) 50.
10
5! -
, , -
.
:
. Silverlight Windows Store
- ,
- ;
.
,
.
C#
,
.
.
, CLR ,
1.
, Microsoft .NET Framework 4.5, AsyncEnumerator ( Power Threading . http://
Wintellect.com/) .NET
Framework 4.5. , AsnycEnumerator Microsoft
, .
, AsyncEnumerator,
.
1
C#
793
.
private static async Task<String> IssueClientRequestAsync(String serverName,
String message)
{
using (var pipe = new NamedPipeClientStream(serverName, "PipeName",
PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough))
{
pipe.Connect(); // ReadMode,
pipe.ReadMode = PipeTransmissionMode.Message; // Connect
//
Byte[] request = Encoding.UTF8.GetBytes(message);
await pipe.WriteAsync(request, 0, request.Length);
//
Byte[] response = new Byte[1000];
Int32 bytesRead = await pipe.ReadAsync(response, 0, response.Length);
return Encoding.UTF8.GetString(response, 0, bytesRead);
} //
}
, IssueClientRequestAsync , async
static. async,
, (
).
, . , IssueClientRequestAsync
NamedPipeClientStream, Connect, ReadMode, Byte[]
WriteAsync . WriteAsync Task IssueClientRequestAsync. C# await ContinueWith Task ,
,
IssueClientRequestAsync.
. Task,
ContinueWith,
. , IssueClientRequestAsync,
await. , Task.
. ,
await . WriteAsync Task
Task<TResult>, .
794
28. -
795
, Monitor.Exit SynchronizationLockException
.
await
from
join.
. ,
.
, , .
, ,
.
internal sealed class Type1 { }
internal sealed class Type2 { }
private static async Task<Type1> Method1Async()
/* ,
}
private static async Task<Type2> Method2Async()
/* ,
}
{
Type1 */
{
Type2 */
,
.
private static async Task<String> MyMethodAsync(Int32 argument) {
Int32 local = argument;
try {
Type1 result1 = await Method1Async();
for (Int32 x = 0; x < 3; x++) {
Type2 result2 = await Method2Async();
}
}
catch (Exception) {
Console.WriteLine("Catch");
}
finally {
Console.WriteLine("Finally");
}
return "Done";
}
796
28. -
MyMethodAsync , . -,
Task<String>, String. -,
, ,
for. , .
MyMethodAsync
.
, , IL-
C#.
, ,
. , .
MyMethodAsync,
, .
// AsyncStateMachine
// ( , );
// , .
[DebuggerStepThrough, AsyncStateMachine(typeof(StateMachine))]
private static Task<String> MyMethodAsync(Int32 argument) {
//
StateMachine stateMachine = new StateMachine() {
// , Task<String>.
//
// .
m_builder = AsyncTaskMethodBuilder<String>.Create(),
m_state =
1, //
m_argument = argument //
}; //
// .
stateMachine.m_builder.Start(ref stateMachine);
return stateMachine.m_builder.Task; //
} //
//
[CompilerGenerated, StructLayout(LayoutKind.Auto)]
private struct StateMachine : IAsyncStateMachine {
// (Task)
public AsyncTaskMethodBuilder<String> m_builder;
public Int32 m_state;
// :
public Int32 m_argument, m_local, m_x;
public Type1 m_resultType1;
public Type2 m_resultType2;
//
//
//
//
Awaiter.
.
await,
:
797
798
28. -
m_resultType1 = awaiterType1.GetResult(); //
ForLoopPrologue:
m_x = 0; // 'for'
goto ForLoopBody; // 'for'
ForLoopEpilog:
m_resultType2 = awaiterType2.GetResult();
m_x++; // x
// 'for'
ForLoopBody:
if (m_x < 3) { // 'for'
// Method2Async
awaiterType2 = Method2Async().GetAwaiter();
if (!awaiterType2.IsCompleted) {
m_state = 1; // 'Method2Async'
//
m_awaiterType2 = awaiterType2; //
//
// MoveNext
m_builder.AwaitUnsafeOnCompleted(ref awaiterType2, ref this);
executeFinally = false; //
// 'try'
return; //
} //
// 'Method2Async'
goto ForLoopEpilog; // ,
}
}
catch (Exception) {
Console.WriteLine("Catch");
}
finally {
// , 'try',
// 'finally'.
//
// 'try'.
if (executeFinally) {
Console.WriteLine("Finally");
}
}
result = "Done"; // ,
} // .
catch (Exception exception) {
// :
// .
m_builder.SetException(exception);
return;
}
// :
799
m_builder.SetResult(result);
, ,
, . ,
. ,
await,
GetAwaiter. ,
. , GetAwaiter,
(awaiter).
,
IsCompleted. ,
true, . GetResult ,
, ,
.
.
, IsCompleted false.
OnCompleted , MoveNext .
, . ,
Task, ,
MoveNext.
, ,
. GetResult
.
, .
, Task ,
, await
. (Task ) ,
( WhenAll WhenAny Task)
. CancellationToken Task,
await - .
. TaskLogger,
-
800
28. -
. , -
.
public static class TaskLogger {
public enum TaskLogLevel { None, Pending }
public static TaskLogLevel LogLevel { get; set; }
public sealed class TaskLogEntry {
public Task Task { get; internal set; }
public String Tag { get; internal set; }
public DateTime LogTime { get; internal set; }
public String CallerMemberName { get; internal set; }
public String CallerFilePath { get; internal set; }
public Int32 CallerLineNumber { get; internal set; }
public override string ToString() {
return String.Format("LogTime={0}, Tag={1}, Member={2}, File={3}({4})",
LogTime, Tag ?? "(none)", CallerMemberName, CallerFilePath,
CallerLineNumber);
}
}
private static readonly ConcurrentDictionary<Task, TaskLogEntry> s_log =
new ConcurrentDictionary<Task, TaskLogEntry>();
public static IEnumerable<TaskLogEntry> GetLogEntries() { return s_log.Values; }
public static Task<TResult> Log<TResult>(this Task<TResult> task,
String tag = null,
[CallerMemberName] String callerMemberName = null,
[CallerFilePath] String callerFilePath = null,
[CallerLineNumber] Int32 callerLineNumber = 1
) {
return (Task<TResult>)
Log((Task)task, tag, callerMemberName, callerFilePath, callerLineNumber);
}
public static Task Log(this Task task, String tag = null,
[CallerMemberName] String callerMemberName = null,
[CallerFilePath] String callerFilePath = null,
[CallerLineNumber] Int32 callerLineNumber = 1
) {
if (LogLevel == TaskLogLevel.None) return task;
var logEntry = new TaskLogEntry {
Task = task,
LogTime = DateTime.Now,
Tag = tag,
CallerMemberName = callerMemberName,
CallerFilePath = callerFilePath,
CallerLineNumber = callerLineNumber
};
s_log[task] = logEntry;
task.ContinueWith(t => { TaskLogEntry entry;
s_log.TryRemove(t, out entry); },
TaskContinuationOptions.ExecuteSynchronously);
return task;
}
}
801
:
public static async Task Go() {
#if DEBUG
// TaskLogger
// ;
TaskLogger.LogLevel = TaskLogger.TaskLogLevel.Pending;
#endif
// 3 ; TaskLogger
// .
var tasks = new List<Task> {
Task.Delay(2000).Log("2s op"),
Task.Delay(5000).Log("5s op"),
Task.Delay(6000).Log("6s op")
};
try {
// 3 ;
// .
// : WithCancellation - ,
// .
await Task.WhenAll(tasks).
WithCancellation(new CancellationTokenSource(3000).Token);
}
catch (OperationCanceledException) { }
//
//
foreach (var op in TaskLogger.GetLogEntries().OrderBy(tle => tle.LogTime))
Console.WriteLine(op);
}
, :
LogTime=7/16/2012 6:44:31 AM, Tag=6s op, Member=Go,
File=C:\CLR via C#\Code\Ch28
1I
OOps.cs(332)
LogTime=7/16/2012 6:44:31 AM, Tag=5s op, Member=Go,
File=C:\CLR via C#\Code\Ch28
1I
OOps.cs(331)
, Task, : GetAwaiter
, await . ,
Task; ,
GetAwaiter. ,
async- .
public sealed class EventAwaiter<TEventArgs> : INotifyCompletion {
private ConcurrentQueue<TEventArgs> m_events = new ConcurrentQueue<TEventArgs>();
private Action m_continuation;
#region ,
//
// ;
public EventAwaiter<TEventArgs> GetAwaiter() { return this; }
802
28. -
// , -
public Boolean IsCompleted { get { return m_events.Count > 0; } }
// , ;
//
public void OnCompleted(Action continuation) {
Volatile.Write(ref m_continuation, continuation);
}
// ,
// await
public TEventArgs GetResult() {
TEventArgs e;
m_events.TryDequeue(out e);
return e;
}
#endregion
// ,
//
public void EventRaised(Object sender, TEventArgs eventArgs) {
m_events.Enqueue(eventArgs); // EventArgs
// GetResult/await
// ,
Action continuation = Interlocked.Exchange(ref m_continuation, null);
if (continuation != null) continuation(); //
} //
}
EventAwaiter
await .
.
private static async void ShowExceptions() {
var eventAwaiter = new EventAwaiter<FirstChanceExceptionEventArgs>();
AppDomain.CurrentDomain.FirstChanceException += eventAwaiter.EventRaised;
while (true) {
Console.WriteLine("AppDomain exception: {0}",
(await eventAwaiter).Exception.GetType());
}
}
, , , :
public static void Go() {
ShowExceptions();
for (Int32 x = 0; x < 3; x++) {
try {
switch (x) {
803
}
}
catch { }
Task
Task<Result>, .
void.
, C#
: .
:
void EventHandlerCallback(Object sender, EventArgs e);
- , , . , -
.
void C#
void, await
-.
void,
, Task,
. ,
, void, 1.
804
28. -
FCL
, ,
FCL. ,
Async. FCL
, -,
XxxAsync. 1:
System.IO.Stream ReadAsync,
WriteAsync, FlushAsync CopyToAsync.
System.IO.textReader
ReadAsync, ReadLineAsync, ReadToEndAsync ReadBlockAsync. , System.IO.TextWriter, WriteAsync, Write
LineAsync FlushAsync.
System.Net.Http.HttpClient GetAsync, Get
StreamAsync, GetByteArrayAsync, PostAsync, PutAsync, DeleteAsync .
System.Net.WebRequest ( FileWebRequest,
FtpWebRequest HttpWebRequest) GetRequestStreamAsync
GetResponseAsync.
System.Data.SqlClient.SqlCommand Exe
cuteDbDataReaderAsync , ExecuteNonQueryAsync , ExecuteReaderAsync ,
ExecuteScalarAsync ExecuteXmlReaderAsync.
(, SvcUtil.exe), , XxxAsync.
.NET Framework
, , , BeginXxx EndXxx
IAsyncResult. , XxxAsync
( Task)
. ,
Task.
FCL, ,
XxxAsync, BeginXxx EndXxx.
, Microsoft
WinRT
IAsyncInfo. , .NET Framework , IAsyncInfo Task.
WinRT API 25.
1
FCL
805
. , .
,
BeginXxx/EndXxx Task.
,
. .
private static async void StartServer() {
while (true) {
var pipe = new NamedPipeServerStream(c_pipeName, PipeDirection.InOut,
1,
PipeTransmissionMode.Message, PipeOptions.Asynchronous |
PipeOptions.WriteThrough);
// .
// : NamedPipeServerStream
// .
// Task
// FromAsync TaskFactory.
await Task.Factory.FromAsync(pipe.BeginWaitForConnection,
pipe.EndWaitForConnection, null);
// ; ,
// .
ServiceClientRequestAsync(pipe);
}
}
NamedPipeServerStream BeginWaitForConnection
EndWaitForConnection, WaitForConnectionAsync.
, FCL. ,
, FromAsync TaskScheduler,
BeginXxx EndXxx, FromAsync
Task, . Task
await1.
FCL , Task,
. , WebClient ( )
TaskCompletionSource, await
.
private static async Task<String> AwaitWebClient(Uri uri) {
// System.Net.WebClient
FromAsync TaskScheduler ,
IAsyncResult, , BeginXxx
EndXxx. IAsyncResult,
.
1
806
28. -
//
var wc = new System.Net.WebClient();
// TaskCompletionSource Task
var tcs = new TaskCompletionSource<String>();
// WebClient
// DownloadStringCompleted, TaskCompletionSource
wc.DownloadStringCompleted += (s, e) => {
if (e.Cancelled) tcs.SetCanceled();
else if (e.Error != null) tcs.SetException(e.Error);
else tcs.SetResult(e.Result);
};
//
wc.DownloadStringAsync(uri);
// Task TaskCompletionSource
// .
String result = await tcs.Task;
// ( )...
}
return result;
-
, Windows . , , -.
, ,
. IRP- CLR- , Task .
await ,
, .
27 , Task
AggregateException, InnerExceptions . await Task AggregateException
1. ,
. ,
AggregateException , , . .
: GetResult TaskAwaiter.
807
, Task, , -
. ,
Task, .
void;
. ,
, void,
(. ). , .
.
. Microsoft Visual Studio
. await,
(F10)
.
, , !
.
, (F11)
, (Shift+F11); ,
.
Shift+F11 ,
.
, ,
(F5).
, , ,
.
, ; .
, , await,
.
, ,
.
, , , ,
.
, .
,
808
28. -
. ,
,
Run Task:
// Task.Run
Task.Run(async () => {
//
// TODO: ...
await XxxAsync(); //
// ...
});
C#:
-. , awat
-,
. async - - ,
Task Task<TResult>,
Func Task Task<TResult>.
async, await:
static async Task OuterAsyncFunction() {
InnerAsyncFunction(); // await!
// , InnerAsyncFunction...
}
static async Task InnerAsyncFunction() { /* ... */ }
, C# await . ,
, InnerAsyncFunction,
.
, Task, InnerAsyncFunction. 1.
static async Task OuterAsyncFunction() {
var noWarning = InnerAsyncFunction(); // await
// , InnerAsyncFunction...
}
, :
[MethodImpl(MethodImplOptions.AggressiveInlining)] //
//
public static void NoWarning(this Task task) { /* */ }
, ,
.
1
809
:
static async Task OuterAsyncFunction() {
InnerAsyncFunction().NoWarning(); // await
// , InnerAsyncFunction...
}
-
: , . . ,
, .
:
public static async Task Go() {
// ,
//
StartServer(); // void,
// ;
// Task<String> .
List<Task<String>> requests = new List<Task<String>>(10000);
for (Int32 n = 0; n < requests.Capacity; n++)
requests.Add(IssueClientRequestAsync("localhost", "Request #" + n));
//
// : 1+ ,
// WhenAll
String[] responses = await Task.WhenAll(requests);
//
for (Int32 n = 0; n < responses.Length; n++)
Console.WriteLine(responses[n]);
}
,
, for 10000 . IssueClientRequestAsync
Task<String>, ,
, , 1. ,
, Task<String>
, .
: ,
8- , , 100%. , , !
, .
1
810
28. -
, .
WhenAll Task.
Task<String[]>,
Task List. await Task<String[]>, . (
Console.WriteLine).
,
, .
WhenAny Task.
:
public static async Task Go() {
// ,
//
StartServer();
// ;
// Task<String> .
List<Task<String>> requests = new List<Task<String>>(10000);
for (Int32 n = 0; n < requests.Capacity; n++)
requests.Add(IssueClientRequestAsync("localhost", "Request #" + n));
//
while (requests.Count > 0) {
//
Task<String> response = await Task.WhenAny(requests);
requests.Remove(response); //
//
Console.WriteLine(response.Result);
}
}
while, .
await WhenAny Task,
Task<String> , .
Task<String> ,
( Console.WriteLine).
.NET Framework ,
. Windows- (
811
, )
; , .
(GUI),
Windows Forms, Windows Presentation Foundation (WPF),
Silverlight Windows Store, ,
. GUI-
,
, , , .
Task, .
,
. (,
) ,
. -
.
ASP.NET , .
,
(System.Globalization.CultureInfo),
, 1.
- (System.
Security.Principal.IPrincipal), ,
. , .
,
,
, ,
.
, FCL System.Threading.Synchronization
Context, . ,
, . FCL
, SynchronizationContext,
; , .
SynchronizationContext. await Task
SynchronizationContext .
Task, SynchronizationContext,
. , GUI-
await Task, , await,
GUI-,
http://msdn.microsoft.
com/ru-ru/library/bz9tc508.aspx.
1
812
28. -
. ASP.NET , await, ,
.
. ,
.
WPF:
private sealed class MyWpfWindow : Window {
public MyWpfWindow() { Title = "WPF Window"; }
protected override void OnActivated(EventArgs e) {
// Result GUI- ;
//
String http = GetHttp().Result; //
}
base.OnActivated(e);
, , SynchronizationContext.
, . , , SynchronizationContext.
, ,
.
Task Task<TResult>
ConfigureAwait :
// Task :
public ConfiguredTaskAwaitable
ConfigureAwait(Boolean continueOnCapturedContext);
// Task<TResult> :
public ConfiguredTaskAwaitable<TResult>
ConfigureAwait(Boolean continueOnCapturedContext);
813
SynchronizationContext , Task,
await .
GetHttp ,
ConfigureAwait.
GetHttp :
private async Task<String> GetHttp() {
// HTTP GetHttp
HttpResponseMessage msg = await new
HttpClient().GetAsync("http://Wintellect.com/")
.ConfigureAwait(false);
// ,
// ( GUI-).
}
, ConfigureAwait(false)
Task, await. ,
, ,
; ,
SynchronizationContext,
. ,
.
GetHttp , , :
private Task<String> GetHttp() {
return Task.Run(async () => {
// ,
// SynchronizationContext
HttpResponseMessage msg = await new
HttpClient().GetAsync("http://Wintellect.com/");
return await msg.Content.ReadAsStringAsync();
});
}
: GetHttp
; async ,
await. , -, Task.Run, .
,
.NET Framework,
814
28. -
.
, ,
, MSDN.
Web Forms ASP.NET:
.aspx Async=true page
RegisterAsyncTask System.Web.UI.Page.
MVC- ASP.NET:
System.Web.Mvc.AsyncController
Task<ActionResult> .
ASP.NET:
System.Web.HttpTaskAsyncHandler
ProcessRequestAsync.
WCF:
, Task Task<TResult>.
-
Windows -. ,
. ,
, , ;
. ,
, .
?
, , .
WithCancellation, Task<TResult> (
, Task) :
private struct Void { } // -
// TaskCompletionSource.
private static async Task<TResult>
WithCancellation<TResult>(this Task<TResult> originalTask,
CancellationToken ct) {
// Task, CancellationToken
var cancelTask = new TaskCompletionSource<Void>();
// CancellationToken Task
using (ct.Register(
815
:
public static async Task Go() {
// CancellationTokenSource,
//
var cts = new CancellationTokenSource(5000); // ,
var ct = cts.Token; // cts.Cancel()
try {
// Task.Delay ; ,
// Task
await Task.Delay(10000).WithCancellation(ct);
Console.WriteLine("Task completed");
}
catch (OperationCanceledException) {
Console.WriteLine("Task cancelled");
}
}
Win32 API , -. , . ,
Win32- CreateFile ( FileStream) . CreateFile
. ,
, Win32-,
, . , Win32 , CreateFile, , , FCL
. Windows
816
28. -
, ,
/, / ..
, .
,
( ). ,
, Windows .
,
,
. Windows Vista Win32- CancelSynchronousIO.
-, . FCL,
, P/Invoke.
P/Invoke .
,
, .
.
- , -, Windows Runtime Windows
/ . ,
Windows Runtime API (.
OpenAsync Windows.Storage.StorageFile). Windows Runtime
API /. ,
C# .
FileStream
FileStream FileOptions.Asynchronous ,
( Win32- CreateFile
FILE_FLAG_OVERLAPPED). Windows
. ,
ReadAsync FileStream.
, FileStream
,
.
FileStream, FileOptions.
Asynchronous. Read FileStream
. FileStream ,
. ,
817
, BeginRead FileStream,
FileOptions.Asynchronous.
. FileStream ,
- ,
FileOptions.Asynchronous ( ). ,
ReadAsync, Read.
.
FileStream, FileOptions.Asynchronous.
FileStream . FileStream
-, . ,
System.IO.File (Create, Open OpenWrite),
FileStream.
FileOptions.Asynchronous,
.
, NTFS
.
http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B156932.
-
26 ,
. - . ,
.
, ,
, .
, ,
, ..1
Windows . http://www.
microsoft.com/whdc/driver/priorityio.mspx. ,
FCL; , .
P/Invoking. :
Windows- SuperFetch -
.
1
818
28. -
819
, :
public static void Main () {
using (ThreadIO.BeginBackgroundProcessing()) {
// -
// (, BeginRead/BeginWrite)
}
}
, ,
. - , ,
- .
, ,
.
-.
( ). , -
, .
29.
, ;
( ) , . ,
, ,
- . ,
. 27
, ,
28 -.
.
. ,
.
, , . 28 ,
. ,
.
, ,
, ,
.
,
. -,
. ,
. ,
. ,
.
,
. ,
. , , .
-
821
, ,
,
.
.
,
,
, , .
.
, , :
// LinkedList
public class Node {
internal Node m_next;
//
}
public sealed class LinkedList {
private Node m_head;
public void Add(Node newNode) {
//
newNode.m_next = m_head;
m_head = newNode;
}
}
Add .
,
,
Add :
public sealed class LinkedList {
private SomeKindOfLock m_lock = new SomeKindOfLock();
private Node m_head;
public void Add(Node newNode) {
m_lock.Acquire();
//
newNode.m_next = m_head;
m_head = newNode;
m_lock.Release();
}
}
Add , .
;
, . Add
. , Add
822
29.
.
, . ,
, , ,
.
, ,
. 26,
. ,
;
, ,
, , , , .
, ,
,
. , .
new,
. ,
. ,
, ,
.
,
, . ,
,
, . , . , ;
,
, , .
String. , ,
.
. FCL Microsoft
. ,
.
FCL,
, .
823
Console ,
, ,
.
, , , ,
.
. System.Math
Max, :
public static Int32 Max(Int32 val1, Int32 val2) {
return (val1 < val2) ? val2 : val1;
}
, . Int32 ,
Max , , .
, .
FCL ,
. ,
, , ,
. , ,
, , .
, ,
. (
, ThreadPool.
QueueUserWorkItem Task ..), ,
.
, . , , ,
. ,
, Cancel CancellationTokenSource, , IsCancellationRequested
CancellationToken, , .
,
1.
, , volatile,
.
1
824
29.
. ,
. : .
,
. (
). ,
Windows .
,
. ,
.
, ? , ,
. ,
. Windows
, .
, . ,
, , .
,
.
.
Windows
, . ,
1.
.
, , Windows , . ,
, , .
, , ,
.
;
() (livelock),
, .
825
. ,
() (deadlock). -
, , , ,
( ..), 1.
,
: ( ) . , .
,
(hybrid constructs), .
,
.
, . ,
.
CLR - ,
Win32. , CLR-
Windows, . 1992
2, .
CLR : Boolean,
Char, (S)Byte, (U)Int16, (U)Int32, (U)IntPtr, Single . , . , :
internal static class SomeType {
public static Int32 x = 0;
}
- , x
() 0x00000000 0x01234567:
SomeType.x = 0x01234567;
, ,
.
2
Windows via C/C++ (Microsoft Press, 2007) .
1
826
29.
(torn read).
, , -
, .
, ,
. ,
U(Int64) Double.
:
Volatile- ,
, .
Interlocked- , , .
( ) , .
Volatile-
, . ,
: ,
, ..
.
if/else, switch/case, , ,
, , .
, , .
, C# C# (Intermediate Language, IL), , ,
JIT- , . C#, JIT-
. , :
827
, 0, ,
. . ,
, OptimizedAway, JIT-
OptimizedAway, ,
. . ;
, .
, . ,
.
C#, JIT- .
, , .
. ,
, :
internal static class StrangeBehavior {
// , volatile
private static Boolean s_stopWorker = false;
public static void Main() {
Console.WriteLine("Main: letting worker run for 5 seconds");
Thread t = new Thread(Worker);
t.Start();
Thread.Sleep(5000);
s_stopWorker = true;
Console.WriteLine("Main: waiting for worker to stop");
t.Join();
}
private static void Worker(Object o) {
Int32 x = 0;
while (!s_stopWorker) x++;
Console.WriteLine("Worker: stopped when x={0}", x);
}
}
828
29.
Main ,
Worker, , .
Main Worker 5, , Boolean true.
Worker , .
Main Worker, Join, Main , .
, ?
- . Worker , s_stopWorker true false,
.
, s_stopWorker.
true, "Worker: stopped when x=0". ,
x.
, s_stopWorker
, .
, , .cs platform:x86 /optimize+ C#.
,
. , JIT-
x86, x64 IA64, ,
. JIT
, .
:
, , JIT-, ,
. , ,
, JIT- , .
,
:
internal sealed class ThreadsSharingData {
private Int32 m_flag = 0;
private Int32 m_value = 0;
//
public void Thread1() {
// .
m_value = 5;
m_flag = 1;
}
//
829
, , Thread1 .
, . 5 m_value 1 m_flag.
.
, ,
Thread2, , m_flag 1,
0.
. ,
Thread1 , ( , ). Thread2, ,
m_flag m_value . ,
m_value, 0. Thread1,
m_value 5, m_flag 1. Thread2 , m_value
5.
m_flag, 1.
Thread2 0.
, , , .
.
, .
System.Threading.Volatile ,
1:
public sealed class Volatile {
public static void Write(ref Int32 location, Int32 value);
public static Int32 Read(ref Int32 location);
}
, ,
C#, JIT- .
:
VolatileRead VolatileWrite, : Boolean, (S)Byte, (U)Int16, UInt32, (U)Int64, (U)IntPtr, Single, Double
T, T 'class' ( ).
1
830
29.
Volatile.Write location . .
Volatile.Read address .
.
, :
Volatile.
Write, Volatile.Read.
ThreadsSharing
Data:
. Thread1 , .
, ( m_flag 1),
Volatile.Write. Thread2 , (m_flag)
Volatile.Read.
? Thread1
Volatile.Write , 1 m_flag. m_value = 5
Volatile.Write, . ,
Volatile.
Write, 1
831
m_flag. ,
; , Volatile.Write.
Volatile.Read Thread2 ,
m_flag.
m_value Volatile.Read,
m_flag.
,
Volatile.Read. Volatile.Read
, ; Volatile.Read.
Volatile C#
, Volatile.
Read Volatile.Write ? , ,
.
C# volatile,
Boolean, (S)Byte, (U)Int16, (U)Int32,
(U)IntPtr, Single Char.
, (S)Byte, (U)Int16
(U)Int32. JIT- , ,
, ,
Read Write Volatile
. , volatile C# JIT- .
,
.
volatile ThreadsSharingData
:
internal sealed class ThreadsSharingData {
private volatile Int32 m_flag = 0;
private
Int32 m_value = 0;
//
public void Thread1() {
// . 5 m_value
// 1 m_flag
m_value = 5;
m_flag = 1;
}
//
public void Thread2() {
// . m_value m_flag
if (m_flag == 1)
Console.WriteLine(m_value);
}
}
832
29.
( ) volatile
, C#1. , .
, . ,
volatile, . , ,
:
m_amount = m_amount + m_amount; // , m_amount
// volatile
,
. m_amount volatile, . ,
m_amount , ,
m_amount.
; .
C# .
, Int32 m_amount
Int32.TryParse, :
Boolean success = Int32.TryParse("123", out m_amount);
// :
// CS0420:
, volatile CLS,
( Visual Basic).
Interlocked-
, Read Volatile
, Write .
, .
System.Threading.Interlocked.
, .
, Interlocked ,
Interlocked
, .
, Int32,
. :
public static class Interlocked {
// (++location)
833
834
29.
//
var httpClient = new HttpClient();
foreach (var server in m_servers.Keys) {
m_ac.AboutToBegin(1);
httpClient.GetByteArrayAsync(server)
.ContinueWith(task => ComputeResult(server, task));
}
// AsyncCoordinator,
// AllDone ,
// Cancel -
m_ac.AllBegun(AllDone, timeout);
}
private void ComputeResult(String server, Task<Byte[]> task) {
Object result;
if (task.Exception != null) {
result = task.Exception.InnerException;
} else {
// - - (-)
// ...
result = task.Result.Length; //
} //
// (/)
//
m_servers[server] = result;
m_ac.JustEnded();
}
//
public void Cancel() { m_ac.Cancel(); }
// -,
// Cancel -
private void AllDone(CoordinationStatus status) {
switch (status) {
case CoordinationStatus.Cancel:
Console.WriteLine("Operation canceled.");
break;
case CoordinationStatus.Timeout:
Console.WriteLine("Operation timed
out.");
break;
case CoordinationStatus.AllDone:
Console.WriteLine("Operation completed; results below:");
foreach (var server in m_servers) {
Console.Write("{0} ", server.Key);
Object result = server.Value;
if (result is Exception) {
Console.WriteLine("failed due to {0}.", result.GetType().Name);
} else {
835
}
break;
Interlocked-, AsyncCoordinator.
, , .
MultiWebRequest AsyncCoordinator
URI ( ).
-. AboutToBegin AsyncCoordinator,
1.
GetByteArrayAsync HttpClient.
Task, ContinueWith,
ComputeResult . AllBegun AsyncCoordinator,
, (AllDone),
-, -.
ComputeResult MultiWebRequests.
, ( ), .
JustEnded AsyncCoordinator, AsyncCoordinator
.
AsyncCoordinator
AllDone , -.
, .
AllDone
, AsyncCoordinator ,
, , Cancel. , , , AllDone,
AllBegin.
, , , AllBegun,
Cancel. , AsyncCoordinator , , AllDone
. AllDone
, ,
CoordinationStatus:
internal enum CoordinationStatus { AllDone, Timeout, Cancel };
, m_ac.AboutToBeging(m_requests.
Length) AboutToBegin .
1
836
29.
, , , ,
. AsyncCoordinator . Interlocked,
. :
internal sealed class AsyncCoordinator {
private Int32 m_opCount = 1; // 1 AllBegun
private Int32 m_statusReported = 0; // 0=false, 1=true
private Action<CoordinationStatus> m_callback;
private Timer m_timer;
//
public void AboutToBegin(Int32 opsToAdd = 1) {
Interlocked.Add(ref m_opCount, opsToAdd);
}
//
public void JustEnded() {
if (Interlocked.Decrement(ref m_opCount) == 0)
ReportStatus(CoordinationStatus.AllDone);
}
//
public void AllBegun(Action<CoordinationStatus> callback,
Int32 timeout = Timeout.Infinite) {
m_callback = callback;
if (timeout != Timeout.Infinite)
m_timer = new Timer(TimeExpired, null, timeout, Timeout.Infinite);
JustEnded();
}
private void TimeExpired(Object o) {
ReportStatus(CoordinationStatus.Timeout);
}
public void Cancel() { ReportStatus(CoordinationStatus.Cancel); }
private void ReportStatus(CoordinationStatus status) {
// , ;
//
if (Interlocked.Exchange(ref m_statusReported, 1) == 0)
m_callback(status);
}
}
m_opCount.
, .
AboutToBegin. Interlocked.
Add, m_opCount .
, -
.
837
JustEnded. Interlocked.Decrement
m_opCount . , m_opCount 0, ReportStatus.
m_opCount 1 ( 0); ,
, AllDone , . AllBegun
m_opCount 0.
AllBegun, , JustEnded,
m_opCount 1
1. m_opCount
0,
-.
ReportStatus , ,
Cancel. , , m_callback
. Interlocked.Exchange
m_statusReported. Boolean;
, Interlocked Boolean. Int32,
0 false, 1 true.
ReportStatus Interlocked.Exchange
m_statusReported 1.
, Interlocked.Exchange 0,
. ,
Interlocked.Exchange, 1, , ,
.
Interlocked- , Int32.
,
?
, . Interlocked- :
internal struct SimpleSpinLock {
private Int32 m_ResourceInUse; // 0=false ( ), 1=true
public void Enter() {
while (true) {
// , .
838
29.
//
//
if
//
}
}
,
(Interlocked.Exchange(ref m_ResourceInUse, 1) == 0) return;
- ...
, SimpleSpinLock:
public sealed class SomeResource {
private SimpleSpinLock m_sl = new SimpleSpinLock();
public void AccessResource() {
m_sl.Enter();
// ...
m_sl.Leave();
}
}
SimpleSpinLock .
Enter, Interlocked.Exchange ,
m_resourceInUse 0 1. , m_resourceInUse 0, Enter ,
AccessResource.
m_resourceInUse 1.
, 0, ,
Exchange , Leave.
SomeResource, Leave, , ,
Volatile.Write m_resourceInUse 0.
m_resourceInUse 0 1 ,
, Enter,
SomeResource.
.
. , ,
,
. ,
.
, - . , ,
839
, , ,
. , . Windows . ,
, .
PriorityBoostEnabled System.Diagnostics.Process System.
Diagnostics.ProcessThread.
. .
, .
, FCL System.Threading.SpinWait,
.
, ,
, ,
, . SpinWait
Sleep, Yield SpinWait Thread.
.
,
. Sleep:
public static void Sleep(Int32 millisecondsTimeout);
public static void Sleep(TimeSpan timeout);
Sleep -
. .
, 100,
,
. , Windows
. , , ,
.
millisecondsTimeout Sleep
System.Threading.Timeout.Infinite ( 1).
. , .
Sleep 0 ,
. ,
,
Sleep.
840
29.
Windows
, Yield Thread:
public static Boolean Yield();
, ,
true, , .
Yield . ,
, Yield false,
.
Yield
. ,
, . , Windows
, . ,
Yield ,
.
Thread.Sleep(0) Thread.Sleep(1).
,
Thread.Sleep(1) ,
Windows 1,
.
. , ,
. , , SpinWait Thread:
public static void SpinWait(Int32 iterations);
,
. Windows - (
, ).
,
.
841
FCL System.Threading.SpinLock ,
SimpleSpinLock.
SpinWait . SpinLock
. ,
SimpleSpinLock SpinLock FCL .
, .
SpinLock , , ,
.
, SpinLock ,
, - .
SpinLock,
(readonly),
.
Interlocked-
, Interlocked-, , Microsoft ,
. , Interlocked
Multiple, Divide, Minimum, Maximum, And, Or, Xor
. ,
Interlocked.CompareExchange
Int32.
Int64, Single, Double, Object,
, .
Maximum:
public static Int32 Maximum(ref Int32 target, Int32 value) {
Int32 currentVal = target, startVal, desiredVal;
// target ,
//
do {
//
startVal = currentVal;
// startVal value
desiredVal = Math.Max(startVal, value);
// . !
// if (target == startVal) target = desiredVal
// ,
currentVal = Interlocked.CompareExchange(
ref target, desiredVal, startVal);
// ,
} while (startVal != currentVal);
842
29.
// ,
return desiredVal;
}
, . ,
, currentVal
target.
startVal.
.
. ,
desiredVal.
startVal value.
, target
. , . ,
derivedVal startVal, target, ,
. ,
target desiredVal ,
,
Interlocked.CompareExchange. ,
target startVal ( target ).
target , CompareExchange
desiredVal. , CompareExchange
target.
CompareExchange target
, currentVal. startVal currentVal.
target ,
desiredVal, while ,
. , ,
target,
desiredVal,
currentVal,
, .
Morph1:
delegate Int32 Morpher<TResult, TArgument>(
Int32 startValue, TArgument argument,
out TResult morphResult);
843
Windows
. ,
. ,
, ,
. .
, :
, Windows
, , .
.
, .
, .
,
.
, ;
,
.
(events) (semaphores).
844
29.
,
(mutex). Windows via
C/C++ (Microsoft Press, 2007).
System.Threading
WaitHandle. Windows. FCL .
System.Threading MSCorLib.dll.
Semaphore, System.dll. :
WaitHandle
EventWaitHandle
AutoResetEvent
ManualResetEvent
Semaphore
Mutex
845
:
WaitOne WaitHandle
. Win32- WaitForSingleObjectEx.
true , .
, false.
WaitAll WaitHandle
, WaitHandle[].
, true,
false.
Win32- WaitForMultipleObjectsEx,
bWaitAll TRUE.
WaitAny WaitHandle
,
WaitHandle[] . Int32 .
, WaitHandle.WaitTimeout.
Win32- WaitForMultipleObjectsEx,
bWaitAll FALSE.
Dispose .
Win32 CloseHandle. Dispose
, ,
. ,
Dispose; .
, , .
(apartment)
. , Windows-,
. COM. . , .
29, ,
.
846
29.
.
, AutoResetEvent, ManualResetEvent, Semaphore
Mutex WaitHandle,
. , , .
-, Win32-
CreateEvent ( bManualReset FALSE), CreateEvent
( bManualReset TRUE ), CreateSemaphore
CreateMutex. , ,
SafeWaitHandle, WaitHandle.
-, EventWaitHandle, Semaphore Mutex
OpenExisting, Win32- OpenEvent, OpenSemaphore
OpenMutex, String .
, ,
, OpenExisting.
WaitHandleCannotBeOpenedExcep
tion.
, .
Microsoft Office Outlook, Windows Live
Messenger, Windows Media Player Windows Media Center.
:
using System;
using System.Threading;
public static class Program {
public static void Main() {
Boolean createdNew;
//
using (new Semaphore(0, 1, "SomeUniqueStringIdentifyingMyApp",
out createdNew)) {
if (createdNew) {
// ,
// . ...
} else {
// ;
// .
// , Main,
//
}
}
}
}
847
Semaphore,
EventWaitHandle Mutex, .
. ,
. ,
. , Semaphore ( SomeUniqueStringIdentifyingMyApp). Windows
; createdNew
true.
Windows ,
; ,
. , ,
, .
.
, createdNew
false. , ,
.
(events) Boolean,
. ,
false, true. . true,
,
false. true
, ,
false ,
. , :
public class EventWaitHandle
public Boolean Set(); //
//
public Boolean Reset(); //
//
}
: WaitHandle {
Boolean true;
true
Boolean false;
true
848
29.
,
SimpleSpinLock:
internal sealed class SimpleWaitLock : IDisposable {
private readonly AutoResetEvent m_available;
public SimpleWaitLock() {
m_available = new AutoResetEvent(true); //
}
public void Enter() {
//
m_available.WaitOne();
}
public void Leave() {
//
m_available.Set();
}
}
SimpleWaitLock ,
SimpleSpinLock. , ; -
.
SimpleWaitLock
SimpleSpinLock, Enter
Leave .
, . ,
AutoResetEvent Dispose,
. , ,
.
, :
public static void Main() {
Int32 x = 0;
const Int32 iterations = 10000000; // 10
// x 10 ?
Stopwatch sw = Stopwatch.StartNew();
for (Int32 i = 0; i < iterations; i++) {
x++;
}
Console.WriteLine("Incrementing x: {0:N0}", sw.ElapsedMilliseconds);
// x 10 ,
849
// ?
sw.Restart();
for (Int32 i = 0; i < iterations; i++) {
M(); x++; M();
}
Console.WriteLine("Incrementing x in M: {0:N0}", sw.ElapsedMilliseconds);
// x 10 ,
// SimpleSpinLock?
SpinLock sl = new SpinLock(false);
sw.Restart();
for (Int32 i = 0; i < iterations; i++) {
Boolean taken = false; sl.Enter(ref taken); x++; sl.Exit();
}
Console.WriteLine("Incrementing x in SpinLock: {0:N0}",
sw.ElapsedMilliseconds);
// x 10 ,
// SimpleWaitLock?
using (SimpleWaitLock swl = new SimpleWaitLock()) {
sw.Restart();
for (Int32 i = 0; i < iterations; i++) {
swl.Enter(); x++; swl.Leave();
}
Console.WriteLine(
"Incrementing x in SimpleWaitLock: {0:N0}", sw.ElapsedMilliseconds);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void M() { /* */ }
, :
Incrementing
Incrementing
Incrementing
Incrementing
x: 8
x in M: 69 ~9
x in SpinLock: 164 ~21
x in SimpleWaitLock: 8,854 ~1107
, x 8.
9 ! , ,
21 (164/8) . ,
.
1107 (8854/8) ! , . ,
. .
850
29.
(semaphores) Int32,
. 0
0.
.
Int32, .
Semaphore:
public sealed class Semaphore : WaitHandle {
public Semaphore(Int32 initialCount, Int32 maximumCount);
public Int32 Release(); // Release(1);
//
public Int32 Release(Int32 releaseCount); //
//
}
, :
.
.
, ,
releaseCount ( releaseCount , Release Semaphore).
, , .
, Set
, , Release
,
. , Release ,
,
SemaphoreFullException.
SimpleWaitLock
,
( ,
):
public sealed class SimpleWaitLock : IDisposable {
private Semaphore m_AvailableResources;
public SimpleWaitLock(Int32 maximumConcurrentThreads) {
m_AvailableResources =
851
,
. -, Mutex
, . (Int32). ReleaseMutex, Mutex
, . ,
Mutex , ReleaseMutex System.
ApplicationException. Mutex - , , ,
System.Threading.AbandonedMutexException.
, . , Mutex,
. AbandonedMutexException,
, .
, Mutex , ,
- .
,
, .
852
29.
ReleaseMutex . ,
0, .
. , . Mutex
. , Mutex ,
. , , Mutex.
.
,
, .
:
internal class SomeClass : IDisposable {
private readonly Mutex m_lock = new Mutex();
public void Method1() {
m_lock.WaitOne();
// -...
Method2(); // Method2,
m_lock.ReleaseMutex();
}
public void Method2() {
m_lock.WaitOne();
// -...
m_lock.ReleaseMutex();
}
}
853
30.
29
.
.
, ,
(hybrid thread synchronization
constructs).
,
.
, ( )
.
,
.
. , ,
FCL,
, .
Wintellect Power Threading, (http://Wintellect.com/PowerThreading.aspx).
,
FCL, .
,
,
.
:
internal sealed class SimpleHybridLock : IDisposable {
// Int32
855
// (Interlocked-)
private Int32 m_waiters = 0;
// AutoResetEvent -
private AutoResetEvent m_waiterLock = new AutoResetEvent(false);
public void Enter() {
//
if (Interlocked.Increment(ref m_waiters) == 1)
return; // , ,
// (),
// .
m_waiterLock.WaitOne(); //
// WaitOne ,
}
public void Leave() {
//
if (Interlocked.Decrement(ref m_waiters) == 0)
return; // ,
// ,
m_waiterLock.Set(); //
}
public void Dispose() { m_waiterLock.Dispose(); }
}
SimpleHybridLock : Int32 , ,
AutoResetEvent, .
,
Int32 AutoResetEvent.
AutoResetEvent SimpleHybridLock
,
Int32.
(AutoResetEventSlim), AutoResetEvent
, . AutoResetEvent Dispose
.
SimpleHybridLock,
Enter Leave,
. .
Enter Interlocked.Incre
ment m_waiters 1, .
, , ,
, Enter .
856
30.
, .
Enter, m_waiters
, , WaitOne, AutoResetEvent. WaitOne
Windows,
.
, ,
, .
-
. 29
Enter SimpleSpinLock.
Leave.
Interlocked.Decrement, m_waiters .
Enter, , Leave,
. , .
, Int32,
! ,
Leave
m_waiters, , , ,
. , Leave,
( ) .
Set AutoResetEvent.
, . , .
, AutoResetEvent
; AutoResetEvent
,
Leave.
Leave
, Enter , .
, ,
, Enter Leave,
.
.
, ;
.
857
, ,
,
. ,
, , .
, , , .
. Mutex1.
,
, .
:
internal sealed class AnotherHybridLock : IDisposable {
// Int32
// ( Interlocked)
private Int32 m_waiters = 0;
// AutoResetEvent
private AutoResetEvent m_waiterLock = new AutoResetEvent(false);
//
private Int32 m_spincount = 4000; //
// ,
private Int32 m_owningThreadId = 0, m_recursion = 0;
public void Enter() {
// ,
//
Int32 threadId = Thread.CurrentThread.ManagedThreadId;
if (threadId == m_owningThreadId) { m_recursion++; return; }
// ,
SpinWait spinwait = new SpinWait();
for (Int32 spinCount = 0; spinCount < m_spincount; spinCount++) {
// ,
//
if (Interlocked.CompareExchange(
ref m_waiters, 1, 0) == 0) goto GotLock;
Mutex , . Mutex
.
1
858
30.
//
//
spinwait.SpinOnce();
}
// , ,
//
if (Interlocked.Increment(ref m_waiters) > 1) {
//
//
m_waiterLock.WaitOne(); // ;
//
// ,
//
}
GotLock:
// ,
// ,
m_owningThreadId = threadId; m_recursion = 1;
}
public void Leave() {
// ,
Int32 threadId = Thread.CurrentThread.ManagedThreadId;
if (threadId != m_owningThreadId)
throw new SynchronizationLockException(
"Lock not owned by calling thread");
// .
// ,
if (--m_recursion > 0) return;
m_owningThreadId = 0; //
// ,
if (Interlocked.Decrement(ref m_waiters) == 0)
return;
// ,
m_waiterLock.Set(); //
}
, , , . ,
, ,
FCL
859
. 29 ,
Int32 , .
,
SimpleHybridlock AnotherHybridLock.
:
Incrementing x: 8
Incrementing x in M: 69 ~9
Incrementing x in SpinLock: 164 ~21
Incrementing x in SimpleHybridLock: 164 ~21 ( SpinLock)
Incrementing x in AnotherHybridLock: 230 ~29 (- /
)
Incrementing x in SimpleWaitLock: 8,854 ~1107
, AnotherHybridLock
, SimpleHybridLock. , .
, , .
FCL
FCL ,
, ,
.
. , ,
. CancellationToken ( 27), ,
,
.
.
ManualResetEventSlim SemaphoreSlim
System.Threading.ManualReset
EventSlim System.Threading.SemaphoreSlim1. ,
,
AutoResetEventSlim ,
SemaphoreSlim maxCount .
1
860
30.
, , . Wait
CancellationToken. (
):
public class ManualResetEventSlim : IDisposable {
public ManualResetEventSlim(Boolean initialState, Int32 spinCount);
public void Dispose();
public void Reset();
public void Set();
public Boolean Wait(
Int32 millisecondsTimeout, CancellationToken cancellationToken);
public Boolean IsSet { get; }
public Int32 SpinCount { get; }
public WaitHandle WaitHandle { get; }
}
public class SemaphoreSlim : IDisposable {
public SemaphoreSlim(Int32 initialCount, Int32 maxCount);
public void Dispose();
public Int32 Release(Int32 releaseCount);
public Boolean Wait(
Int32 millisecondsTimeout, CancellationToken cancellationToken);
// async await (. 28)
public Task<Boolean> WaitAsync(Int32 millisecondsTimeout,
CancellationToken cancellationToken);
Monitor
,
Monitor, , .
, , C#
, JIT, CLR . ,
, , .
, .
,
(sync block). ,
AnotherHybridLock. ,
, -,
. Monitor ,
FCL
861
. .
Monitor:
public static class Monitor {
public static void Enter(Object obj);
public static void Exit(Object obj);
// ( ):
public static Boolean TryEnter(Object obj, Int32 millisecondsTimeout);
// lockTaken
public static void Enter(Object obj, ref Boolean lockTaken);
public static void TryEnter(
Object obj, Int32 millisecondsTimeout, ref Boolean lockTaken);
}
, , , .
, CLR
. CLR
. ,
.
- . (sync block index),
.
1,
.
Monitor.Enter CLR .
. Exit ,
. ,
1, ,
- .
30.1 ,
CLR.
- A, B C T.
. 4,
: -.
-,
Monitor. , ,
,
.
862
30.
. 30.1. ( -).
CLR
Monitor:
internal sealed class Transaction {
private DateTime m_timeOfLastTrans;
public void PerformTransaction() {
Monitor.Enter(this);
// ...
m_timeOfLastTrans = DateTime.Now;
Monitor.Exit(this);
}
public DateTime LastTransaction {
get {
Monitor.Enter(this);
// ...
DateTime temp = m_timeOfLastTrans;
Monitor.Exit(this);
return temp;
}
}
}
FCL
863
, . ,
. :
public static void SomeMethod() {
var t = new Transaction();
Monitor.Enter(t); //
// LastTransaction
// .
// SomeMethod Monitor.Exit!
ThreadPool.QueueUserWorkItem(o => Console.WriteLine(t.LastTransaction));
// - ...
Monitor.Exit(t);
}
, SomeMethod, Monitor.
Enter, Transaction. LastTransaction, Monitor.
Enter, .
, , SomeMethod,
Monitor.Exit. ,
LastTransaction, ,
, . ,
. , ,
, ,
.
. Transaction:
internal sealed class Transaction {
private readonly Object m_lock = new Object(); //
//
private DateTime m_timeOfLastTrans;
public void PerformTransaction() {
Monitor.Enter(m_lock); //
// ...
m_timeOfLastTrans = DateTime.Now;
Monitor.Exit(m_lock); //
}
public DateTime LastTransaction {
get {
Monitor.Enter(m_lock); //
// ...
DateTime temp = m_timeOfLastTrans;
Monitor.Exit(m_lock); //
return temp;
}
}
}
864
30.
Transaction ,
m_lock.
, ,
Monitor ; ,
, ,
. Monitor
:
- System.Marshal
ByRefObject, ( 22). Monitor
, .
Monitor.Enter , ( , ,
22), .
CLR,
. ,
.
- Monitor.
( 14),
String
. Monitor
.
CLR ;
. ,
, String .
, , , . ,
. CLR,
.
String
Monitor.
Monitor Object,
.
. Monitor.Enter
, .
[MethodImpl(MethodImplOptions.Synchro
nized)] JIT-
Monitor.Enter Monitor.Exit. , this, .
FCL
865
,
. .
( 8) CLR
-, , .
. ,
,
.
.
, . , - ,
, C#
lock. :
private void SomeMethod() {
lock (this) {
// ...
}
}
:
private void SomeMethod() {
Boolean lockTaken = false;
try {
//
Monitor.Enter(this, ref lockTaken);
// ...
}
finally {
if (lockTaken) Monitor.Exit(this);
}
}
C# , Monitor.Exit finally. ,
try. . try
, .
finally ,
. ,
. ,
try .
JIT- ,
try, .
866
30.
,
1. lock.
lockTaken Boolean ,
. , try Monitor.Enter ( 22).
finally, .
lockTaken.
false, , .
Monitor.Enter , lockTaken
true. finally ,
Monitor.Exit. , SpinLock
lockTaken.
ReaderWriterLockSlim
. (, SimpleSpinLock , SimpleWaitLock ,
SimpleHybridLock, AnotherHybridLock, Mutex Monitor), ,
,
. ,
,
. ,
, . ReaderWriterLockSlim
, .
:
, ,
, .
, , , , , .
, , , , , .
, .
, ,
, .
,
.
, finally, try
, (,
).
1
FCL
867
(
):
public class ReaderWriterLockSlim : IDisposable {
public ReaderWriterLockSlim(LockRecursionPolicy recursionPolicy);
public void Dispose();
public void EnterReadLock();
public Boolean TryEnterReadLock(Int32 millisecondsTimeout);
public void ExitReadLock();
public void EnterWriteLock();
public Boolean TryEnterWriteLock(Int32 millisecondsTimeout);
public void ExitWriteLock();
//
public Boolean IsReadLockHeld { get; }
public Boolean IsWriteLockHeld { get; }
public Int32 CurrentReadCount { get; }
public Int32 RecursiveReadCount { get; }
public Int32 RecursiveWriteCount { get; }
public Int32 WaitingReadCount { get; }
public Int32 WaitingWriteCount { get; }
public LockRecursionPolicy RecursionPolicy { get; }
// ,
}
:
internal sealed class Transaction : IDisposable {
private readonly ReaderWriterLockSlim m_lock =
new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
private DateTime m_timeOfLastTrans;
public void PerformTransaction() {
m_lock.EnterWriteLock();
// ...
m_timeOfLastTrans = DateTime.Now;
m_lock.ExitWriteLock();
}
public DateTime LastTransaction {
get {
m_lock.EnterReadLock();
// ...
DateTime temp = m_timeOfLastTrans;
m_lock.ExitReadLock();
return temp;
}
}
}
868
30.
, . -, ReaderWriterLockSlim
LockRecurionsPolicy, :
public enum LockRecursionPolicy { NoRecursion, SupportsRecursion }
SupportsRecursion . ,
,
LockRecursionPolicy.NoRecursion (
).
- ,
,
, .
ReaderWriterLockSlim ! .
ReaderWriterLockSlim (
), . .
,
.
. . ,
.
,
. , ,
.
OneManyLock
-, ,
FCL ReaderWriterLockSlim1.
Ch30-1-HybridThreadSync.cs
. http://Wintellect.com/Books.
1
FCL
869
OneManyLock, ,
. :
public sealed class OneManyLock : IDisposable {
public OneManyLock();
public void Dispose();
, . Int32, , Semaphore,
, AutoResetEvent, .
.
. 0 Free (), 1 OwnedByWriter ( ), 2 OwnedByReaders
( ), 3 OwnedByReadersAndWriterPending (
) 4 ReservedForWriter ( ). .
( 0 1048575)
(RR), .
(RW),
. AutoResetEvent.
(WW),
. Semaphore.
,
Int64, Interlocked.
.
:
, OwnedByReaders,
RR= 1, .
OwnedByReaders (
), RR++, .
RW++, .
, .
:
RR--.
870
30.
RR > 0, .
WW > 0, ReservedForWriter ( ), WW--,
, .
RW = 0 WW = 0, Free (), .
:
, OwnedByWriter
( ), .
ReservedForWriter (
), OwnedByWriter ( ), .
OwnedByWriter ( ),
WW++, . ,
.
OwnedByReaders
AndWriterPending ( ), WW++, . ,
.
:
WW= 0 RW= 0, Free (), .
WW> 0, ReservedForWriter ( ), WW--,
, .
WW= 0 RW> 0, Free (), RW= 0, ,
.
, ,
, .
, , , .
, , RR WW 0,
Free. ,
.
, -
FCL
871
.
.
,
Interlocked- 29. ,
. .
OneManyLock ReaderWriterLockSlim
ReaderWriterLock FCL, :
x OneManyLock: 330 .
x ReaderWriterLockSlim: 554 1,7 .
x ReaderWriterLock: 984 3 .
, -
- , , . , - .
Power
Threading library ( http://Wintellect.com/
PowerThreading.aspx). , OneManyResourceLock.
,
(deadlocks), ( ),
.
,
.
CountdownEvent
System.Threading.CountdownEvent. ManualResetEventSlim
0.
( ,
0). (
):
public class CountdownEvent : IDisposable {
public CountdownEvent(Int32 initialCount);
public void Dispose();
public void Reset(Int32 count); //
//
public void AddCount(Int32 signalCount); //
//
public Boolean TryAddCount(Int32 signalCount); //
//
CurrentCount
count
CurrentCount
signalCount
CurrentCount
signalCount
872
30.
CurrentCount CountdownEvent
. CurrentCount 0, AddCount
InvalidOperationException, TryAddCount
false.
Barrier
System.Threading.Barrier
, -
. ,
. ,
CLR ,
.
, .
, .
,
. , , ,
. ,
.
.
Barrier,
( ):
public class Barrier : IDisposable {
public Barrier(Int32 participantCount, Action<Barrier> postPhaseAction);
public void Dispose();
public Int64 AddParticipants(Int32 participantCount); //
//
public void RemoveParticipants(Int32 participantCount); //
//
public Boolean SignalAndWait(
Int32 millisecondsTimeout, CancellationToken cancellationToken);
public Int64 CurrentPhaseNumber { get; } //
FCL
//
public Int32 ParticipantCount { get; } //
public Int32 ParticipantsRemaining { get; } //
//
}
873
( 0)
,
SignalAndWait
Barrier , .
Action<Barrier>, ,
.
Barrier AddParticipant
RemoveParticipant, .
SignalAndWait , Barrier (
ManualResetEventSlim). SignalAndWait
Barrier (
SignalAndWait ) , .
, .
-,
,
. ,
Volatile Interlocked, . , .
, ,
.
, :
. , , , . C#
.
.
.
. ,
. . Windows ,
.
, GUI- - .
874
30.
. , GUI-
.
, . , , , , , ,
.. ,
.
, .
.
, , ..
, , ,
.
Monitor 1. -.
Monitor,
,
.
(
-), . ,
Monitor, , 2. , finally,
. ,
,
, -
.
, , - ,
, . ,
.
, , ( 27),
. , ,
Monitor SpinLock.
, .
, SpinLock Monitor ,
.
2
, Monitor , .
1
875
,
. ,
, . -
XxxAsync,
- ( , ).
,
(double-check locking). , ,
(lazy initialization).
, .
.
,
.
, . Java, , Java .
www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html.
, , (.29) CLR
. ,
C#:
internal sealed class Singleton {
// s_lock
// . ,
//
// , System.Object
// .
//
private static readonly Object s_lock = new Object();
// Singleton
private static Singleton s_value = null;
//
private Singleton() {
// Singleton
}
876
30.
// , Singleton
// ( )
public static Singleton GetSingleton() {
// Singleton ,
if (s_value != null) return s_value;
Monitor.Enter(s_lock); // ,
//
if (s_value == null) {
// ,
Singleton temp = new Singleton();
// s_value (. )
Volatile.Write(ref s_value, temp);
}
Monitor.Exit(s_lock);
// Singleton
return s_value;
}
}
GetSingleton s_value, , -
. .
,
. , GetSingleton,
,
, , .
.
, Java.
GetSingleton Java s_value
if
.
true, , Singleton . , ,
GetSingleton , .
.
CLR
:
, .
GetSingleton , s_value
Monitor.Enter;
.
GetSingleton Volatile.Write. ,
if :
s_value = new Singleton(); //
877
, ,
Singleton, s_value,
(publishing).
Singleton, s_value ( ) .
, .
, s_value,
GetSingleton? ,
s_value null Singleton,
!
, - , .
Interlocked.Exchange. ,
temp s_value ,
. s_value volatile.
() s_value
. , , ,
.
. , ,
. .
Singleton
, :
internal sealed class Singleton {
private static Singleton s_value = new Singleton();
//
//
private Singleton() {
// Singleton
}
// , Singleton
// ( , )
public static Singleton GetSingleton() { return s_value; }
}
CLR ,
GetSingleton Singleton .
, CLR . 8.
.
Singleton ,
878
30.
Singleton. .
Singleton:
internal sealed class Singleton {
private static Singleton s_value = null;
//
//
private Singleton() {
// Singleton
}
// , Singleton
// ( , )
public static Singleton GetSingleton() {
if (s_value != null) return s_value;
// Singleton ,
//
Singleton temp = new Singleton();
Interlocked.CompareExchange(ref s_value, temp, null);
// Singleton
//
return s_value; //
}
}
GetSingleton
( ) Singleton .
Interlocked.CompareExchange s_value
. , ,
. ,
GetSingleton , -
Singleton.
,
Singleton, . -, . -, .
Monitor
, , .
, . CompareExchange
. ,
.
FCL ,
. System.Lazy (
):
879
:
public static void Main() {
// DateTime
Lazy<String> s = new Lazy<String>(
() => DateTime.Now.ToLongTimeString(),
LazyThreadSafetyMode.PublicationOnly);
Console.WriteLine(s.IsValueCreated); //
//
Console.WriteLine(s.Value); //
Console.WriteLine(s.IsValueCreated); //
//
Thread.Sleep(10000); //
//
Console.WriteLine(s.Value); //
//
}
false,
Value
true,
Value
10
,
:
False
2:40:42 PM
True
2:40:42 PM , 10 ,
Lazy
LazyThreadSafetyMode. :
public enum LazyThreadSafetyMode {
None, //
// ( GUI-)
ExecutionAndPublication, //
PublicationOnly, // Interlocked.CompareExchange
}
Lazy. System.Threading.LazyInitializer. :
public static class LazyInitializer {
// Interlocked.CompareExchange
public static T EnsureInitialized<T>(ref T target) where T: class;
public static T EnsureInitialized<T>(
ref T target, Func<T> valueFactory) where T: class;
// syncLock Enter Exit Monitor
public static T EnsureInitialized<T>(
880
30.
syncLock
EnsureInitialized
.
:
, .
. , -, , -,
, . , ,
.
(condition variable pattern),
Monitor:
public static class Monitor {
public static Boolean Wait(Object obj);
public static Boolean Wait(Object obj, Int32 millisecondsTimeout);
:
internal sealed class ConditionVariablePattern {
private readonly Object m_lock = new Object();
private Boolean m_condition = false;
public void Thread1() {
Monitor.Enter(m_lock); //
881
// ""
while (!m_condition) {
// , ,
Monitor.Wait(m_lock); // ,
//
}
// , ...
Monitor.Exit(m_lock); //
}
public void Thread2() {
Monitor.Enter(m_lock); //
// ...
m_condition = true;
// Monitor.Pulse(m_lock); //
Monitor.PulseAll(m_lock); //
Monitor.Exit(m_lock); //
}
}
, Thread1, .
Boolean ,
. , ,
, , 10.
, ,
, Wait.
, ,
.
Thread2 , .
Enter , - ,
, Pulse(All),
Wait. Pulse ,
( ), PulseAll
( ). .
, Thread2, Monitor.Exit,
. ,
PulseAll .
, Wait, ,
, .
, Wait Exit.
882
30.
, , Thread1,
. , Wait.
, , Exit,
.
( ),
, .
, .
, , ,
, .
internal sealed class SynchronizedQueue<T> {
private readonly Object m_lock = new Object();
private readonly Queue<T> m_queue = new Queue<T>();
public void Enqueue(T item) {
Monitor.Enter(m_lock);
//
// /
m_queue.Enqueue(item);
Monitor.PulseAll(m_lock);
}
Monitor.Exit(m_lock);
public T Dequeue() {
Monitor.Enter(m_lock);
// , ()
while (m_queue.Count == 0)
Monitor.Wait(m_queue);
//
T item = m_queue.Dequeue();
Monitor.Exit(m_lock);
return item;
}
}
, . ,
883
, .
.
-, . .
,
- . , . ,
, . ,
, . !
.
, , .
-
. Windows .
, .
, ,
Task, 27.
, Barrier:
( Task),
Task.
, :
, , ,
.
.
,
, , .
, , ,
.
,
.
, ,
. ,
( ). , , , , .
884
30.
. Microsoft. 2009
7603502.
SemaphoreSlim WaitAsync.
:
public Task<Boolean> WaitAsync(Int32 millisecondsTimeout,
CancellationToken cancellationToken);
( - ).
private static async Task
AccessResourceViaAsyncSynchronization(SemaphoreSlim asyncLock) {
// TODO: ...
await asyncLock.WaitAsync(); // .
// , ,
// .
// TODO: ( )...
// , ,
// .
asyncLock.Release();
// TODO: ...
}
WaitAsync SemaphoreSlim , , ,
. SemaphoreSlim 1, .
, ,
Monitor , SemaphoreSlim
(, ).
/? .NET Framework
ConcurrentExclusiveSchedulerPair, :
public class ConcurrentExclusiveSchedulerPair {
public ConcurrentExclusiveSchedulerPair();
public TaskScheduler ExclusiveScheduler { get; }
public TaskScheduler ConcurrentScheduler { get; }
//
}
TaskScheduler , / . , ExclusiveScheduler,
,
ConcurrentScheduler. , ,
ConcurrentScheduler, -
885
, ExclusiveScheduler.
ConcurrentExclusiveSchedulerPair :
private static void ConcurrentExclusiveSchedulerDemo() {
var cesp = new ConcurrentExclusiveSchedulerPair();
var tfExclusive = new TaskFactory(cesp.ExclusiveScheduler);
var tfConcurrent = new TaskFactory(cesp.ConcurrentScheduler);
for (Int32 operation = 0; operation < 5; operation++) {
var exclusive = operation < 2; //
// 2 3
(exclusive ? tfExclusive : tfConcurrent).StartNew(() => {
Console.WriteLine("{0} access", exclusive ? "exclusive" : "concurrent");
// TODO: ...
});
}
}
, .NET Framework /. , ,
AsyncOneManyLock. , SemaphoreSlim:
private static async Task
AccessResourceViaAsyncSynchronization(AsyncOneManyLock asyncLock) {
// TODO: ...
// OneManyMode.Exclusive OneManyMode.Shared
//
await asyncLock.AcquireAsync(OneManyMode.Shared); //
// , ,
// , ;
// TODO: ...
// , ,
// .
asyncLock.Release();
// TODO: ...
}
AsyncOneManyLock.
public enum OneManyMode { Exclusive, Shared }
public sealed class AsyncOneManyLock {
#region Lock code
private SpinLock m_lock = new SpinLock(true); //
// readonly SpinLock
private void Lock() { Boolean taken = false; m_lock.Enter(ref taken); }
private void Unlock() { m_lock.Exit(); }
#endregion
#region Lock state and helper methods
886
30.
}
private void MakeWriter() { m_state = 1
; }
private void MakeFree() { m_state = 0; }
#endregion
// (
// )
private readonly Task m_noContentionAccessGranter;
//
// TaskCompletionSource,
private readonly Queue<TaskCompletionSource<Object>> m_qWaitingWriters =
new Queue<TaskCompletionSource<Object>>();
//
// TaskCompletionSource
private TaskCompletionSource<Object> m_waitingReadersSignal =
new TaskCompletionSource<Object>();
private Int32 m_numWaitingReaders = 0;
public AsyncOneManyLock() {
m_noContentionAccessGranter = Task.FromResult<Object>(null);
}
public Task WaitAsync(OneManyMode mode) {
Task accressGranter = m_noContentionAccessGranter; //
//
Lock();
switch (mode) {
case OneManyMode.Exclusive:
if (IsFree) {
MakeWriter(); //
} else {
// :
var tcs = new TaskCompletionSource<Object>();
m_qWaitingWriters.Enqueue(tcs);
accressGranter = tcs.Task;
}
break;
case OneManyMode.Shared:
if (IsFree || (IsOwnedByReaders && m_qWaitingWriters.Count == 0)) {
AddReaders(1); //
} else { //
//
m_numWaitingReaders++;
887
accressGranter =
m_waitingReadersSignal.Task.ContinueWith(t => t.Result);
}
break;
}
Unlock();
}
return accressGranter;
, , .
SpinLock,
. SpinLock 29, , . WaitAsync,
,
, ,
TaskCompletionSource . -
888
30.
,
.
Release , , , TaskCompletionSource
. . SpinLock Queue.
, , .
public
public
public
public
public
ConcurrentQueue();
void Enqueue(T item);
Boolean TryDequeue(out T result);
Int32 Count { get; }
IEnumerator<T> GetEnumerator();
// LIFO
public class ConcurrentStack<T> : IProducerConsumerCollection<T>,
IEnumerable<T>, ICollection, IEnumerable {
public
public
public
public
public
ConcurrentStack();
void Push(T item);
Boolean TryPop(out T result);
Int32 Count { get; }
IEnumerator<T> GetEnumerator();
//
public class ConcurrentBag<T> : IProducerConsumerCollection<T>,
IEnumerable<T>, ICollection, IEnumerable {
public ConcurrentBag();
public void Add(T item);
public Boolean TryTake(out T result);
889
// /
public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>,
ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey,
TValue>>, IDictionary, ICollection, IEnumerable {
public
public
public
public
public
TKey
public
public
TKey
public
public
public
}
ConcurrentDictionary();
Boolean TryAdd(TKey key, TValue value);
Boolean TryGetValue(TKey key, out TValue value);
TValue this[TKey key] { get; set; }
Boolean TryUpdate(
key, TValue newValue, TValue comparisonValue);
Boolean TryRemove(TKey key, out TValue value);
TValue AddOrUpdate(
key, TValue addValue, Func<TKey, TValue> updateValueFactory);
TValue GetOrAdd(TKey key, TValue value);
Int32 Count { get; }
IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator();
. , ,
. , TryDequeue, TryPop,
TryTake TryGetValue, true,
false.
, ,
. ConcurrentDictionary
Monitor, , . ConcurrentQueue
ConcurrentStack Interlocked
. ConcurrentBag - .
Interlocked - .
-
.
Interlocked. - , Monitor - . ,
(stealing) .
,
GetEnumerator, C# foreach,
LINQ. ConcurrentStack, ConcurrentQueue ConcurrentBag
GetEnumerator ;
. GetEnumerator ConcurrentDictionary
890
30.
, ,
; . Count
. ,
.
ConcurrentStack, ConcurrentQueue ConcurrentBag IProducerConsumerCollection, :
public interface IProducerConsumerCollection<T> : IEnumerable<T>,
ICollection, IEnumerable {
Boolean TryAdd(T item);
Boolean TryTake(out T item);
T[] ToArray();
void CopyTo(T[] array, Int32 index);
}
. , , ,
, , , , . ,
,
.
System.Collections.Concurrent.BlockingCollection, . ( ):
public class BlockingCollection<T> : IEnumerable<T>, ICollection,
IEnumerable, IDisposable {
public BlockingCollection(
IProducerConsumerCollection<T> collection, Int32 boundedCapacity);
public void Add(T item);
public Boolean TryAdd(
T item, Int32 msTimeout, CancellationToken cancellationToken);
public void CompleteAdding();
public T Take();
public Boolean TryTake(
out T item, Int32 msTimeout, CancellationToken cancellationToken);
public Int32 BoundedCapacity { get; }
public Int32 Count { get; }
public Boolean IsAddingCompleted { get; } //
//
public Boolean IsCompleted { get; } //
//
true,
AddingComplete
true,
IsAddingComplete Count==0
891
BlockingCollection bounded
Capacity .
Add , .
, TryAdd, () / CancellationToken.
,
CancellationToken ( CancellationToken 27).
BlockingCollection IDisposable.
Dispose
SemaphoreSlim, -
-.
, -
CompleteAdding. -,
foreach, GetConsumingEnumerable,
. ,
/ :
public static void Main() {
var bl = new BlockingCollection<Int32>(new ConcurrentQueue<Int32>());
//
ThreadPool.QueueUserWorkItem(ConsumeItems, bl);
// 5
for (Int32 item = 0; item < 5; item++) {
Console.WriteLine("Producing: " + item);
bl.Add(item);
}
// -,
bl.CompleteAdding();
Console.ReadLine(); //
}
private static void ConsumeItems(Object o) {
var bl = (BlockingCollection<Int32>) o;
// ,
foreach (var item in bl.GetConsumingEnumerable()) {
Console.WriteLine("Consuming: " + item);
}
//
Console.WriteLine("All items have been consumed");
}
892
30.
:
Producing: 0
Producing: 1
Producing: 2
Producing: 3
Producing: 4
Consuming: 0
Consuming: 1
Consuming: 2
Consuming: 3
Consuming: 4
All items have been consumed
, Producing ()
Consuming () , All items have been
consumed ( ) .
BlockingCollection AddToAny,
TryAddToAny, TakeFromAny TryTakeFromAny. BlockingCollection<T>[], , ,
CancellationToken. (Try)AddToAny
, ,
. (Try)TakeFromAny , .
foreground thread
arity
lock
verification
deadlock
inline
delegate
deserialization
handle
AppDomain
task
closed types
private
sealed class
protected
( )
value type
cloning
covariant
,
code page
contra-variant
versioning
tuple
heap
manifest
894
array
, , ( )
native
metadata
callback method
extension method
()
accessor methods
mutex
inheritance
custom attribute
jagged array
unmanaged
implicit
generic
shim
event handler
constraint
public
lazy initialization
reflection
type parameter
overloading
override
enumerated type
scheduler
reference counting
late binding
threading model
casting
binding
application
,
,
code contract
marshaling
namespace
thread pool
()
parse
deploying
hosting
early binding
895
unboxing
distributed application
culture
null
nullable
,
,
assembly
semaphore
serialization
weak reference
reference type
strong reference
garbage collection
boxing
managed code
finalization
background thread
hash code
partial method
instance method
explicit
kernel
.
.
.
.
, 192102, -, . (. ), . 3, , . 7.
005-93,
2; 95 3005 .
13.06.13. 70100/16. . . . 72,240. 2000.
CtP .
194044, -, . , 9. / (812) 495-56-10.