C# in Depth....1
contents....8
foreword....18
preface....20
acknowledgments....21
about this book....23
Who should read this book....23
How this book is organized: A roadmap....24
About the code....25
Book forum....26
Other online resources....26
about the author....27
about the cover illustration....28
Part 1 C# in context....30
1 Survival of the sharpest....32
1.1 An evolving language....32
1.1.1 A helpful type system at large and small scales....33
1.1.2 Ever more concise code....35
1.1.3 Simple data access with LINQ....38
1.1.4 Asynchrony....39
1.1.5 Balancing efficiency and complexity....40
1.1.6 Evolution at speed: Using minor versions....41
1.2 An evolving platform....42
1.3 An evolving community....43
1.4 An evolving book....44
1.4.1 Mixed-level coverage....45
1.4.2 Examples using Noda Time....45
1.4.3 Terminology choices....46
Summary....47
Part 2 C# 2?5....48
2 C# 2....50
2.1 Generics....51
2.1.1 Introduction by example: Collections before generics....51
2.1.2 Generics save the day....54
2.1.3 What can be generic?....58
2.1.4 Type inference for type arguments to methods....59
2.1.5 Type constraints....61
2.1.6 The default and typeof operators....63
2.1.7 Generic type initialization and state....66
2.2 Nullable value types....67
2.2.1 Aim: Expressing an absence of information....68
2.2.2 CLR and framework support: The Nullable struct....69
2.2.3 Language support....72
2.3 Simplified delegate creation....78
2.3.1 Method group conversions....79
2.3.2 Anonymous methods....79
2.3.3 Delegate compatibility....81
2.4 Iterators....82
2.4.1 Introduction to iterators....83
2.4.2 Lazy execution....84
2.4.3 Evaluation of yield statements....85
2.4.4 The importance of being lazy....86
2.4.5 Evaluation of finally blocks....87
2.4.6 The importance of finally handling....90
2.4.7 Implementation sketch....91
2.5 Minor features....95
2.5.1 Partial types....96
2.5.2 Static classes....98
2.5.3 Separate getter/setter access for properties....98
2.5.4 Namespace aliases....99
2.5.5 Pragma directives....101
2.5.6 Fixed-size buffers....102
2.5.7 InternalsVisibleTo....102
Summary....103
3 C# 3: LINQ and everything that comes with it....104
3.1 Automatically implemented properties....105
3.2 Implicit typing....106
3.2.1 Typing terminology....106
3.2.2 Implicitly typed local variables (var)....107
3.2.3 Implicitly typed arrays....108
3.3 Object and collection initializers....110
3.3.1 Introduction to object and collection initializers....110
3.3.2 Object initializers....112
3.3.3 Collection initializers....113
3.3.4 The benefits of single expressions for initialization....115
3.4 Anonymous types....115
3.4.1 Syntax and basic behavior....115
3.4.2 The compiler-generated type....118
3.4.3 Limitations....119
3.5 Lambda expressions....120
3.5.1 Lambda expression syntax....121
3.5.2 Capturing variables....123
3.5.3 Expression trees....130
3.6 Extension methods....132
3.6.1 Declaring an extension method....132
3.6.2 Invoking an extension method....133
3.6.3 Chaining method calls....135
3.7 Query expressions....136
3.7.1 Query expressions translate from C# to C#....137
3.7.2 Range variables and transparent identifiers....137
3.7.3 Deciding when to use which syntax for LINQ....139
3.8 The end result: LINQ....140
Summary....140
4 C# 4: Improving interoperability....142
4.1 Dynamic typing....143
4.1.1 Introduction to dynamic typing....143
4.1.2 Dynamic behavior beyond reflection....148
4.1.3 A brief look behind the scenes....153
4.1.4 Limitations and surprises in dynamic typing....156
4.1.5 Usage suggestions....160
4.2 Optional parameters and named arguments....162
4.2.1 Parameters with default values and arguments with names....163
4.2.2 Determining the meaning of a method call....164
4.2.3 Impact on versioning....166
4.3 COM interoperability improvements....167
4.3.1 Linking primary interop assemblies....168
4.3.2 Optional parameters in COM....169
4.3.3 Named indexers....171
4.4 Generic variance....172
4.4.1 Simple examples of variance in action....172
4.4.2 Syntax for variance in interface and delegate declarations....173
4.4.3 Restrictions on using variance....174
4.4.4 Generic variance in practice....176
Summary....178
5 Writing asynchronous code....179
5.1 Introducing asynchronous functions....181
5.1.1 First encounters of the asynchronous kind....181
5.1.2 Breaking down the first example....183
5.2 Thinking about asynchrony....184
5.2.1 Fundamentals of asynchronous execution....184
5.2.2 Synchronization contexts....186
5.2.3 Modeling asynchronous methods....187
5.3 Async method declarations....189
5.3.1 Return types from async methods....190
5.3.2 Parameters in async methods....191
5.4 Await expressions....191
5.4.1 The awaitable pattern....192
5.4.2 Restrictions on await expressions....194
5.5 Wrapping of return values....195
5.6 Asynchronous method flow....197
5.6.1 What is awaited and when?....197
5.6.2 Evaluation of await expressions....198
5.6.3 The use of awaitable pattern members....202
5.6.4 Exception unwrapping....203
5.6.5 Method completion....205
5.7 Asynchronous anonymous functions....209
5.8 Custom task types in C# 7....211
5.8.1 The 99.9% case: ValueTask....211
5.8.2 The 0.1% case: Building your own custom task type....213
5.9 Async main methods in C# 7.1....215
5.10 Usage tips....216
5.10.1 Avoid context capture by using ConfigureAwait (where appropriate)....216
5.10.2 Enable parallelism by starting multiple independent tasks....218
5.10.3 Avoid mixing synchronous and asynchronous code....219
5.10.4 Allow cancellation wherever possible....219
5.10.5 Testing asynchrony....220
Summary....221
6 Async implementation....222
6.1 Structure of the generated code....224
6.1.1 The stub method: Preparation and taking the first step....227
6.1.2 Structure of the state machine....228
6.1.3 The MoveNext() method (high level)....231
6.1.4 The SetStateMachine method and the state machine boxing dance....233
6.2 A simple MoveNext() implementation....234
6.2.1 A full concrete example....234
6.2.2 MoveNext() method general structure....236
6.2.3 Zooming into an await expression....238
6.3 How control flow affects MoveNext()....239
6.3.1 Control flow between await expressions is simple....240
6.3.2 Awaiting within a loop....241
6.3.3 Awaiting within a try/finally block....242
6.4 Execution contexts and flow....245
6.5 Custom task types revisited....247
Summary....248
7 C# 5 bonus features....249
7.1 Capturing variables in foreach loops....249
7.2 Caller information attributes....251
7.2.1 Basic behavior....251
7.2.2 Logging....253
7.2.3 Simplifying INotifyPropertyChanged implementations....253
7.2.4 Corner cases of caller information attributes....255
7.2.5 Using caller information attributes with old versions of .NET....261
Summary....261
Part 3 C# 6....262
8 Super-sleek properties and expression-bodied members....264
8.1 A brief history of properties....265
8.2 Upgrades to automatically implemented properties....267
8.2.1 Read-only automatically implemented properties....267
8.2.2 Initializing automatically implemented properties....268
8.2.3 Automatically implemented properties in structs....269
8.3 Expression-bodied members....271
8.3.1 Even simpler read-only computed properties....271
8.3.2 Expression-bodied methods, indexers, and operators....274
8.3.3 Restrictions on expression-bodied members in C# 6....276
8.3.4 Guidelines for using expression-bodied members....278
Summary....280
9 Stringy features....281
9.1 A recap on string formatting in .NET....282
9.1.1 Simple string formatting....282
9.1.2 Custom formatting with format strings....282
9.1.3 Localization....284
9.2 Introducing interpolated string literals....287
9.2.1 Simple interpolation....287
9.2.2 Format strings in interpolated string literals....288
9.2.3 Interpolated verbatim string literals....288
9.2.4 Compiler handling of interpolated string literals (part 1)....290
9.3 Localization using FormattableString....290
9.3.1 Compiler handling of interpolated string literals (part 2)....291
9.3.2 Formatting a FormattableString in a specific culture....292
9.3.3 Other uses for FormattableString....294
9.3.4 Using FormattableString with older versions of .NET....297
9.4 Uses, guidelines, and limitations....299
9.4.1 Developers and machines, but maybe not end users....299
9.4.2 Hard limitations of interpolated string literals....301
9.4.3 When you can but really shouldn?t....302
9.5 Accessing identifiers with nameof....304
9.5.1 First examples of nameof....304
9.5.2 Common uses of nameof....306
9.5.3 Tricks and traps when using nameof....309
Summary....312
10 A sm?rg?sbord of features for concise code....313
10.1 Using static directives....313
10.1.1 Importing static members....314
10.1.2 Extension methods and using static....317
10.2 Object and collection initializer enhancements....319
10.2.1 Indexers in object initializers....320
10.2.2 Using extension methods in collection initializers....323
10.2.3 Test code vs. production code....327
10.3 The null conditional operator....328
10.3.1 Simple and safe property dereferencing....328
10.3.2 The null conditional operator in more detail....329
10.3.3 Handling Boolean comparisons....330
10.3.4 Indexers and the null conditional operator....331
10.3.5 Working effectively with the null conditional operator....332
10.3.6 Limitations of the null conditional operator....334
10.4 Exception filters....334
10.4.1 Syntax and semantics of exception filters....335
10.4.2 Retrying operations....340
10.4.3 Logging as a side effect....341
10.4.4 Individual, case-specific exception filters....342
10.4.5 Why not just throw?....343
Summary....344
Part 4 C# 7 and beyond....346
11 Composition using tuples....348
11.1 Introduction to tuples....349
11.2 Tuple literals and tuple types....350
11.2.1 Syntax....350
11.2.2 Inferred element names for tuple literals (C# 7.1)....352
11.2.3 Tuples as bags of variables....353
11.3 Tuple types and conversions....358
11.3.1 Types of tuple literals....358
11.3.2 Conversions from tuple literals to tuple types....359
11.3.3 Conversions between tuple types....363
11.3.4 Uses of conversions....365
11.3.5 Element name checking in inheritance....365
11.3.6 Equality and inequality operators (C# 7.3)....366
11.4 Tuples in the CLR....367
11.4.1 Introducing System.ValueTuple<...>....367
11.4.2 Element name handling....368
11.4.3 Tuple conversion implementations....370
11.4.4 String representations of tuples....370
11.4.5 Regular equality and ordering comparisons....371
11.4.6 Structural equality and ordering comparisons....372
11.4.7 Womples and large tuples....374
11.4.8 The nongeneric ValueTuple struct....375
11.4.9 Extension methods....375
11.5 Alternatives to tuples....375
11.5.1 System.Tuple<...>....376
11.5.2 Anonymous types....376
11.5.3 Named types....377
11.6 Uses and recommendations....377
11.6.1 Nonpublic APIs and easily changed code....377
11.6.2 Local variables....378
11.6.3 Fields....379
11.6.4 Tuples and dynamic don?t play together nicely....380
Summary....381
12 Deconstruction and pattern matching....382
12.1 Deconstruction of tuples....383
12.1.1 Deconstruction to new variables....384
12.1.2 Deconstruction assignments to existing variables and properties....386
12.1.3 Details of tuple literal deconstruction....390
12.2 Deconstruction of nontuple types....390
12.2.1 Instance deconstruction methods....391
12.2.2 Extension deconstruction methods and overloading....392
12.2.3 Compiler handling of Deconstruct calls....393
12.3 Introduction to pattern matching....394
12.4 Patterns available in C# 7.0....396
12.4.1 Constant patterns....396
12.4.2 Type patterns....397
12.4.3 The var pattern....400
12.5 Using patterns with the is operator....401
12.6 Using patterns with switch statements....403
12.6.1 Guard clauses....404
12.6.2 Pattern variable scope for case labels....405
12.6.3 Evaluation order of pattern-based switch statements....406
12.7 Thoughts on usage....408
12.7.1 Spotting deconstruction opportunities....408
12.7.2 Spotting pattern matching opportunities....409
Summary....409
13 Improving efficiency with more pass by reference....410
13.1 Recap: What do you know about ref?....411
13.2 Ref locals and ref returns....414
13.2.1 Ref locals....414
13.2.2 Ref returns....419
13.2.3 The conditional ?: operator and ref values (C# 7.2)....421
13.2.4 Ref readonly (C# 7.2)....422
13.3 in parameters (C# 7.2)....424
13.3.1 Compatibility considerations....425
13.3.2 The surprising mutability of in parameters: External changes....426
13.3.3 Overloading with in parameters....427
13.3.4 Guidance for in parameters....428
13.4 Declaring structs as readonly (C# 7.2)....430
13.4.1 Background: Implicit copying with read-only variables....430
13.4.2 The readonly modifier for structs....432
13.4.3 XML serialization is implicitly read-write....433
13.5 Extension methods with ref or in parameters (C# 7.2)....434
13.5.1 Using ref/in parameters in extension methods to avoid copying....434
13.5.2 Restrictions on ref and in extension methods....436
13.6 Ref-like structs (C# 7.2)....437
13.6.1 Rules for ref-like structs....438
13.6.2 Span and stackalloc....439
13.6.3 IL representation of ref-like structs....443
Summary....443
14 Concise code in C# 7....444
14.1 Local methods....444
14.1.1 Variable access within local methods....446
14.1.2 Local method implementations....449
14.1.3 Usage guidelines....454
14.2 Out variables....456
14.2.1 Inline variable declarations for out parameters....456
14.2.2 Restrictions lifted in C# 7.3 for out variables and pattern variables....457
14.3 Improvements to numeric literals....458
14.3.1 Binary integer literals....458
14.3.2 Underscore separators....459
14.4 Throw expressions....460
14.5 Default literals (C# 7.1)....461
14.6 Nontrailing named arguments (C# 7.2)....462
14.7 Private protected access (C# 7.2)....464
14.8 Minor improvements in C# 7.3....464
14.8.1 Generic type constraints....464
14.8.2 Overload resolution improvements....465
14.8.3 Attributes for fields backing automatically implemented properties....466
Summary....466
15 C# 8 and beyond....468
15.1 Nullable reference types....469
15.1.1 What problem do nullable reference types solve?....469
15.1.2 Changing the meaning when using reference types....470
15.1.3 Enter nullable reference types....471
15.1.4 Nullable reference types at compile time and execution time....472
15.1.5 The damn it or bang operator....474
15.1.6 Experiences of nullable reference type migration....476
15.1.7 Future improvements....478
15.2 Switch expressions....482
15.3 Recursive pattern matching....484
15.3.1 Matching properties in patterns....484
15.3.2 Deconstruction patterns....485
15.3.3 Omitting types from patterns....486
15.4 Indexes and ranges....487
15.4.1 Index and Range types and literals....487
15.4.2 Applying indexes and ranges....488
15.5 More async integration....490
15.5.1 Asynchronous resource disposal with using await....490
15.5.2 Asynchronous iteration with foreach await....491
15.5.3 Asynchronous iterators....494
15.6 Features not yet in preview....495
15.6.1 Default interface methods....495
15.6.2 Record types....497
15.6.3 Even more features in brief....498
15.7 Getting involved....499
Conclusion....500
appendix Language features by version....502
index....508
Symbols....508
A....508
B....510
C....510
D....513
E....514
F....515
G....516
H....516
I....516
J....518
K....518
L....518
M....519
N....519
O....520
P....521
Q....522
R....522
S....522
T....524
U....525
V....525
W....526
X....526
Y....526
C# in Depth-back....528
This book is about the C# programming language. It often means going into some details of the runtime responsible for executing your code and the libraries that support your application, but the focus is firmly on the language itself.The goal of the book is to help you become as comfortable with C# as possible, so you never need to feel like you're fighting against the language. I want you to feel fluent in C#, with the connotations of working in a smooth and flowing way. Think of C# as a river, and you're paddling in a kayak. The more you know about the river, the faster you can travel with its current. Sometimes, you might want to go upstream for some reason, but even then, understanding how the river works will make it easier for you to reach your destination without getting stuck.If you're an experienced C# programmer who wants to learn more about the language, this book is for you! You don't need to be an expert to understand this book, but I hope it will help you gain a deeper understanding of the language and its features.You know the basics of C#. I'll explain all the terminology that I use, which was introduced after C# 1, and some older terms that are often misunderstood (such as parameters and arguments). However, I assume you already know what a class is and what an object is. If you're an expert, you may still find this book useful because it offers different ways of thinking about familiar concepts. You may also discover areas of the language that you weren't aware of; I know this has been my experience while writing the book.If you're completely new to C#, this book might not be useful for you yet. There are many introductory books and online tutorials available on C#. Once you've mastered the basics, I hope you'll return and dive deeper into the subject.