Table of Contents....5
About the Authors....51
About the Technical Reviewers....52
Acknowledgments....53
Introduction....54
Part I: Introducing C# and .NET 6....63
Chapter 1: Introducing C# and .NET 6....64
Exploring Some Key Benefits of the .NET Platform....65
Understanding the .NET Support Lifecycle....65
Previewing the Building Blocks of the .NET Platform....66
The Role of the Base Class Libraries....66
The Role of .NET Standard....66
What C# Brings to the Table....67
Major Features in Prior Releases....68
New Features in C# 10....68
Managed vs. Unmanaged Code....68
Using Additional .NET–Aware Programming Languages....68
Getting an Overview of .NET Assemblies....69
The Role of the Common Intermediate Language....69
Benefits of CIL....72
Compiling CIL to Platform-Specific Instructions....72
Precompiling CIL to Platform-Specific Instructions....73
The Role of .NET Type Metadata....73
The Role of the Assembly Manifest....74
Understanding the Common Type System....74
CTS Class Types....75
CTS Interface Types....75
CTS Structure Types....76
CTS Enumeration Types....76
CTS Delegate Types....77
CTS Type Members....77
Intrinsic CTS Data Types....77
Understanding the Common Language Specification....78
Ensuring CLS Compliance....80
Understanding the .NET Runtime....80
Distinguishing Between Assembly, Namespace, and Type....80
Accessing a Namespace Programmatically....83
Global Using Statements (New 10.0)....83
Implicit Global Using Statements (New 10.0)....84
File Scoped Namespaces (New 10.0)....85
Referencing External Assemblies....85
Exploring an Assembly Using ildasm.exe....86
Summary....86
Chapter 2: Building C# Applications....88
Installing .NET 6....88
Understanding the .NET Version Numbering Scheme....88
Confirming the .NET 6 Install....89
Checking For Updates....90
Use an Earlier Version of the .NET (Core) SDK....90
Building .NET Core Applications with Visual Studio....90
Installing Visual Studio 2022 (Windows)....91
Taking Visual Studio 2022 for a Test-Drive....92
Using the New Project Dialog and C# Code Editor....93
Changing the Target .NET Core Framework....96
Using C# 10 Features....98
Running and Debugging Your Project....98
Using Solution Explorer....99
Using the Visual Class Diagram Tool....100
Building .NET Core Applications with Visual Studio Code....105
Taking Visual Studio Code for a Test-Drive....105
Creating Solutions and Projects....106
Exploring the Visual Studio Code Workspace....106
Restoring Packages, Building and Running Programs....107
Debugging Your Project....108
Finding the .NET Core and C# Documentation....108
Summary....109
Part II: Core C# Programming....110
Chapter 3: Core C# Programming Constructs, Part 1....111
Breaking Down a Simple C# Program (Updated C# 10)....111
Using Variations of the Main() Method (Updated 7.1)....113
Using Top-Level Statements (New 9.0)....114
Specifying an Application Error Code (Updated 9.0)....116
Processing Command-Line Arguments (Updated 9.0)....118
Specifying Command-Line Arguments with Visual Studio 2022....120
Additional Members of the System.Environment Class (Updated 10.0)....121
Using the System.Console Class....122
Performing Basic Input and Output (I/O) with the Console Class....123
Formatting Console Output....124
Formatting Numerical Data....125
Formatting Numerical Data Beyond Console Applications....126
Working with System Data Types and Corresponding C# Keywords....127
Understanding Variable Declaration and Initialization....128
The default Literal (New 7.1)....129
Using Intrinsic Data Types and the new Operator (Updated 9.0)....130
Understanding the Data Type Class Hierarchy....131
Understanding the Members of Numerical Data Types....132
Understanding the Members of System.Boolean....133
Understanding the Members of System.Char....133
Parsing Values from String Data....134
Using TryParse to Parse Values from String Data....134
Using System.DateTime and System.TimeSpan (Updated 10.0)....135
Working with the System.Numerics Namespace....136
Using Digit Separators (New 7.0)....137
Using Binary Literals (New 7.0/7.2)....138
Working with String Data....138
Performing Basic String Manipulation....139
Performing String Concatenation....140
Using Escape Characters....141
Performing String Interpolation....142
Performance Improvements (Updated 10.0)....143
Defining Verbatim Strings (Updated 8.0)....144
Working with Strings and Equality....145
Modifying String Comparison Behavior....146
Strings Are Immutable....147
Using the System.Text.StringBuilder Type....149
Narrowing and Widening Data Type Conversions....150
Using the checked Keyword....152
Setting Project-wide Overflow Checking (Project File)....154
Setting Project-wide Overflow Checking (Visual Studio)....154
Selecting the Build Configuration....155
Using the unchecked Keyword....155
Understanding Implicitly Typed Local Variables....156
Declaring Numerics Implicitly....157
Understanding Restrictions on Implicitly Typed Variables....158
Implicit Typed Data Is Strongly Typed Data....159
Understanding the Usefulness of Implicitly Typed Local Variables....160
Working with C# Iteration Constructs....160
Using the for Loop....161
Using the foreach Loop....161
Using Implicit Typing Within foreach Constructs....162
Using the while and do/while Looping Constructs....162
A Quick Discussion About Scope....163
Working with Decision Constructs and the Relational/Equality Operators....164
Using the if/else Statement....164
Using Equality and Relational Operators....164
Using if/else with Pattern Matching (New 7.0)....166
Making Pattern Matching Improvements (New 9.0)....166
Using the Conditional Operator (Updated 7.2, 9.0)....168
Using Logical Operators....169
Using the switch Statement....169
Performing switch Statement Pattern Matching (New 7.0, Updated 9.0)....172
Using switch Expressions (New 8.0)....175
Summary....177
Chapter 4: Core C# Programming Constructs, Part 2....178
Understanding C# Arrays....178
Looking at the C# Array Initialization Syntax....179
Understanding Implicitly Typed Local Arrays....180
Defining an Array of Objects....181
Working with Multidimensional Arrays....181
Using Arrays As Arguments or Return Values....183
Using the System.Array Base Class....184
Using Indices and Ranges (New 8.0, Updated 10.0)....185
Understanding Methods....187
Understanding Expression-Bodied Members....188
Understanding Local Functions (New 7.0, Updated 9.0)....188
Understanding Static Local Functions (New 8.0)....190
Understanding Method Parameters....190
Understanding Method Parameter Modifiers....190
Understanding the Default Parameter-Passing Behavior....191
The Default Behavior for Value Types....191
The Default Behavior for Reference Types....192
Using the out Modifier (Updated 7.0)....192
Discarding out Parameters (New 7.0)....194
The out Modifier in Constructors and Initializers (New 7.3)....194
Using the ref Modifier....194
Using the in Modifier (New 7.2)....195
Using the params Modifier....196
Defining Optional Parameters....197
Using Named Arguments (Updated 7.2)....198
Understanding Method Overloading....200
Checking Parameters for Null (Updated 10.0)....203
Understanding the enum Type....203
Controlling the Underlying Storage for an enum....205
Declaring enum Variables....205
Using the System.Enum Type....206
Dynamically Discovering an enum’s Name-Value Pairs....207
Using Enums, Flags, and Bitwise Operations....208
Understanding the Structure....210
Creating Structure Variables....212
Structure Constructors (Updated 10.0)....212
Using Field Initializers (New 10.0)....213
Using Read-Only Structs (New 7.2)....214
Using Read-Only Members (New 8.0)....215
Using ref Structs (New 7.2)....215
Using Disposable ref Structs (New 8.0)....216
Understanding Value Types and Reference Types....217
Using Value Types, Reference Types, and the Assignment Operator....218
Using Value Types Containing Reference Types....219
Passing Reference Types by Value....221
Passing Reference Types by Reference....222
Final Details Regarding Value Types and Reference Types....223
Understanding C# Nullable Types....224
Using Nullable Value Types....225
Using Nullable Reference Types (New 8.0, Updated 10.0)....226
Opting in for Nullable Reference Types (Updated 10.0)....227
Nullable Reference Types in Action....228
Migration Considerations....229
Change Nullable Warnings to Errors....229
Operating on Nullable Types....230
The Null-Coalescing Operator....230
The Null-Coalescing Assignment Operator (New 8.0)....231
The Null Conditional Operator....231
Understanding Tuples (New/Updated 7.0)....232
Getting Started with Tuples....232
Using Inferred Variable Names (Updated 7.1)....233
Understanding Tuple Equality/Inequality (New 7.3)....234
Understanding Tuples as Method Return Values....234
Understanding Discards with Tuples....235
Understanding Tuple Pattern Matching switch Expressions (New 8.0)....235
Deconstructing Tuples (Updated 10.0)....236
Deconstructing Tuples with Positional Pattern Matching (New 8.0)....237
Summary....238
Part III: Object Oriented Programming with C#....239
Chapter 5: Understanding Encapsulation....240
Introducing the C# Class Type....240
Allocating Objects with the new Keyword....242
Understanding Constructors....243
Understanding the Role of the Default Constructor....243
Defining Custom Constructors....244
Constructors As Expression-Bodied Members (New 7.0)....245
Constructors with out Parameters (New 7.3)....245
Understanding the Default Constructor Revisited....245
Understanding the Role of the this Keyword....247
Chaining Constructor Calls Using this....248
Observing Constructor Flow....250
Revisiting Optional Arguments....252
Understanding the static Keyword....253
Defining Static Field Data....254
Defining Static Methods....256
Defining Static Constructors....257
Defining Static Classes....259
Importing Static Members via the C# using Keyword....260
Defining the Pillars of OOP....261
Understanding the Role of Encapsulation....261
Understanding the Role of Inheritance....262
Understanding the Role of Polymorphism....263
Understanding C# Access Modifiers (Updated 7.2)....264
Using the Default Access Modifiers....265
Using Access Modifiers and Nested Types....266
Understanding the First Pillar: C#’s Encapsulation Services....266
Encapsulation Using Traditional Accessors and Mutators....267
Encapsulation Using Properties....269
Properties As Expression-Bodied Members (New 7.0)....272
Using Properties Within a Class Definition....273
Read-Only Properties....274
Write-Only Properties....275
Mixing Private and Public Get/Set Methods on Properties....275
Revisiting the static Keyword: Defining Static Properties....275
Pattern Matching with Property Patterns (New 8.0)....276
Extended Property Patterns (New 10.0)....278
Understanding Automatic Properties....279
Interacting with Automatic Properties....280
Automatic Properties and Default Values....281
Initializing Automatic Properties....282
Understanding Object Initialization....283
Looking at the Object Initialization Syntax....283
Using init-Only Setters (New 9.0)....284
Calling Custom Constructors with Initialization Syntax....285
Initializing Data with Initialization Syntax....287
Working with Constant and Read-Only Field Data....288
Understanding Constant Field Data....288
Constant Interpolated Strings (New 10.0)....289
Understanding Read-Only Fields....289
Understanding Static Read-Only Fields....290
Understanding Partial Classes....291
Records (New 9.0)....292
Immutable Record Types with Standard Property Syntax....294
Immutable Record Types with Positional Syntax....295
Deconstructing Mutable Record Types....296
Mutable Record Types....296
Value Equality with Record Types....296
Copying Record Types Using with Expressions....297
Record Structs (New 10.0)....298
Mutable Record Structs....298
Immutable Record Structs....299
Deconstructing Record Structs....300
Summary....300
Chapter 6: Understanding Inheritance and Polymorphism....301
Understanding the Basic Mechanics of Inheritance....301
Specifying the Parent Class of an Existing Class....302
Regarding Multiple Base Classes....304
Using the sealed Keyword....304
Revisiting Visual Studio Class Diagrams....305
Understanding the Second Pillar of OOP: The Details of Inheritance....307
Calling Base Class Constructors with the base Keyword....308
Keeping Family Secrets: The protected Keyword....310
Adding a sealed Class....311
Understanding Inheritance with Record Types (New 9.0)....312
Inheritance for Record Types with Standard Properties....313
Inheritance for Record Types with Positional Parameters....314
Nondestructive Mutation with Inherited Record Types....315
Equality with Inherited Record Types....315
Deconstructor Behavior with Inherited Record Types....316
Programming for Containment/Delegation....316
Understanding Nested Type Definitions....317
Understanding the Third Pillar of OOP: C#’s Polymorphic Support....319
Using the virtual and override Keywords....320
Overriding Virtual Members with Visual Studio/Visual Studio Code....323
Sealing Virtual Members (Updated 10.0)....323
Understanding Abstract Classes....324
Understanding the Polymorphic Interface....326
Understanding Member Shadowing....330
Understanding Base Class/Derived Class Casting Rules....331
Using the C# as Keyword....333
Using the C# is Keyword (Updated 7.0, 9.0)....335
Discards with the is Keyword (New 7.0)....336
Revisiting Pattern Matching (New 7.0)....337
Discards with switch Statements (New 7.0)....337
Understanding the Super Parent Class: System.Object....338
Overriding System.Object.ToString()....341
Overriding System.Object.Equals()....341
Overriding System.Object.GetHashCode()....342
Testing Your Modified Person Class....343
Using the Static Members of System.Object....344
Summary....344
Chapter 7: Understanding Structured Exception Handling....345
Ode to Errors, Bugs, and Exceptions....345
The Role of .NET Exception Handling....346
The Building Blocks of .NET Exception Handling....347
The System.Exception Base Class....347
The Simplest Possible Example....348
Throwing a General Exception....351
Catching Exceptions....352
Throw As Expression (New 7.0)....354
Configuring the State of an Exception....354
The TargetSite Property....354
The StackTrace Property....355
The HelpLink Property....355
The Data Property....356
System-Level Exceptions (System.SystemException)....358
Application-Level Exceptions (System.ApplicationException)....358
Building Custom Exceptions, Take 1....359
Building Custom Exceptions, Take 2....361
Building Custom Exceptions, Take 3....361
Processing Multiple Exceptions....362
General catch Statements....365
Rethrowing Exceptions....365
Inner Exceptions....366
The finally Block....367
Exception Filters....368
Debugging Unhandled Exceptions Using Visual Studio....368
Summary....370
Part IV: Advanced C# Programming....371
Chapter 8: Working with Interfaces....372
Understanding Interface Types....372
Interface Types vs. Abstract Base Classes....373
Defining Custom Interfaces....376
Implementing an Interface....377
Invoking Interface Members at the Object Level....379
Obtaining Interface References: The as Keyword....380
Obtaining Interface References: The is Keyword (Updated 7.0)....381
Default Implementations (New 8.0)....381
Static Constructors and Members (New 8.0)....382
Interfaces as Parameters....383
Interfaces as Return Values....385
Arrays of Interface Types....385
Implementing Interfaces Using Visual Studio or Visual Studio Code....387
Explicit Interface Implementation....388
Designing Interface Hierarchies....391
Interface Hierarchies with Default Implementations (New 8.0)....392
Multiple Inheritance with Interface Types....394
The IEnumerable and IEnumerator Interfaces....396
Building Iterator Methods with the yield Keyword....399
Guard Clauses with Local Functions (New 7.0)....399
Building a Named Iterator....401
The ICloneable Interface....402
A More Elaborate Cloning Example....404
The IComparable Interface....407
Specifying Multiple Sort Orders with IComparer....410
Custom Properties and Custom Sort Types....411
Summary....412
Chapter 9: Understanding Object Lifetime....413
Classes, Objects, and References....413
The Basics of Object Lifetime....415
The CIL of new....415
Setting Object References to null....417
Determining If an Object Is Live....417
Understanding Object Generations....419
Ephemeral Generations and Segments....421
Garbage Collection Types....421
Background Garbage Collection....421
The System.GC Type....422
Forcing a Garbage Collection....424
Building Finalizable Objects....426
Overriding System.Object.Finalize()....427
Detailing the Finalization Process....429
Building Disposable Objects....430
Reusing the C# using Keyword....432
Using Declarations (New 8.0)....433
Building Finalizable and Disposable Types....434
A Formalized Disposal Pattern....435
Understanding Lazy Object Instantiation....437
Customizing the Creation of the Lazy Data....439
Chapter 10: Collections and Generics....441
The Motivation for Collection Classes....441
The System.Collections Namespace....443
An Illustrative Example: Working with the ArrayList....444
A Survey of System.Collections.Specialized Namespace....444
The Problems of Nongeneric Collections....445
The Issue of Performance....446
The Issue of Type Safety....449
A First Look at Generic CollectionsT....452
The Role of Generic Type Parameters....453
Specifying Type Parameters for Generic Classes/Structures....454
Specifying Type Parameters for Generic Members....456
Specifying Type Parameters for Generic Interfaces....456
The System.Collections.Generic Namespace....457
Understanding Collection Initialization Syntax....459
Working with the List Class....460
Working with the Stack Class....462
Working with the Queue Class....463
Working with the PriorityQueue Class (New 10)....464
Working with the SortedSet Class....465
Working with the Dictionary Class....467
The System.Collections.ObjectModel Namespace....468
Working with ObservableCollection....468
Creating Custom Generic Methods....470
Inference of Type Parameters....472
Creating Custom Generic Structures and Classes....473
Default Value Expressions with Generics....474
Default Literal Expressions (New 7.1)....476
Pattern Matching with Generics (New 7.1)....476
Constraining Type Parameters....477
Examples of Using the where Keyword....477
The Lack of Operator Constraints....479
Summary....480
Chapter 11: Advanced C# Language Features....481
Understanding Indexer Methods....481
Indexing Data Using String Values....483
Overloading Indexer Methods....484
Indexers with Multiple Dimensions....485
Indexer Definitions on Interface Types....486
Understanding Operator Overloading....486
Overloading Binary Operators....487
What of the += and –= Operators?....489
Overloading Unary Operators....490
Overloading Equality Operators....491
Overloading Comparison Operators....491
Final Thoughts Regarding Operator Overloading....492
Understanding Custom Type Conversions....493
Recall: Numerical Conversions....493
Recall: Conversions Among Related Class Types....493
Creating Custom Conversion Routines....494
Additional Explicit Conversions for the Square Type....497
Defining Implicit Conversion Routines....497
Understanding Extension Methods....499
Defining Extension Methods....499
Invoking Extension Methods....500
Importing Extension Methods....501
Extending Types Implementing Specific Interfaces....502
Extension Method GetEnumerator Support (New 9.0)....503
Understanding Anonymous Types....504
Defining an Anonymous Type....505
The Internal Representation of Anonymous Types....506
The Implementation of ToString() and GetHashCode()....508
The Semantics of Equality for Anonymous Types....508
Anonymous Types Containing Anonymous Types....510
Working with Pointer Types....511
The unsafe Keyword....513
Working with the * and & Operators....515
An Unsafe (and Safe) Swap Function....516
Field Access via Pointers (the -> Operator)....517
The stackalloc Keyword....517
Pinning a Type via the fixed Keyword....518
The sizeof Keyword....519
Summary....519
Chapter 12: Delegates, Events, and Lambda Expressions....520
Understanding the Delegate Type....521
Defining a Delegate Type in C#....521
The System.MulticastDelegate and System.Delegate Base Classes....523
The Simplest Possible Delegate Example....525
Investigating a Delegate Object....527
Sending Object State Notifications Using Delegates....528
Enabling Multicasting....531
Removing Targets from a Delegate’s Invocation List....533
Method Group Conversion Syntax....534
Understanding Generic Delegates....535
The Generic Action<> and Func<> Delegates....536
Understanding C# Events....538
The C# event Keyword....539
Events Under the Hood....541
Listening to Incoming Events....542
Simplifying Event Registration Using Visual Studio....543
Creating Custom Event Arguments....544
The Generic EventHandler Delegate....546
Understanding C# Anonymous Methods....547
Accessing Local Variables....548
Using static with Anonymous Methods (New 9.0)....549
Discards with Anonymous Methods (New 9.0)....550
Understanding Lambda Expressions....551
Dissecting a Lambda Expression....553
Processing Arguments Within Multiple Statements....554
Lambda Expressions with Multiple (or Zero) Parameters....555
Using static with Lambda Expressions (New 9.0)....557
Discards with Lambda Expressions (New 9.0)....557
Retrofitting the CarEvents Example Using Lambda Expressions....558
Lambdas and Expression-Bodied Members (Updated 7.0)....558
Summary....559
Chapter 13: LINQ to Objects....561
LINQ-Specific Programming Constructs....561
Implicit Typing of Local Variables....562
Object and Collection Initialization Syntax....563
Lambda Expressions....563
Extension Methods....564
Anonymous Types....565
Understanding the Role of LINQ....565
LINQ Expressions Are Strongly Typed....566
The Core LINQ Assemblies....566
Applying LINQ Queries to Primitive Arrays....566
Once Again, Using Extension Methods....568
Once Again, Without LINQ....569
Reflecting Over a LINQ Result Set....569
LINQ and Implicitly Typed Local Variables....571
LINQ and Extension Methods....572
The Role of Deferred Execution....573
DefaultIfEmpty (New 10.0)....574
The Role of Immediate Execution....575
Set Default for [First/Last/Single]OrDefault Methods (New 10)....576
Returning the Result of a LINQ Query....577
Returning LINQ Results via Immediate Execution....578
Applying LINQ Queries to Collection Objects....579
Accessing Contained Subobjects....580
Applying LINQ Queries to Nongeneric Collections....580
Filtering Data Using OfType()....581
Investigating the C# LINQ Query Operators....582
Basic Selection Syntax....583
Obtaining Subsets of Data....584
Paging Data....585
Paging Data with Ranges (New 10.0)....586
Paging Data with Chunks (New 10.0)....587
Projecting New Data Types....587
Projecting to Different Data Types....589
Obtaining Counts Using Enumerable....589
Obtaining Nonenumerated Counts (New 10.0)....590
Reversing Result Sets....591
Sorting Expressions....591
LINQ As a Better Venn Diagramming Tool....591
Venn Diagramming with Selectors (New 10.0)....593
Removing Duplicates....595
Removing Duplicates with Selectors (New 10.0)....595
LINQ Aggregation Operations....596
Aggregation with Selectors (New 10.0)....596
The Internal Representation of LINQ Query Statements....596
Building Query Expressions with Query Operators (Revisited)....597
Building Query Expressions Using the Enumerable Type and Lambda Expressions....598
Building Query Expressions Using the Enumerable Type and Anonymous Methods....599
Building Query Expressions Using the Enumerable Type and Raw Delegates....600
Summary....601
Part V: Programming with .NET Core Assemblies....603
Chapter 14: Processes, AppDomains, and Load Contexts....604
The Role of a Windows Process....604
The Role of Threads....605
Interacting with Processes Using .NET Core....606
Enumerating Running Processes....608
Investigating a Specific Process....609
Investigating a Process’s Thread Set....610
Investigating a Process’s Module Set....611
Starting and Stopping Processes Programmatically....613
Controlling Process Startup Using the ProcessStartInfo Class....614
Leveraging OS Verbs with ProcessStartInfo....615
Understanding .NET Application Domains....616
The System.AppDomain Class....617
Interacting with the Default Application Domain....617
Enumerating Loaded Assemblies....618
Assembly Isolation with Application Load Contexts....619
Summarizing Processes, AppDomains, and Load Contexts....622
Summary....623
Chapter 15: Multithreaded, Parallel, and Async Programming....624
The Process/AppDomain/Context/Thread Relationship....624
The Problem of Concurrency....625
The Role of Thread Synchronization....626
The System.Threading Namespace....626
The System.Threading.Thread Class....627
Obtaining Statistics About the Current Thread of Execution....628
The Name Property....629
The Priority Property....629
Manually Creating Secondary Threads....630
Working with the ThreadStart Delegate....630
Working with the ParameterizedThreadStart Delegate....632
The AutoResetEvent Class....633
Foreground Threads and Background Threads....634
The Issue of Concurrency....635
Synchronization Using the C# lock Keyword....637
Synchronization Using the System.Threading.Monitor Type....639
Synchronization Using the System.Threading.Interlocked Type....640
Programming with Timer Callbacks....641
Using a Stand-Alone Discard (New 7.0)....642
Understanding the ThreadPool....643
Parallel Programming Using the Task Parallel Library....644
The System.Threading.Tasks Namespace....644
The Role of the Parallel Class....644
Data Parallelism with the Parallel Class....645
Accessing UI Elements on Secondary Threads....649
The Task Class....650
Handling Cancellation Request....650
Task Parallelism Using the Parallel Class....652
Parallel LINQ Queries (PLINQ)....655
Opting in to a PLINQ Query....656
Cancelling a PLINQ Query....656
Async Calls Using the async/await Pattern....658
A First Look at the C# async and await Keywords (Updated 7.1, 9.0)....658
SynchronizationContext and async/await....660
The Role of ConfigureAwait....660
Naming Conventions for Asynchronous Methods....661
Async Methods That Don’t Return Data....661
Async Void Methods....662
Async Void Methods Using Task....663
Async Methods with Multiple Awaits....664
Calling Async Methods from Synchronous Methods....666
Await in catch and finally Blocks....667
Generalized Async Return Types (New 7.0)....668
Local Functions with async/await (New 7.0)....668
Cancelling async/await Operations....669
Cancelling async/await operations with WaitAsync() (New 10.0)....672
Cancelling async/await operations in Synchronous Calls....672
Asynchronous Streams (New 8.0)....672
The Parallel.ForEachAsync() Method (New 10.0)....673
Update the Book Reader App with async/await....674
Wrapping Up async and await....675
Summary....675
Chapter 16: Building and Configuring Class Libraries....676
Defining Custom Namespaces (Updated 10.0)....676
Resolving Name Clashes with Fully Qualified Names....678
Resolving Name Clashes with Aliases....679
Creating Nested Namespaces....680
Change the Root Namespace Using Visual Studio 2022....681
Change the Root Namespace Using the Project File....681
The Role of .NET Assemblies....682
Assemblies Promote Code Reuse....682
Assemblies Establish a Type Boundary....683
Assemblies Are Versionable Units....683
Assemblies Are Self-Describing....683
Understanding the Format of a .NET Assembly....683
Installing the C++ Profiling Tools....684
The Operating System (Windows) File Header....684
The CLR File Header....685
CIL Code, Type Metadata, and the Assembly Manifest....686
Optional Assembly Resources....686
Class Libraries vs. Console Applications....687
.NET Standard vs. .NET (Core) Class Libraries....687
Configuring Applications with Configuration Files....688
Multiple Configuration Files....690
Working with Objects (Updated 10.0)....690
Additional Configuration Options....693
Building and Consuming a .NET Class Library....694
Exploring the Manifest....696
Exploring the CIL....698
Exploring the Type Metadata....699
Building a C# Client Application....699
Building a Visual Basic Client Application....701
Cross-Language Inheritance in Action....702
Exposing internal Types to Other Assemblies....703
Using an Assembly Attribute....703
Using the Project File....704
NuGet and .NET Core....704
Packaging Assemblies with NuGet....704
Referencing NuGet Packages....705
Publishing Console Applications (Updated .NET 5/6)....706
Publishing Framework-Dependent Applications....707
Publishing Self-Contained Applications....707
Publishing Self-Contained Applications as a Single File....708
How .NET Locates Assemblies....709
Summary....711
Chapter 17: Type Reflection, Late Binding, Attribute, and Dynamic Types....712
The Necessity of Type Metadata....712
Viewing (Partial) Metadata for the EngineStateEnum Enumeration....713
Viewing (Partial) Metadata for the Car Type....714
Examining a TypeRef....716
Documenting the Defining Assembly....716
Documenting Referenced Assemblies....716
Documenting String Literals....717
Understanding Reflection....718
The System.Type Class....718
Obtaining a Type Reference Using System.Object.GetType()....719
Obtaining a Type Reference Using typeof()....720
Obtaining a Type Reference Using System.Type.GetType()....720
Building a Custom Metadata Viewer....721
Reflecting on Methods....721
Reflecting on Fields and Properties....722
Reflecting on Implemented Interfaces....722
Displaying Various Odds and Ends....723
Adding the Top-Level Statements....723
Reflecting on Static Types....725
Reflecting on Generic Types....725
Reflecting on Method Parameters and Return Values....725
Dynamically Loading Assemblies....727
Reflecting on Framework Assemblies....728
Understanding Late Binding....730
The System.Activator Class....730
Invoking Methods with No Parameters....732
Invoking Methods with Parameters....732
Understanding the Role of .NET Attributes....733
Attribute Consumers....734
Applying Attributes in C#....734
C# Attribute Shorthand Notation....735
Specifying Constructor Parameters for Attributes....736
The Obsolete Attribute in Action....736
Building Custom Attributes....738
Applying Custom Attributes....738
Named Property Syntax....739
Restricting Attribute Usage....739
Assembly-Level Attributes....740
Using a Separate File for Assembly Attributes....741
Using the Project File for Assembly Attributes....741
Reflecting on Attributes Using Early Binding....742
Reflecting on Attributes Using Late Binding....743
Putting Reflection, Late Binding, and Custom Attributes in Perspective....745
Building an Extendable Application....745
Building the Multiproject ExtendableApp Solution....746
Creating the Solution and Projects with the CLI....746
Adding PostBuild Events into the Project Files....746
Creating the Solution and Projects with Visual Studio....747
Setting Project Build Dependencies....748
Adding PostBuild Events....749
Building CommonSnappableTypes.dll....750
Building the C# Snap-In....750
Building the Visual Basic Snap-In....751
Adding the Code for the ExtendableApp....751
The Role of the C# dynamic Keyword....753
Calling Members on Dynamically Declared Data....755
The Scope of the dynamic Keyword....757
Limitations of the dynamic Keyword....757
Practical Uses of the dynamic Keyword....758
The Role of the Dynamic Language Runtime....758
The Role of Expression Trees....759
Dynamic Runtime Lookup of Expression Trees....759
Simplifying Late-Bound Calls Using Dynamic Types....760
Leveraging the dynamic Keyword to Pass Arguments....761
Summary....763
Chapter 18: Understanding CIL and the Role of Dynamic Assemblies....764
Motivations for Learning the Grammar of CIL....764
Examining CIL Directives, Attributes, and Opcodes....766
The Role of CIL Directives....766
The Role of CIL Attributes....766
The Role of CIL Opcodes....767
The CIL Opcode/CIL Mnemonic Distinction....767
Pushing and Popping: The Stack-Based Nature of CIL....768
Understanding Round-Trip Engineering....769
The Role of CIL Code Labels....772
Interacting with CIL: Modifying an *.il File....772
Compiling CIL Code with ILASM.EXE....773
Compiling CIL Code with Microsoft.NET.Sdk.il Projects....773
Understanding CIL Directives and Attributes....775
Specifying Externally Referenced Assemblies in CIL....775
Defining the Current Assembly in CIL....776
Defining Namespaces in CIL....777
Defining Class Types in CIL....777
Defining and Implementing Interfaces in CIL....778
Defining Structures in CIL....779
Defining Enums in CIL....779
Defining Generics in CIL....780
Compiling the CILTypes.il File....781
.NET Base Class Library, C#, and CIL Data Type Mappings....781
Defining Type Members in CIL....782
Defining Field Data in CIL....782
Defining Type Constructors in CIL....783
Defining Properties in CIL....783
Defining Member Parameters....784
Examining CIL Opcodes....785
The .maxstack Directive....787
Declaring Local Variables in CIL....787
Mapping Parameters to Local Variables in CIL....788
The Hidden this Reference....789
Representing Iteration Constructs in CIL....789
The Final Word on CIL....790
Understanding Dynamic Assemblies....790
Exploring the System.Reflection.Emit Namespace....791
The Role of the System.Reflection.Emit.ILGenerator....792
Emitting a Dynamic Assembly....793
Emitting the Assembly and Module Set....795
The Role of the ModuleBuilder TypeC....795
Emitting the HelloClass Type and the String Member Variable....796
Emitting the Constructors....797
Emitting the SayHello() Method....798
Using the Dynamically Generated Assembly....798
Summary....799
Part VI: File Handling, Object Serialization, and Data Access....800
Chapter 19: File I/O and Object Serialization....801
Exploring the System.IO Namespace....801
The Directory(Info) and File(Info) Types....802
The Abstract FileSystemInfo Base Class....803
Working with the DirectoryInfo Type....803
Enumerating Files with the DirectoryInfo Type....805
Creating Subdirectories with the DirectoryInfo Type....806
Working with the Directory Type....807
Working with the DriveInfo Class Type....808
Working with the FileInfo Class....809
The FileInfo.Create() Method....810
The FileInfo.Open() Method....811
The FileInfo.OpenRead() and FileInfo.OpenWrite() Methods....812
The FileInfo.OpenText() Method....813
The FileInfo.CreateText() and FileInfo.AppendText() Methods....813
Working with the File Type....814
Additional File-centric Members....814
The Abstract Stream Class....815
Working with FileStreams....816
Working with StreamWriters and StreamReaders....818
Writing to a Text File....818
Reading from a Text File....819
Directly Creating StreamWriter/StreamReader Types....820
Working with StringWriters and StringReaders....821
Working with BinaryWriters and BinaryReaders....822
Watching Files Programmatically....824
Understanding Object Serialization....826
The Role of Object Graphs....826
Creating the Sample Types and Top-Level Statements....827
Extensible Markup Language (XML)....829
Serializing and Deserializing with the XmlSerializer....831
Controlling the Generated XML Data....831
Serializing Objects Using the XmlSerializer....832
Serializing Collections of Objects....833
Deserializing Objects and Collections of Objects....833
JavaScript Object Notation (JSON) Serialization....834
Serializing and Deserializing with System.Text.Json....835
Controlling the Generated JSON Data....835
Serializing Objects Using the JsonSerializer....836
Including Fields....836
Pretty-Print the JSON....838
PascalCase or camelCase JSON....838
Ignoring Circular References with JsonSerializer (New 10)....840
Number Handling with JsonSerializer....840
JSON Property Ordering (New 10)....841
Support for IAsyncEnumerable (New 10)....842
Streaming Serialization....842
Streaming Deserialization....842
Potential Performance Issues Using JsonSerializerOptions....843
Web Defaults for JsonSerializer....843
General Defaults for JsonSerializer....843
Serializing Collections of Objects....844
Deserializing Objects and Collections of Objects....844
JsonConverters....844
Summary....846
Chapter 20: Data Access with ADO.NET....847
ADO.NET vs. ADO....847
Understanding ADO.NET Data Providers....848
ADO.NET Data Providers....849
The Types of the System.Data Namespace....850
The Role of the IDbConnection Interface....851
The Role of the IDbTransaction Interface....851
The Role of the IDbCommand Interface....851
The Role of the IDbDataParameter and IDataParameter Interfaces....852
The Role of the IDbDataAdapter and IDataAdapter Interfaces....853
The Role of the IDataReader and IDataRecord Interfaces....853
Abstracting Data Providers Using Interfaces....854
Setting Up SQL Server and Azure Data Studio....857
Installing SQL Server....857
Installing SQL Server in a Docker Container....857
Pulling the Image and Running SQL Server 2019....858
Installing SQL Server 2019....859
Installing a SQL Server IDE....859
Connecting to SQL Server....860
Connecting to SQL Server in a Docker Container....860
Connecting to SQL Server LocalDb....861
Connecting to Any Other SQL Server Instance....862
Restoring the AutoLot Database Backup....862
Copying the Backup File to Your Container....863
Restoring the Database with SSMS....863
Restoring the Database to SQL Server (Docker)....863
Restoring the Database to SQL Server (Windows)....864
Restoring the Database with Azure Data Studio....865
Creating the AutoLot Database....866
Creating the Database....867
Creating the Tables....867
Creating the Inventory Table....867
Creating the Makes Table....868
Creating the Customers Table....868
Creating the Orders Table....868
Creating the CreditRisks Table....869
Creating the Table Relationships....869
Creating the Inventory to Makes Relationship....869
Creating the Inventory to Orders Relationship....870
Creating the Orders to Customers Relationship....870
Creating the Customers to CreditRisks Relationship....870
Creating the GetPetName() Stored Procedure....871
Adding Test Records....871
Makes Records....871
Inventory Table Records....872
Customer Records....872
Order Records....873
CreditRisk Records....873
The ADO.NET Data Provider Factory Model....873
A Complete Data Provider Factory Example....874
A Potential Drawback with the Data Provider Factory Model....878
Diving Deeper into Connections, Commands, and DataReaders....878
Working with Connection Objects....879
Working with ConnectionStringBuilder Objects....881
Working with Command Objects....882
Working with Data Readers....883
Obtaining Multiple Result Sets Using a Data Reader....884
Working with Create, Update, and Delete Queries....885
Create the Car and CarViewModel Classes....886
Adding the InventoryDal Class....886
Adding Constructors....886
Opening and Closing the Connection....887
Adding IDisposable....887
Adding the Selection Methods....888
Inserting a New Car....890
Create the Strongly Type InsertCar() Method....890
Adding the Deletion Logic....891
Adding the Update Logic....891
Working with Parameterized Command Objects....892
Specifying Parameters Using the DbParameter Type....892
Update the GetCar Method....892
Update the DeleteCar Method....893
Update the UpdateCarPetName Method....893
Update the InsertAuto Method....894
Executing a Stored Procedure....895
Creating a Console-Based Client Application....896
Understanding Database Transactions....897
Key Members of an ADO.NET Transaction Object....898
Adding a Transaction Method to InventoryDal....899
Testing Your Database Transaction....901
Executing Bulk Copies with ADO.NET....902
Exploring the SqlBulkCopy Class....902
Creating a Custom Data Reader....902
Executing the Bulk Copy....906
Testing the Bulk Copy....907
Summary....908
Part VII: Entity Framework Core....909
Chapter 21: Introducing Entity Framework Core....910
Object-Relational Mappers....911
Understanding the Role of the Entity Framework Core....911
The Building Blocks of the Entity Framework....912
The DbContext Class....913
Creating a Derived DbContext....914
Configuring the DbContext....914
The Design-Time DbContext Factory....915
OnModelCreating....916
Saving Changes....916
Transaction and Save Point Support....916
Explicit Transactions and Execution Strategies....917
Saving/Saved Changes Events....918
The DbSet Class....918
The ChangeTracker....919
ChangeTracker Events....920
The StateChanged Event....920
The Tracked Event....921
Resetting DbContext State....921
Entities....921
Entity Properties and Database Columns....921
Table Mapping Schemes....922
Table-Per-Hierarchy Mapping....922
Table-per-Type Mapping....923
Navigation Properties and Foreign Keys....924
Missing Foreign Key Properties....925
One-to-Many Relationships....925
One-to-One Relationships....927
Many-to-Many Relationships....929
Many-to-Many Prior to EF Core 5....931
Cascade Behavior....931
Optional Relationships....932
Required Relationships....932
Entity Conventions....933
Mapping Properties to Columns....933
Overriding EF Core Conventions....934
Entity Framework Data Annotations....934
Annotations and Navigation Properties....939
The Fluent API....939
Class and Property Methods....939
Class and Property Mapping....939
Keys and Indices....939
Field Size and Nullability....940
Default Values....941
RowVersion/Concurrency Tokens....944
SQL Server Sparse Columns....944
Computed Columns....945
Check Constraints....945
One-to-Many Relationships....946
One-to-One Relationships....947
Many-to-Many Relationships....947
Excluding Entities from Migrations....949
Using IEntityTypeConfiguration Classes....949
Conventions, Annotations, and the Fluent API, Oh My!....952
Owned Entity Types....952
Query Types....955
Flexible Query/Table Mapping....958
Query Execution....958
Mixed Client-Server Evaluation....958
Tracking vs. NoTracking Queries....959
Code First vs. Database First....959
The EF Core Global Tool CLI Commands....960
The Migrations Commands....962
The Add Command....962
The Remove Command....964
The List Command....964
The Bundle Command....964
The Script Command....965
The Database Commands....966
The Drop Command....966
The Database Update Command....966
The DbContext Commands....967
The DbContext Scaffold Command....967
The DbContext Optimize Command....968
Summary....969
Chapter 22: Exploring Entity Framework Core....970
Creating Records....970
Entity State....971
Add a Single Record Using Add....971
Add a Single Record Using Attach....972
Add Multiple Records at Once....973
Identity Column Considerations When Adding Records....974
Adding an Object Graph....976
Add Many-to-Many Records....977
Add Sample Records....978
Clear the Sample Data....979
Querying Data....980
Get All Records....980
Filter Records....981
Sort Records....982
Reverse Sort Records....983
Paging....984
Retrieve a Single Record....985
Using First....986
Using Last....988
Using Single....989
Using Find....990
Aggregation Methods....991
Any( ) and All( )....992
Getting Data from Stored Procedures....993
Querying Related Data....994
Eager Loading....994
Filtered Include....997
Eager Loading with Split Queries....997
Many-to-Many Queries....998
Explicit Loading....998
Lazy Loading....1000
Updating Records....1003
Entity State....1003
Update Tracked Entities....1003
Update Nontracked Entities....1004
Deleting Records....1005
Entity State....1005
Delete Tracked Records....1005
Delete Nontracked Entities....1006
Catch Cascade Delete Failures....1007
Notable EF Core Features....1007
Global Query Filters....1007
Global Query Filters on Navigation Properties....1009
Explicit Loading with Global Query Filters....1010
Raw SQL Queries with LINQ....1011
Projections....1012
Handling Database-Generated Values....1013
Concurrency Checking....1015
Connection Resiliency....1017
Database Function Mapping....1018
EF.Functions....1020
Batching of Statements....1022
Value Converters....1023
Shadow Properties....1026
SQL Server Temporal Table Support....1028
Configure Temporal Tables....1028
Main Table and History Table Interactions....1032
Querying Temporal Tables....1033
Clearing Temporal Tables....1035
Summary....1038
Chapter 23: Build a Data Access Layer with Entity Framework Core....1039
Create the AutoLot.Dal and AutoLot.Models Projects....1039
Add the Database View....1040
Scaffold the DbContext and Entities....1041
Examine the Results....1041
Switch to Code First....1042
Create the DbContext Design-Time Factory....1042
Create the Initial Migration....1042
Applying the Migration....1043
Create the GlobalUsings Files....1044
Create Custom Exceptions....1045
Finalize the Entities and ViewModel....1046
The Entities....1046
The BaseEntity Class....1046
The Owned Person Entity....1047
The Car (Inventory) Entity....1047
Update the ApplicationDbContext Class....1051
The CarConfiguration Class....1052
The Driver Entity....1054
Update the ApplicationDbContext Class....1054
The DriverConfiguration Class....1054
The CarDriver Entity....1055
Update the ApplicationDbContext Class....1055
The CarDriverConfiguration Class....1055
The Radio Entity....1056
Update the ApplicationDbContext Class....1057
The RadioConfiguration Class....1057
The Customer Entity....1058
The CustomerConfiguration Class....1059
The Make Entity....1059
The MakeConfiguration Class....1060
The CreditRisk Entity....1061
The CreditRiskConfiguration Class....1062
The Order Entity....1063
The OrderConfiguration Class....1064
The SeriLogEntry Entity....1065
Update the ApplicationDbContext Class....1066
The SerilogEntryConfiguration Class....1066
The View Models....1066
The CustomerOrderViewModel....1066
Add the INonPersisted Interface....1068
Update the ApplicationDbContext Class....1068
The CustomerOrderViewModelConfiguration Class....1068
Update the GlobalUsings.cs Files....1069
The TemporalViewModel....1069
Update the ApplicationDbContext....1070
Add the Mapped Database Functions....1070
Handling DbContext and ChangeTracker Events....1070
Override the Conventions....1072
Override the SaveChanges Method....1072
Create the Next Migration and Update the Database....1073
Use EF Migrations to Create/Update Database Objects....1073
Add the MigrationHelpers Class....1073
Create and Update the Migration....1075
Apply the Migration....1075
Add the Repositories....1076
Add the IBaseViewRepo Interface....1076
Add the BaseViewRepo Implementation....1076
Implement the Read Methods....1078
Add the IBaseRepo Interface....1078
Add the BaseRepo Implementation....1079
Implement the SaveChanges Method....1079
Implement the Common Read Methods....1080
The Add, Update, and Delete Methods....1080
Add the ITemporalTableBaseRepo Interface....1081
Add the TemporalTableBaseRepo Implementation....1082
Implement the Helper Methods....1082
Implement the Temporal Methods....1082
Entity-Specific Repo Interfaces....1083
The CarDriver Repository Interface....1084
The Car Repository Interface....1084
The Credit Risk Interface....1084
The CustomerOrderViewModel Repository Interface....1084
The Customer Repository Interface....1085
The Driver Repository Interface....1085
The Make Repository Interface....1085
The Order Repository Interface....1085
The Radio Repository Interface....1086
Implement the Entity-Specific Repositories....1086
The CarDriver Repository....1086
The Car Repository....1087
The CreditRisk Repository....1089
The CustomerOrderViewModel Repository....1089
The Customer Repository....1089
The Driver Repository....1090
The Make Repository....1091
The Order Repository....1091
The Radio Repository....1092
Update the GlobalUsings.cs Files....1092
Programmatic Database and Migration Handling....1092
Drop, Create, and Clean the Database....1093
Data Initialization....1095
Create the Sample Data....1095
Load the Sample Data....1097
Summary....1098
Chapter 24: Test-Driving AutoLot....1099
Setting Up the Test-Drives....1099
Create the Project....1099
Make the AutoLot.Dal Internals Visible to AutoLot.Dal.Tests....1101
Add the GlobalUsings File....1101
A First Look at xUnit....1101
Fact Test Methods....1102
Theory Test Methods....1102
Executing Tests....1102
Configure the Project and DbContext Instances....1103
Create the Integration Test Helper....1103
Add the BaseTest Class....1104
Add the Transacted Test Execution Helpers....1105
Add the EnsureAutoLotDatabase Test Fixture Class....1106
Add the Integration Test Classes....1107
Querying the Database....1110
LINQ Queries....1110
LINQ Execution....1110
Get All Records....1111
Filter Records....1111
Sort Records....1115
Reverse Sort Records....1116
Single-Record Queries....1117
Using First....1117
Using Last....1118
Using Single....1119
Global Query Filters....1120
Disable the Query Filters....1120
Query Filters on Navigation Properties....1121
Load Related Data Eagerly....1122
Splitting Queries on Related Data....1124
Filtering Related Data....1127
Load Related Data Explicitly....1128
Load Related Data Explicitly with Query Filters....1129
Temporal Queries....1130
SQL Queries with LINQ....1131
Aggregate Methods....1132
Any() and All()....1134
Getting Data from Stored Procedures....1135
Creating Records....1135
Add a Single Record....1136
Add a Single Record Using Attach....1136
Add Multiple Records at Once....1137
Adding an Object Graph....1138
Updating Records....1139
Update Tracked Entities....1140
Update Nontracked Entities....1140
Concurrency Checking When Updating Records....1141
Deleting Records....1142
Delete Tracked Records....1142
Delete Nontracked Entities....1143
Catch Cascade Delete Failures....1143
Concurrency Checking When Deleting Records....1144
Summary....1144
Part VIII: Windows Client Development....1145
Chapter 25: Introducing Windows Presentation Foundation and XAML....1146
The Motivation Behind WPF....1146
Unifying Diverse APIs....1147
Providing a Separation of Concerns via XAML....1147
Providing an Optimized Rendering Model....1148
Simplifying Complex UI Programming....1148
Investigating the WPF Assemblies....1149
The Role of the Application Class....1150
Constructing an Application Class....1151
Enumerating the Windows Collection....1152
The Role of the Window Class....1152
The Role of System.Windows.Controls.ContentControl....1153
The Role of System.Windows.Controls.Control....1154
The Role of System.Windows.FrameworkElement....1155
The Role of System.Windows.UIElement....1156
The Role of System.Windows.Media.Visual....1156
The Role of System.Windows.DependencyObject....1156
The Role of System.Windows.Threading.DispatcherObject....1157
Understanding the Syntax of WPF XAML....1157
Introducing Kaxaml....1157
XAML XML Namespaces and XAML “Keywords”....1159
Controlling Class and Member Variable Visibility....1161
XAML Elements, XAML Attributes, and Type Converters....1162
Understanding XAML Property-Element Syntax....1163
Understanding XAML Attached Properties....1163
Understanding XAML Markup Extensions....1164
Building WPF Applications Using Visual Studio....1166
The WPF Project Templates....1167
The Toolbox and XAML Designer/Editor....1168
Setting Properties Using the Properties Window....1169
Handling Events Using the Properties Window....1171
Handling Events in the XAML Editor....1172
The Document Outline Window....1173
Enable or Disable the XAML Debugger....1173
Examining the App.xaml File....1175
Mapping the Window XAML Markup to C# Code....1176
The Role of BAML....1178
Solving the Mystery of Main()....1178
Interacting with Application-Level Data....1179
Handling the Closing of a Window Object....1180
Intercepting Mouse Events....1181
Intercepting Keyboard Events....1182
Summary....1183
Chapter 26: WPF Controls, Layouts, Events, and Data Binding....1184
A Survey of the Core WPF Controls....1184
The WPF Ink Controls....1185
The WPF Document Controls....1185
WPF Common Dialog Boxes....1185
A Brief Review of the Visual Studio WPF Designer....1186
Working with WPF Controls Using Visual Studio....1186
Working with the Document Outline Editor....1187
Controlling Content Layout Using Panels....1187
Positioning Content Within Canvas Panels....1189
Positioning Content Within WrapPanel Panels....1190
Positioning Content Within StackPanel Panels....1192
Positioning Content Within Grid Panels....1193
Sizing Grid Columns and Rows....1195
Grids with GridSplitter Types....1195
Positioning Content Within DockPanel Panels....1196
Enabling Scrolling for Panel Types....1197
Configuring Panels Using the Visual Studio Designers....1198
Building a Window’s Frame Using Nested Panels....1202
Building the Menu System....1203
Building Menus Visually....1204
Building the Toolbar....1205
Building the Status Bar....1205
Finalizing the UI Design....1205
Implementing the MouseEnter/MouseLeave Event Handlers....1206
Implementing the Spell-Checking Logic....1207
Understanding WPF Commands....1207
The Intrinsic Command Objects....1208
Connecting Commands to the Command Property....1209
Connecting Commands to Arbitrary Actions....1209
Working with the Open and Save Commands....1210
Understanding Routed Events....1212
The Role of Routed Bubbling Events....1213
Continuing or Halting Bubbling....1214
The Role of Routed Tunneling Events....1215
A Deeper Look at WPF APIs and Controls....1216
Working with the TabControl....1217
Building the Ink API Tab....1217
Designing the Toolbar....1218
The RadioButton Control....1218
Add the Save, Load, and Delete Buttons....1219
Add the InkCanvas Control....1219
Preview the Window....1219
Handling Events for the Ink API Tab....1220
Add Controls to the Toolbox....1220
The InkCanvas Control....1221
The ComboBox Control....1223
Saving, Loading, and Clearing InkCanvas Data....1225
Introducing the WPF Data-Binding Model....1226
Building the Data Binding Tab....1226
Establishing Data Bindings....1227
The DataContext Property....1227
Formatting the Bound Data....1228
Data Conversion Using IValueConverter....1229
Establishing Data Bindings in Code....1230
Building the DataGrid Tab....1231
Understanding the Role of Dependency Properties....1233
Examining an Existing Dependency Property....1235
Important Notes Regarding CLR Property Wrappers....1237
Building a Custom Dependency Property....1238
Adding a Data Validation Routine....1240
Responding to the Property Change....1241
Summary....1242
Chapter 27: WPF Graphics Rendering Services....1243
Understanding WPF’s Graphical Rendering Services....1243
WPF Graphical Rendering Options....1244
Rendering Graphical Data Using Shapes....1245
Adding Rectangles, Ellipses, and Lines to a Canvas....1246
Removing Rectangles, Ellipses, and Lines from a Canvas....1249
Working with Polylines and Polygons....1249
Working with Paths....1250
The Path Modeling “Mini-Language”....1252
WPF Brushes and Pens....1253
Configuring Brushes Using Visual Studio....1254
Configuring Brushes in Code....1257
Configuring Pens....1258
Applying Graphical Transformations....1258
A First Look at Transformations....1259
Transforming Your Canvas Data....1260
Working with the Visual Studio Transform Editor....1262
Building the Initial Layout....1262
Applying Transformations at Design Time....1264
Transforming the Canvas in Code....1265
Rendering Graphical Data Using Drawings and Geometries....1266
Building a DrawingBrush Using Geometries....1266
Painting with the DrawingBrush....1267
Containing Drawing Types in a DrawingImage....1268
Working with Vector Images....1268
Converting a Sample Vector Graphic File into XAML....1269
Importing the Graphical Data into a WPF Project....1270
Interacting with the Sign....1271
Rendering Graphical Data Using the Visual Layer....1271
The Visual Base Class and Derived Child Classes....1271
A First Look at Using the DrawingVisual Class....1272
Rendering Visual Data to a Custom Layout Manager....1274
Responding to Hit-Test Operations....1276
Summary....1277
Chapter 28: WPF Resources, Animations, Styles, and Templates....1278
Understanding the WPF Resource System....1278
Working with Binary Resources....1279
Including Loose Resource Files in a Project....1280
Configuring the Loose Resources....1280
Programmatically Loading an Image....1280
Embedding Application Resources....1282
Working with Object (Logical) Resources....1282
The Role of the Resources Property....1283
Defining Window-wide Resources....1283
The {StaticResource} Markup Extension....1286
The {DynamicResource} Markup Extension....1286
Application-Level Resources....1287
Defining Merged Resource Dictionaries....1288
Defining a Resource-Only Assembly....1289
Understanding WPF’s Animation Services....1290
The Role of the Animation Class Types....1290
The To, From, and By Properties....1291
The Role of the Timeline Base Class....1291
Authoring an Animation in C# Code....1292
Controlling the Pace of an Animation....1293
Reversing and Looping an Animation....1294
Authoring Animations in XAML....1295
The Role of Storyboards....1296
The Role of Event Triggers....1296
Animation Using Discrete Key Frames....1297
Understanding the Role of WPF Styles....1298
Defining and Applying a Style....1298
Overriding Style Settings....1299
The Effect of TargetType on Styles....1299
Subclassing Existing Styles....1301
Defining Styles with Triggers....1301
Defining Styles with Multiple Triggers....1302
Animated Styles....1303
Assigning Styles Programmatically....1303
Logical Trees, Visual Trees, and Default Templates....1305
Programmatically Inspecting a Logical Tree....1305
Programmatically Inspecting a Visual Tree....1307
Programmatically Inspecting a Control’s Default Template....1308
Building a Control Template with the Trigger Framework....1311
Templates as Resources....1312
Incorporating Visual Cues Using Triggers....1313
The Role of the {TemplateBinding} Markup Extension....1314
The Role of ContentPresenter....1315
Incorporating Templates into Styles....1315
Summary....1316
Chapter 29: WPF Notifications, Validations, Commands, and MVVM....1317
Introducing Model-View-ViewModel....1317
The Model....1317
The View....1318
The View Model....1318
Anemic Models or Anemic View Models....1318
The WPF Binding Notification System....1319
Observable Models and Collections....1319
Adding Bindings and Data....1321
Programmatically Changing the Vehicle Data....1322
Observable Models....1322
Using nameof....1324
Observable Collections....1324
Using the ObservableCollections Class....1324
Implementing a Dirty Flag....1324
Updating the Source Through UI Interaction....1326
Wrapping Up Notifications and Observables....1326
WPF Validations....1326
Updating the Sample for the Validation Examples....1327
The Validation Class....1327
Validation Options....1327
Notify on Exceptions....1327
IDataErrorInfo....1328
INotifyDataErrorInfo....1331
Implement the Supporting Code....1331
Use INotifyDataErrorInfo for Validations....1333
Combine IDataErrorInfo with INotifyDataErrorInfo for Validations....1334
Show All Errors....1336
Move the Support Code to a Base Class....1337
Leverage Data Annotations with WPF....1338
Add Data Annotations to the Model....1338
Check for Data Annotation–Based Validation Errors....1338
Customizing the ErrorTemplate....1340
Wrapping Up Validations....1342
Creating Custom Commands....1343
Implementing the ICommand Interface....1343
Adding the ChangeColorCommand....1343
Attaching the Command to the CommandManager....1344
Updating MainWindow.xaml.cs....1344
Updating MainWindow.xaml....1345
Testing the Application....1345
Creating the CommandBase Class....1346
Adding the AddCarCommand Class....1347
Updating MainWindow.xaml.cs....1347
Updating MainWindow.xaml....1348
Updating ChangeColorCommand....1348
RelayCommands....1348
Creating the Base RelayCommand....1348
Creating RelayCommand....1349
Updating MainWindow.xaml.cs....1350
Adding and Implementing the Delete Car Button....1350
Wrapping Up Commands....1350
Migrate Code and Data to a View Model....1351
Moving the MainWindow.xaml.cs Code....1351
Updating the MainWindow Code and Markup....1352
Updating the Control Markup....1352
Wrapping Up View Models....1353
Updating AutoLot.Dal for MVVM....1353
Summary....1353
Part IX: ASP.NET Core....1354
Chapter 30: Introducing ASP.NET Core....1355
A Quick Look Back at ASP.NET MVC....1355
Introducing the MVC Pattern....1355
The Model....1355
The View....1356
The Controller....1356
ASP.NET Core and the MVC Pattern....1356
ASP.NET Core and .NET Core....1356
One Framework, Many Uses....1357
Create and Configure the Solution and Projects....1357
Using Visual Studio 2022....1357
Create the Solution and Projects....1357
Add in AutoLot.Models and AutoLot.Dal....1360
Add the Project References....1360
Add the NuGet Packages....1361
Using the Command Line....1362
Update the Entity Framework Core Package Reference....1364
Disable Nullable Reference Types For All Projects....1365
Create a GlobalUsing.cs Class in Each Project....1365
Running ASP.NET Core Applications....1365
Using Visual Studio....1366
Using Visual Studio Code....1367
Using the Command Line or Terminal Window....1367
Changing Code While Debugging....1367
Debugging ASP.NET Core Applications....1367
Attaching with Visual Studio....1368
Attaching with Visual Studio Code....1368
Update the AutoLot.Api and AutoLot.Web Kestrel Ports....1369
ASP.NET Core Concepts from MVC/Web API....1370
Convention over Configuration....1370
Naming Conventions....1370
Controllers and Actions (MVC Based Web Apps and RESTful Services)....1371
The Controller Class....1371
The ControllerBase Class....1371
Actions....1373
Antiforgery Tokens....1373
Opting In (MVC Style Web Apps)....1373
Opting Out (Razor Page Web Apps)....1374
Directory Structure Conventions....1374
The Controllers Folder....1374
The Views Folder....1374
The Shared Folder....1374
The Pages Folder....1374
The Shared Folder....1374
The Areas Folder....1375
The wwwroot Folder....1375
Routing....1375
URL Patterns and Route Tokens....1375
Handling Duplicate C# Method Signatures....1376
Custom Route Tokens....1376
Route Token Constraints....1377
Conventional Routing (MVC Style Web Apps)....1377
Area Routes....1379
Named Routes....1379
Attribute Routing (MVC Style Web Apps and RESTful Services)....1379
Razor Page Routing....1381
Routing and HTTP Verbs....1382
HTTP Verbs in MVC Styled Web Application Attribute Routing....1382
HTTP Verbs in RESTful Service Routing....1383
HTTP Verbs in Razor Page Routing....1384
Redirecting Using Routing....1385
Model Binding....1385
The ModelState Dictionary....1386
Adding Custom Errors to the ModelState Dictionary....1386
Clearing the ModelState Dictionary....1386
Implicit Model Binding....1387
Explicit Model Binding....1387
Property Model Binding....1389
Handling Property Name Prefixes....1389
Preventing Over Posting....1390
Controlling Model Binding Sources in ASP.NET Core....1391
Model Validation....1392
Explicit Model Validation....1393
Filters....1394
Authorization Filters....1395
Resource Filters....1395
Action Filters....1395
Page Filters....1395
Exception Filters....1395
Result Filters....1395
Summary....1395
Chapter 31: Diving Into ASP.NET Core....1396
What’s New in ASP.NET Core....1396
Razor Pages....1396
The Razor Page File....1397
The PageModel Class....1397
Page Handler Methods....1398
Environmental Awareness....1399
Determining the Runtime Environment....1399
The WebAppBuilder and WebApp....1402
The Program.cs File with RESTful Services....1402
The Program.cs File with MVC Style Applications....1403
The Program.cs File with Razor Page Based Applications....1404
Application Configuration....1405
Built-in Dependency Injection....1406
Adding Web App Support To The Dependency Injection Container....1407
Adding Derived DbContext Classes into the DI Container....1408
Adding Custom Services To The Dependency Injection Container....1409
Dependency Hierarchies....1410
Injecting Dependencies....1410
Getting Dependencies in Program.cs....1411
Build the Shared Data Services....1412
The Interfaces....1413
The AutoLot.Dal Direct Implementation....1413
The API Initial Implementation....1415
Adding the Data Services to the DI Container....1416
The Options Pattern in ASP.NET Core....1417
Using the Options Pattern....1418
The HTTP Client Factory....1420
Basic Usage....1420
Named Clients....1421
Typed Clients....1421
The AutoLot API Service Wrapper....1422
Update the Application Configuration....1423
Create the ApiServiceSettings Class....1423
Register the ApiServiceSettings Class....1424
The API Service Wrapper Base Class and Interface....1424
The IApiServiceWrapperBase Interface....1425
The ApiServiceWrapperBase Class....1425
Configuring the HttpClient in the Constructor....1426
The Internal Support Methods....1426
The Post and Put Helper Methods....1426
The HTTP Delete Helper Method Call....1427
The HTTP Get Calls....1427
The HTTP Post Call....1428
The HTTP Put Call....1428
The HTTP Delete Call....1429
The Entity Specific Interfaces....1429
The Entity Specific Classes....1429
Complete the API Data Services....1430
Complete the ApiDataServiceBase Class....1430
Complete the Entity Specific Classes....1431
Deploying ASP.NET Core Applications....1432
Lightweight and Modular HTTP Request Pipeline....1432
Logging....1432
Add Logging with Serilog....1433
The Logging Settings....1434
The Logging Configuration....1437
The AutoLot Logging Framework....1439
The IAppLogging Interface....1439
The AppLogging Class....1441
Final Configuration....1443
Add Logging to the Data Services....1444
Update the Base Classes....1444
Update the Entity Specific Data Services Classes....1445
Test-Drive the Logging Framework....1446
String Utilities....1446
Summary....1447
Chapter 32: RESTful Services with ASP.NET Core....1448
Introducing ASP.NET Core RESTful Services....1448
Controller Actions with RESTful Services....1449
Formatted JSON Response Results....1449
Configuring JSON Handling....1452
The ApiController Attribute....1453
Attribute Routing Requirement....1454
Automatic 400 Responses....1454
Binding Source Parameter Inference....1455
Problem Details for Error Status Codes....1456
Reset the Settings....1457
API Versioning....1458
Microsoft’s REST API Guidelines....1458
Add Versioning NuGet Packages....1459
The ApiVersion Class....1459
Add API Version Support....1460
Update the Top Level Statements....1462
API Versions and Naming Convention Updates....1462
The API Version Attributes....1463
Version Interleaving....1464
Controller Splitting....1465
Query String Version Requests and Routing....1466
Attribute Precedence....1467
Getting the API Version in Requests....1468
Route Updates for URL Segment Versioning....1468
URL Segment Versioning and Version Status Values....1468
Deprecating Versions....1469
Unsupported Version Requests....1469
Add the API Version Explorer....1470
Update the Swagger/OpenAPI Settings....1471
Add the XML Documentation File....1471
The Application’s Swagger Settings....1475
The SwaggerDefaultValues Operation Filter....1477
The ConfigureSwaggerOptions Class....1478
Update the SwaggerGen() Call....1480
Update the UseSwaggerUI() Call....1481
View the Results in the Swagger UI....1482
Additional Documentation Options for API Endpoints....1486
Building The BaseCrudController....1487
The Constructor....1488
The Get Methods....1488
The UpdateOne Method....1490
The AddOne Method....1492
The DeleteOne Method....1493
The CarsController....1494
The Remaining Controllers....1495
Exception Filters....1497
Create the CustomExceptionFilter....1497
Apply the Filter....1499
Test the Exception Filter....1499
Add Cross-Origin Requests Support....1500
Create a CORS Policy....1500
Add the CORS Policy to the HTTP Pipeline Handling....1500
Basic Authentication....1501
Add and Configure the Security Information....1501
Build the Basic Authentication Handler....1502
Register the Basic Authentication Handler and Secure the Controllers....1504
Summary....1507
Chapter 33: Web Applications with MVC....1508
Introducing the “V” in ASP.NET Core....1508
ViewResults and Action Methods....1508
The Razor View Engine and Razor Syntax....1511
Views....1514
The Views Directory....1514
The Shared Directory....1515
The DisplayTemplates Folder....1515
The DateTime Display Template....1515
The Car Display Template....1516
The Car with Color Display Template....1517
The EditorTemplates Folder....1517
The Car Edit Template....1517
View CSS Isolation....1518
Layouts....1519
Specifying the Layout for a View....1520
Partial Views....1521
Split the Layout into Partials....1521
Create the Partials....1521
The Head Partial....1521
The Menu Partial....1522
The JavaScript Files Partial....1522
Sending Data to Views....1523
Strongly Typed Views and View Models....1523
ViewBag, ViewData, and TempData....1524
Injecting Data....1525
Managing Client-Side Libraries....1526
Install Library Manager As a .NET Global Tool....1526
Add Client-Side Libraries to AutoLot.Mvc....1526
Add the libman.json File....1526
Visual Studio....1526
Command Line....1527
Update the libman.json File....1527
Update the JavaScript and CSS References....1529
Bundling and Minification....1529
Bundling....1530
Minification....1530
The WebOptimizer Solution....1530
Add and Configure WebOptimizer....1530
Update _ViewImports.cshtml....1532
The Controllers....1532
The HomeController....1533
The BaseCrudController....1534
The IndexAsync Method....1535
The DetailsAsync Method....1535
The CreateAsync Action Methods....1536
The Get Method....1536
The Post Method....1536
The EditAsync Action Methods....1537
The Get Method....1537
The Post Method....1538
The DeleteAsync Action Methods....1538
The Delete Get Method....1539
The Delete Post Method....1539
Using a BindProperty....1540
The CarsController....1541
Areas....1543
Area Routing....1543
The MakesController Area Controller....1544
_ViewImports and _ViewStart....1545
Tag Helpers....1545
Enabling Tag Helpers....1548
The Form Tag Helper....1548
The Cars Create Form....1549
The Form Action Button/Image Tag Helper....1550
The Anchor Tag Helper....1550
The Input Tag Helper....1551
The TextArea Tag Helper....1552
The Select Tag Helper....1552
The Validation Tag Helpers....1553
The Environment Tag Helper....1554
The Link Tag Helper....1555
The Script Tag Helper....1557
The Image Tag Helper....1558
Custom Tag Helpers....1558
Set the Foundation....1559
Update Program.cs....1559
Create the Base Class....1559
The Item Details Tag Helper....1560
The Item Delete Tag Helper....1561
The Item Edit Tag Helper....1562
The Item Create Tag Helper....1563
The Item List Tag Helper....1563
Making Custom Tag Helpers Visible....1564
HTML Helpers....1564
The DisplayFor HTML Helper....1565
The DisplayForModel HTML Helper....1565
The EditorFor and EditorForModel HTML Helpers....1566
The Car Views....1566
The Car List Partial View....1566
The Index View....1568
The ByMake View....1568
The Details View....1569
The Create View....1570
The Edit View....1572
The Delete View....1573
View Components....1574
The Server-Side Code....1575
Build the Partial View....1576
Invoking View Components....1576
Updating the Menu....1577
Custom Validation Attributes....1578
Set the Stage....1578
The ViewModel....1578
The View....1579
The Validation Action Methods....1580
The Validation Menu Item....1580
Server-Side Validation....1580
The MustBeGreaterThanZero Validation Attribute....1581
The MustNotBeGreaterThan Validation Attribute....1583
Client-Side Validation....1585
Client-Side Error Formatting....1586
The MustBeGreaterThanZero Validation Attribute....1587
The MustNotBeGreaterThan Validation Attribute....1588
Update the Validation Scripts Partial....1590
General Data Protection Regulation Support....1590
Add Cookie Policy Support....1590
The Cookie Support Partial View....1591
Menu Support to Accept/Withdraw Cookie Policy Consent....1592
Finish the Admin Area....1594
Run AutoLot.Mvc and AutoLot.Api Together....1596
Using Visual Studio....1596
Using the Command Line....1597
Summary....1598
Chapter 34: Web Applications using Razor Pages....1599
Anatomy of a Razor Page....1599
Razor Page PageModel Classes and Page Handler Methods....1599
Razor Page Views....1602
Razor Views....1604
The _ViewStart and _ViewImports Views....1604
The Shared Directory....1604
The DisplayTemplates Folder....1605
The DateTime Display Template....1605
The Car Display Template....1605
The Car with Color Display Template....1607
The EditorTemplates Folder....1607
The Car Edit Template....1607
View CSS Isolation....1608
Layouts....1608
Injecting Data....1608
Partial Views....1609
Create the Partials....1609
Sending Data to Partials....1609
ViewBag, ViewData, and TempData....1610
Add Client-Side Libraries to AutoLot.Web....1610
Add the libman.json File....1610
Visual Studio....1610
Command Line....1611
Update the libman.json File....1611
Update the JavaScript and CSS References....1612
Add and Configure WebOptimizer....1614
Tag Helpers....1615
Enabling Tag Helpers....1616
The Form Tag Helper....1616
The Form Action Button/Image Tag Helper....1617
The Anchor Tag Helper....1617
Custom Tag Helpers....1617
Update Program.cs....1618
Create the Base Class....1618
The Item Details Tag Helper....1619
The Item Delete Tag Helper....1620
The Item Edit Tag Helper....1621
The Item Create Tag Helper....1621
The Item List Tag Helper....1622
Making Custom Tag Helpers Visible....1623
The Cars Razor Pages....1623
The BasePageModel Class....1623
The Index Razor Page....1626
The Car List Partial View....1627
The Index Razor Page View....1629
The Details Razor Page....1629
The Details Razor Page View....1630
The Create Razor Page....1630
The Create Razor Page View....1631
The Edit Razor Page....1632
The Edit Razor Page View....1633
The Delete Razor Page....1634
The Delete Razor Page View....1635
View Components....1636
Build the Partial View....1637
Areas....1638
Area Routing with Razor Pages....1638
_ViewImports and _ViewStart....1638
The Makes Razor Pages....1638
The Make DisplayTemplate....1638
The Make EditorTemplate....1638
The Index Razor Page....1639
The Index Razor Page View....1639
The Details Razor Page....1640
The Details Razor Page View....1640
The Create Razor Page....1641
The Create Razor Page View....1641
The Edit Razor Page....1642
The Edit Razor Page View....1642
The Delete Razor Page....1643
The Delete Razor Page View....1643
Add the Area Menu Item....1644
Custom Validation Attributes....1644
General Data Protection Regulation Support....1647
The Cookie Support Partial View....1648
Menu Support to Accept/Withdraw Cookie Policy Consent....1649
Summary....1650
Index....1651
Welcome to the most comprehensive foundational guide available on the topic of C# coding and .NET. This book goes beyond “do this, to achieve this” to drill down into the core stuff that makes a good developer, great. This expanded 11th edition delivers loads of new content on Entity Framework, Razor Pages, Web APIs and more. You will find the latest C# 10 and .NET 6 features served up with plenty of “behind the curtain” discussion designed to expand developers’ critical thinking skills when it comes to their craft. Coverage of ASP.NET Core, Entity Framework Core, and more sits alongside the latest updates to the new unified .NET platform, from performance improvements to Windows Desktop apps on .NET 6, updates in XAML tooling, and expanded coverage of data files and data handling. Going beyond the latest features in C# 10, all code samples are rewritten for this latest release.
Dive in and discover why this essential classic is a favorite of C# developers worldwide. Gain a solid foundation in object-oriented development techniques, attributes and reflection, generics and collections, and numerous advanced topics not found in other texts (such as CIL opcodes and emitting dynamic assemblies). Pro C# 10 with .NET 6 will build your coding confidence putting C# into practice, and exploring the .NET universe and its vast potential on your own terms.
Developers of any level who want to either learn C# and .NET or want to take their skills to the next level.