100% found this document useful (3 votes)
13 views

Pro C# 10 with .NET 6: Foundational Principles and Practices in Programming 11th Edition Andrew Troelsen download

The document provides information about the book 'Pro C# 10 with .NET 6: Foundational Principles and Practices in Programming, 11th Edition' by Andrew Troelsen and Phil Japikse, including links for download and details about its content. It covers foundational programming concepts using C# and .NET 6, along with practical applications and examples. Additionally, it includes references to other related books and resources available for download.

Uploaded by

roohibashaud
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (3 votes)
13 views

Pro C# 10 with .NET 6: Foundational Principles and Practices in Programming 11th Edition Andrew Troelsen download

The document provides information about the book 'Pro C# 10 with .NET 6: Foundational Principles and Practices in Programming, 11th Edition' by Andrew Troelsen and Phil Japikse, including links for download and details about its content. It covers foundational programming concepts using C# and .NET 6, along with practical applications and examples. Additionally, it includes references to other related books and resources available for download.

Uploaded by

roohibashaud
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 78

Pro C# 10 with .

NET 6: Foundational Principles


and Practices in Programming 11th Edition Andrew
Troelsen install download

https://ebookmeta.com/product/pro-c-10-with-net-6-foundational-
principles-and-practices-in-programming-11th-edition-andrew-
troelsen/

Download more ebook from https://ebookmeta.com


We believe these products will be a great fit for you. Click
the link to download now, or visit ebookmeta.com
to discover even more!

Pro C# 10 with .NET 6 : Foundational Principles and


Practices in Programming 11th Edition Andrew Troelsen

https://ebookmeta.com/product/pro-c-10-with-net-6-foundational-
principles-and-practices-in-programming-11th-edition-andrew-
troelsen-2/

Pro C# 9 with .NET 5: Foundational Principles and


Practices in Programming 10th Edition Andrew Troelsen

https://ebookmeta.com/product/pro-c-9-with-net-5-foundational-
principles-and-practices-in-programming-10th-edition-andrew-
troelsen/

Pro C# 7: With .NET and .NET Core - Eighth Edition


Andrew Troelsen

https://ebookmeta.com/product/pro-c-7-with-net-and-net-core-
eighth-edition-andrew-troelsen/

Old Age and Political Behavior Frank A. Pinner

https://ebookmeta.com/product/old-age-and-political-behavior-
frank-a-pinner/
Meta Television: A History of US Popular Television's
Self-Awareness 1st Edition Erin Giannini

https://ebookmeta.com/product/meta-television-a-history-of-us-
popular-televisions-self-awareness-1st-edition-erin-giannini/

Strategic Corporate Communication in the Digital Age


1st Edition Mark Anthony Camilleri

https://ebookmeta.com/product/strategic-corporate-communication-
in-the-digital-age-1st-edition-mark-anthony-camilleri/

Bolt Action World War II Wargames Rules 2nd Edition


Warlord Games Peter Dennis Illustrations

https://ebookmeta.com/product/bolt-action-world-war-ii-wargames-
rules-2nd-edition-warlord-games-peter-dennis-illustrations/

Essential Econometric Techniques A Guide to Concepts


and Applications 3rd Edition Elia Kacapyr

https://ebookmeta.com/product/essential-econometric-techniques-a-
guide-to-concepts-and-applications-3rd-edition-elia-kacapyr/

Win the day seven daily habits to help you stress less
and accomplish more First Edition. Edition Mark
Batterson

https://ebookmeta.com/product/win-the-day-seven-daily-habits-to-
help-you-stress-less-and-accomplish-more-first-edition-edition-
mark-batterson/
Semiconductor Basics A Qualitative Non mathematical
Explanation of How Semiconductors Work and How They are
Used 1st Edition George Domingo

https://ebookmeta.com/product/semiconductor-basics-a-qualitative-
non-mathematical-explanation-of-how-semiconductors-work-and-how-
they-are-used-1st-edition-george-domingo/
Pro C# 10 with .NET 6
Foundational Principles and Practices
in Programming

Eleventh Edition

Andrew Troelsen
Phil Japikse
Pro C# 10 with .NET 6: Foundational Principles and Practices in Programming

Andrew Troelsen Phil Japikse


Chambersburg, PA, USA West Chester, OH, USA

ISBN-13 (pbk): 978-1-4842-7868-0 ISBN-13 (electronic): 978-1-4842-7869-7


https://doi.org/10.1007/978-1-4842-7869-7

Copyright © 2022 by Andrew Troelsen, Phil Japikse


This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with
every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an
editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the
trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not
identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Joan Murray
Development Editor: Laura Berendson
Coordinating Editor: Mark Powers
Copyeditor: Kim Wimpsett
Cover designed by eStudioCalamar
Cover image by Shutterstock (www.shutterstock.com)
Distributed to the book trade worldwide by Apress Media, LLC, 1 New York Plaza, New York, NY 10004,
U.S.A. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@springer-sbm.com, or visit www.
springeronline.com. Apress Media, LLC is a California LLC and the sole member (owner) is Springer
Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation.
For information on translations, please e-mail booktranslations@springernature.com; for reprint,
paperback, or audio rights, please e-mail bookpermissions@springernature.com.
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and
licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales
web page at www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to
readers on GitHub. For more detailed information, please visit www.apress.com/source-code.
Printed on acid-free paper
To my family, Amy, Conner, Logan, and Skylar,
thank you for all of the support and patience you have given me.
Also, to my father (Cor);
father, husband, inventor, and my center of excellence.
—Phil
Table of Contents

About the Authors����������������������������������������������������������������������������������������������������� li


About the Technical Reviewers������������������������������������������������������������������������������ liii
Acknowledgments��������������������������������������������������������������������������������������������������� lv
Introduction����������������������������������������������������������������������������������������������������������� lvii


■Part I: Introducing C# and .NET 6������������������������������������������������������� 1

■Chapter 1: Introducing C# and .NET 6�������������������������������������������������������������������� 3
Exploring Some Key Benefits of the .NET Platform���������������������������������������������������������� 4
Understanding the .NET Support Lifecycle����������������������������������������������������������������������� 4
Previewing the Building Blocks of the .NET Platform������������������������������������������������������� 5
The Role of the Base Class Libraries������������������������������������������������������������������������������������������������������ 5
What C# Brings to the Table������������������������������������������������������������������������������������������������������������������� 6
Managed vs. Unmanaged Code�������������������������������������������������������������������������������������������������������������� 7

Using Additional .NET–Aware Programming Languages�������������������������������������������������� 7


Getting an Overview of .NET Assemblies������������������������������������������������������������������������� 8
The Role of the Common Intermediate Language���������������������������������������������������������������������������������� 8
Benefits of CIL�������������������������������������������������������������������������������������������������������������������������������������� 11
Compiling CIL to Platform-Specific Instructions����������������������������������������������������������������������������������� 11
The Role of .NET Type Metadata����������������������������������������������������������������������������������������������������������� 12
The Role of the Assembly Manifest������������������������������������������������������������������������������������������������������ 13
Understanding the Common Type System���������������������������������������������������������������������� 13
CTS Class Types������������������������������������������������������������������������������������������������������������������������������������ 14
CTS Interface Types������������������������������������������������������������������������������������������������������������������������������ 14

v
■ Table of Contents

CTS Structure Types����������������������������������������������������������������������������������������������������������������������������� 15


CTS Enumeration Types������������������������������������������������������������������������������������������������������������������������ 15
CTS Delegate Types������������������������������������������������������������������������������������������������������������������������������ 16
CTS Type Members������������������������������������������������������������������������������������������������������������������������������� 16
Intrinsic CTS Data Types����������������������������������������������������������������������������������������������������������������������� 16

Understanding the Common Language Specification���������������������������������������������������� 17


Ensuring CLS Compliance��������������������������������������������������������������������������������������������������������������������� 19

Understanding the .NET Runtime����������������������������������������������������������������������������������� 19


Distinguishing Between Assembly, Namespace, and Type��������������������������������������������� 19
Accessing a Namespace Programmatically����������������������������������������������������������������������������������������� 22
Global Using Statements (New 10.0)���������������������������������������������������������������������������������������������������� 22
File Scoped Namespaces (New 10.0)��������������������������������������������������������������������������������������������������� 24
Referencing External Assemblies��������������������������������������������������������������������������������������������������������� 24

Exploring an Assembly Using ildasm.exe����������������������������������������������������������������������� 25


Summary������������������������������������������������������������������������������������������������������������������������ 25

■Chapter 2: Building C# Applications�������������������������������������������������������������������� 27
Installing .NET 6������������������������������������������������������������������������������������������������������������� 27
Understanding the .NET Version Numbering Scheme��������������������������������������������������������������������������� 27
Confirming the .NET 6 Install���������������������������������������������������������������������������������������������������������������� 28

Building .NET Core Applications with Visual Studio�������������������������������������������������������� 29


Installing Visual Studio 2022 (Windows)����������������������������������������������������������������������������������������������� 30
Taking Visual Studio 2022 for a Test-Drive������������������������������������������������������������������������������������������� 31
Building .NET Core Applications with Visual Studio Code����������������������������������������������� 44
Taking Visual Studio Code for a Test-Drive������������������������������������������������������������������������������������������� 44

Finding the .NET Core and C# Documentation��������������������������������������������������������������� 47


Summary������������������������������������������������������������������������������������������������������������������������ 48

■Part II: Core C# Programming����������������������������������������������������������� 49

■Chapter 3: Core C# Programming Constructs, Part 1������������������������������������������ 51
Breaking Down a Simple C# Program (Updated C# 10)�������������������������������������������������� 51
Using Variations of the Main() Method (Updated 7.1)��������������������������������������������������������������������������� 53

vi
■ Table of Contents

Using Top-Level Statements (New 9.0)������������������������������������������������������������������������������������������������� 54


Specifying an Application Error Code (Updated 9.0)����������������������������������������������������������������������������� 56
Processing Command-Line Arguments (Updated 9.0)�������������������������������������������������������������������������� 58
Specifying Command-Line Arguments with Visual Studio 2022����������������������������������������������������������� 60

Additional Members of the System.Environment Class (Updated 10.0)������������������������� 61


Using the System.Console Class������������������������������������������������������������������������������������ 62
Performing Basic Input and Output (I/O) with the Console Class��������������������������������������������������������� 63
Formatting Console Output������������������������������������������������������������������������������������������������������������������� 64
Formatting Numerical Data������������������������������������������������������������������������������������������������������������������ 65
Formatting Numerical Data Beyond Console Applications������������������������������������������������������������������� 66

Working with System Data Types and Corresponding C# Keywords������������������������������ 67


Understanding Variable Declaration and Initialization�������������������������������������������������������������������������� 68
Using Intrinsic Data Types and the new Operator (Updated 9.0)���������������������������������������������������������� 70
Understanding the Data Type Class Hierarchy�������������������������������������������������������������������������������������� 71
Understanding the Members of Numerical Data Types������������������������������������������������������������������������ 72
Understanding the Members of System.Boolean��������������������������������������������������������������������������������� 73
Understanding the Members of System.Char��������������������������������������������������������������������������������������� 73
Parsing Values from String Data����������������������������������������������������������������������������������������������������������� 74
Using TryParse to Parse Values from String Data��������������������������������������������������������������������������������� 74
Using System.DateTime and System.TimeSpan (Updated 10.0)���������������������������������������������������������� 75
Working with the System.Numerics Namespace��������������������������������������������������������������������������������� 76
Using Digit Separators (New 7.0)��������������������������������������������������������������������������������������������������������� 77
Using Binary Literals (New 7.0/7.2)������������������������������������������������������������������������������������������������������ 78

Working with String Data����������������������������������������������������������������������������������������������� 78


Performing Basic String Manipulation�������������������������������������������������������������������������������������������������� 79
Performing String Concatenation��������������������������������������������������������������������������������������������������������� 80
Using Escape Characters���������������������������������������������������������������������������������������������������������������������� 81
Performing String Interpolation������������������������������������������������������������������������������������������������������������ 82
Defining Verbatim Strings (Updated 8.0)���������������������������������������������������������������������������������������������� 84
Working with Strings and Equality������������������������������������������������������������������������������������������������������� 85

vii
■ Table of Contents

Strings Are Immutable�������������������������������������������������������������������������������������������������������������������������� 87


Using the System.Text.StringBuilder Type�������������������������������������������������������������������������������������������� 89

Narrowing and Widening Data Type Conversions����������������������������������������������������������� 90


Using the checked Keyword����������������������������������������������������������������������������������������������������������������� 92
Setting Project-wide Overflow Checking (Project File)������������������������������������������������������������������������� 94
Setting Project-wide Overflow Checking (Visual Studio)���������������������������������������������������������������������� 94
Using the unchecked Keyword������������������������������������������������������������������������������������������������������������� 95

Understanding Implicitly Typed Local Variables������������������������������������������������������������� 96


Declaring Numerics Implicitly��������������������������������������������������������������������������������������������������������������� 97
Understanding Restrictions on Implicitly Typed Variables�������������������������������������������������������������������� 98
Implicit Typed Data Is Strongly Typed Data������������������������������������������������������������������������������������������� 99
Understanding the Usefulness of Implicitly Typed Local Variables����������������������������������������������������� 100

Working with C# Iteration Constructs��������������������������������������������������������������������������� 100


Using the for Loop������������������������������������������������������������������������������������������������������������������������������ 101
Using the foreach Loop����������������������������������������������������������������������������������������������������������������������� 101
Using Implicit Typing Within foreach Constructs�������������������������������������������������������������������������������� 102
Using the while and do/while Looping Constructs����������������������������������������������������������������������������� 102

A Quick Discussion About Scope���������������������������������������������������������������������������������� 103


Working with Decision Constructs and the Relational/Equality Operators������������������� 104
Using the if/else Statement���������������������������������������������������������������������������������������������������������������� 104
Using Equality and Relational Operators�������������������������������������������������������������������������������������������� 104
Using if/else with Pattern Matching (New 7.0)����������������������������������������������������������������������������������� 106
Making Pattern Matching Improvements (New 9.0)��������������������������������������������������������������������������� 106
Using the Conditional Operator (Updated 7.2, 9.0)����������������������������������������������������������������������������� 108
Using Logical Operators��������������������������������������������������������������������������������������������������������������������� 109
Using the switch Statement��������������������������������������������������������������������������������������������������������������� 109
Performing switch Statement Pattern Matching (New 7.0, Updated 9.0)������������������������������������������� 112
Using switch Expressions (New 8.0)�������������������������������������������������������������������������������������������������� 115

Summary���������������������������������������������������������������������������������������������������������������������� 117

viii
■ Table of Contents


■Chapter 4: Core C# Programming Constructs, Part 2���������������������������������������� 119
Understanding C# Arrays���������������������������������������������������������������������������������������������� 119
Looking at the C# Array Initialization Syntax�������������������������������������������������������������������������������������� 120
Understanding Implicitly Typed Local Arrays�������������������������������������������������������������������������������������� 121
Defining an Array of Objects��������������������������������������������������������������������������������������������������������������� 122
Working with Multidimensional Arrays����������������������������������������������������������������������������������������������� 122
Using Arrays As Arguments or Return Values������������������������������������������������������������������������������������� 124
Using the System.Array Base Class���������������������������������������������������������������������������������������������������� 125
Using Indices and Ranges (New 8.0, Updated 10.0)��������������������������������������������������������������������������� 126

Understanding Methods����������������������������������������������������������������������������������������������� 128


Understanding Expression-Bodied Members������������������������������������������������������������������������������������� 129
Understanding Local Functions (New 7.0, Updated 9.0)��������������������������������������������������������������������� 129
Understanding Static Local Functions (New 8.0)�������������������������������������������������������������������������������� 131

Understanding Method Parameters����������������������������������������������������������������������������� 131


Understanding Method Parameter Modifiers�������������������������������������������������������������������������������������� 131
Understanding the Default Parameter-Passing Behavior������������������������������������������������������������������� 132
Using the out Modifier (Updated 7.0)�������������������������������������������������������������������������������������������������� 133
Using the ref Modifier������������������������������������������������������������������������������������������������������������������������� 135
Using the in Modifier (New 7.2)���������������������������������������������������������������������������������������������������������� 136
Using the params Modifier����������������������������������������������������������������������������������������������������������������� 137
Defining Optional Parameters������������������������������������������������������������������������������������������������������������� 138
Using Named Arguments (Updated 7.2)���������������������������������������������������������������������������������������������� 139
Understanding Method Overloading��������������������������������������������������������������������������������������������������� 141
Checking Parameters for Null (Updated 10.0)������������������������������������������������������������������������������������ 144

Understanding the enum Type�������������������������������������������������������������������������������������� 144


Controlling the Underlying Storage for an enum�������������������������������������������������������������������������������� 146
Declaring enum Variables������������������������������������������������������������������������������������������������������������������� 146
Using the System.Enum Type������������������������������������������������������������������������������������������������������������� 147
Dynamically Discovering an enum’s Name-Value Pairs��������������������������������������������������������������������� 148
Using Enums, Flags, and Bitwise Operations������������������������������������������������������������������������������������� 149

ix
■ Table of Contents

Understanding the Structure���������������������������������������������������������������������������������������� 151


Creating Structure Variables��������������������������������������������������������������������������������������������������������������� 153
Structure Constructors (Updated 10.0)����������������������������������������������������������������������������������������������� 153
Using Field Initializers (New 10.0)������������������������������������������������������������������������������������������������������ 154
Using Read-Only Structs (New 7.2)���������������������������������������������������������������������������������������������������� 155
Using Read-Only Members (New 8.0)������������������������������������������������������������������������������������������������� 156
Using ref Structs (New 7.2)���������������������������������������������������������������������������������������������������������������� 156
Using Disposable ref Structs (New 8.0)���������������������������������������������������������������������������������������������� 157
Understanding Value Types and Reference Types�������������������������������������������������������� 158
Using Value Types, Reference Types, and the Assignment Operator��������������������������������������������������� 159
Using Value Types Containing Reference Types���������������������������������������������������������������������������������� 160
Passing Reference Types by Value������������������������������������������������������������������������������������������������������ 162
Passing Reference Types by Reference���������������������������������������������������������������������������������������������� 163
Final Details Regarding Value Types and Reference Types����������������������������������������������������������������� 164

Understanding C# Nullable Types��������������������������������������������������������������������������������� 165


Using Nullable Value Types����������������������������������������������������������������������������������������������������������������� 166
Using Nullable Reference Types (New 8.0, Updated 10.0)������������������������������������������������������������������ 167
Operating on Nullable Types��������������������������������������������������������������������������������������������������������������� 171

Understanding Tuples (New/Updated 7.0)�������������������������������������������������������������������� 173


Getting Started with Tuples���������������������������������������������������������������������������������������������������������������� 173
Using Inferred Variable Names (Updated 7.1)������������������������������������������������������������������������������������� 174
Understanding Tuple Equality/Inequality (New 7.3)���������������������������������������������������������������������������� 175
Understanding Tuples as Method Return Values�������������������������������������������������������������������������������� 175
Understanding Discards with Tuples�������������������������������������������������������������������������������������������������� 176
Understanding Tuple Pattern Matching switch Expressions (New 8.0)���������������������������������������������� 176
Deconstructing Tuples (Updated 10.0)������������������������������������������������������������������������������������������������ 177

Summary���������������������������������������������������������������������������������������������������������������������� 179


■Part III: Object Oriented Programming with C#������������������������������ 181

■Chapter 5: Understanding Encapsulation���������������������������������������������������������� 183
Introducing the C# Class Type�������������������������������������������������������������������������������������� 183
Allocating Objects with the new Keyword������������������������������������������������������������������������������������������ 185
x
■ Table of Contents

Understanding Constructors����������������������������������������������������������������������������������������� 186


Understanding the Role of the Default Constructor���������������������������������������������������������������������������� 186
Defining Custom Constructors������������������������������������������������������������������������������������������������������������ 187
Understanding the Default Constructor Revisited������������������������������������������������������������������������������ 188

Understanding the Role of the this Keyword���������������������������������������������������������������� 190


Chaining Constructor Calls Using this������������������������������������������������������������������������������������������������ 191
Observing Constructor Flow��������������������������������������������������������������������������������������������������������������� 193
Revisiting Optional Arguments����������������������������������������������������������������������������������������������������������� 195

Understanding the static Keyword������������������������������������������������������������������������������� 196


Defining Static Field Data������������������������������������������������������������������������������������������������������������������� 197
Defining Static Methods��������������������������������������������������������������������������������������������������������������������� 199
Defining Static Constructors��������������������������������������������������������������������������������������������������������������� 200
Defining Static Classes����������������������������������������������������������������������������������������������������������������������� 202
Importing Static Members via the C# using Keyword������������������������������������������������������������������������ 203

Defining the Pillars of OOP������������������������������������������������������������������������������������������� 204


Understanding the Role of Encapsulation������������������������������������������������������������������������������������������� 204
Understanding the Role of Inheritance����������������������������������������������������������������������������������������������� 205
Understanding the Role of Polymorphism������������������������������������������������������������������������������������������ 206

Understanding C# Access Modifiers (Updated 7.2)������������������������������������������������������ 207


Using the Default Access Modifiers���������������������������������������������������������������������������������������������������� 208
Using Access Modifiers and Nested Types����������������������������������������������������������������������������������������� 209

Understanding the First Pillar: C#’s Encapsulation Services���������������������������������������� 209


Encapsulation Using Traditional Accessors and Mutators������������������������������������������������������������������ 210
Encapsulation Using Properties���������������������������������������������������������������������������������������������������������� 212
Using Properties Within a Class Definition����������������������������������������������������������������������������������������� 216
Read-Only Properties�������������������������������������������������������������������������������������������������������������������������� 217
Write-Only Properties������������������������������������������������������������������������������������������������������������������������� 218
Mixing Private and Public Get/Set Methods on Properties����������������������������������������������������������������� 218
Revisiting the static Keyword: Defining Static Properties������������������������������������������������������������������ 218
Pattern Matching with Property Patterns (New 8.0)��������������������������������������������������������������������������� 219
Extended Property Patterns (New 10.0)��������������������������������������������������������������������������������������������� 221

xi
■ Table of Contents

Understanding Automatic Properties���������������������������������������������������������������������������� 222


Interacting with Automatic Properties������������������������������������������������������������������������������������������������ 223
Automatic Properties and Default Values������������������������������������������������������������������������������������������� 224
Initializing Automatic Properties��������������������������������������������������������������������������������������������������������� 225

Understanding Object Initialization������������������������������������������������������������������������������ 226


Looking at the Object Initialization Syntax����������������������������������������������������������������������������������������� 226
Using init-Only Setters (New 9.0)������������������������������������������������������������������������������������������������������� 227
Calling Custom Constructors with Initialization Syntax���������������������������������������������������������������������� 228
Initializing Data with Initialization Syntax������������������������������������������������������������������������������������������� 230

Working with Constant and Read-Only Field Data������������������������������������������������������� 231


Understanding Constant Field Data���������������������������������������������������������������������������������������������������� 231
Understanding Read-Only Fields�������������������������������������������������������������������������������������������������������� 232
Understanding Static Read-Only Fields���������������������������������������������������������������������������������������������� 233

Understanding Partial Classes������������������������������������������������������������������������������������� 234


Records (New 9.0)�������������������������������������������������������������������������������������������������������� 235
Immutable Record Types with Standard Property Syntax������������������������������������������������������������������� 237
Immutable Record Types with Positional Syntax�������������������������������������������������������������������������������� 238
Mutable Record Types������������������������������������������������������������������������������������������������������������������������ 239
Value Equality with Record Types������������������������������������������������������������������������������������������������������� 239
Copying Record Types Using with Expressions���������������������������������������������������������������������������������� 240

Record Structs (New 10.0)������������������������������������������������������������������������������������������� 241


Mutable Record Structs���������������������������������������������������������������������������������������������������������������������� 241
Immutable Record Structs������������������������������������������������������������������������������������������������������������������ 242
Deconstructing Record Structs����������������������������������������������������������������������������������������������������������� 243

Summary���������������������������������������������������������������������������������������������������������������������� 243

■Chapter 6: Understanding Inheritance and Polymorphism�������������������������������� 245
Understanding the Basic Mechanics of Inheritance����������������������������������������������������� 245
Specifying the Parent Class of an Existing Class�������������������������������������������������������������������������������� 246
Regarding Multiple Base Classes������������������������������������������������������������������������������������������������������� 248
Using the sealed Keyword������������������������������������������������������������������������������������������������������������������ 248

xii
■ Table of Contents

Revisiting Visual Studio Class Diagrams���������������������������������������������������������������������� 249


Understanding the Second Pillar of OOP: The Details of Inheritance��������������������������� 251
Calling Base Class Constructors with the base Keyword������������������������������������������������������������������� 252
Keeping Family Secrets: The protected Keyword������������������������������������������������������������������������������� 254
Adding a sealed Class������������������������������������������������������������������������������������������������������������������������ 255
Understanding Inheritance with Record Types (New 9.0)������������������������������������������������������������������� 256

Programming for Containment/Delegation������������������������������������������������������������������� 260


Understanding Nested Type Definitions���������������������������������������������������������������������������������������������� 261

Understanding the Third Pillar of OOP: C#’s Polymorphic Support������������������������������� 263


Using the virtual and override Keywords�������������������������������������������������������������������������������������������� 264
Overriding Virtual Members with Visual Studio/Visual Studio Code��������������������������������������������������� 267
Sealing Virtual Members (Updated 10.0)�������������������������������������������������������������������������������������������� 267
Understanding Abstract Classes��������������������������������������������������������������������������������������������������������� 268
Understanding the Polymorphic Interface������������������������������������������������������������������������������������������ 270
Understanding Member Shadowing��������������������������������������������������������������������������������������������������� 274

Understanding Base Class/Derived Class Casting Rules���������������������������������������������� 275


Using the C# as Keyword�������������������������������������������������������������������������������������������������������������������� 277
Using the C# is Keyword (Updated 7.0, 9.0)��������������������������������������������������������������������������������������� 279
Revisiting Pattern Matching (New 7.0)����������������������������������������������������������������������������������������������� 281

Understanding the Super Parent Class: System.Object������������������������������������������������ 282


Overriding System.Object.ToString( )�������������������������������������������������������������������������������������������������� 285
Overriding System.Object.Equals( )���������������������������������������������������������������������������������������������������� 285
Overriding System.Object.GetHashCode()������������������������������������������������������������������������������������������ 286
Testing Your Modified Person Class���������������������������������������������������������������������������������������������������� 287
Using the Static Members of System.Object�������������������������������������������������������������������������������������� 288

Summary���������������������������������������������������������������������������������������������������������������������� 288

■Chapter 7: Understanding Structured Exception Handling�������������������������������� 289
Ode to Errors, Bugs, and Exceptions���������������������������������������������������������������������������� 289
The Role of .NET Exception Handling��������������������������������������������������������������������������� 290
The Building Blocks of .NET Exception Handling�������������������������������������������������������������������������������� 291
The System.Exception Base Class������������������������������������������������������������������������������������������������������ 291
xiii
■ Table of Contents

The Simplest Possible Example����������������������������������������������������������������������������������� 292


Throwing a General Exception������������������������������������������������������������������������������������������������������������ 295
Catching Exceptions��������������������������������������������������������������������������������������������������������������������������� 296
Throw As Expression (New 7.0)���������������������������������������������������������������������������������������������������������� 297

Configuring the State of an Exception�������������������������������������������������������������������������� 298


The TargetSite Property���������������������������������������������������������������������������������������������������������������������� 298
The StackTrace Property��������������������������������������������������������������������������������������������������������������������� 299
The HelpLink Property������������������������������������������������������������������������������������������������������������������������ 299
The Data Property������������������������������������������������������������������������������������������������������������������������������� 300

System-Level Exceptions (System.SystemException)�������������������������������������������������� 302


Application-Level Exceptions (System.ApplicationException)�������������������������������������� 302
Building Custom Exceptions, Take 1��������������������������������������������������������������������������������������������������� 303
Building Custom Exceptions, Take 2��������������������������������������������������������������������������������������������������� 305
Building Custom Exceptions, Take 3��������������������������������������������������������������������������������������������������� 305

Processing Multiple Exceptions����������������������������������������������������������������������������������� 306


General catch Statements������������������������������������������������������������������������������������������������������������������ 309
Rethrowing Exceptions����������������������������������������������������������������������������������������������������������������������� 309
Inner Exceptions��������������������������������������������������������������������������������������������������������������������������������� 310
The finally Block��������������������������������������������������������������������������������������������������������������������������������� 311
Exception Filters��������������������������������������������������������������������������������������������������������������������������������� 312

Debugging Unhandled Exceptions Using Visual Studio������������������������������������������������ 312


Summary���������������������������������������������������������������������������������������������������������������������� 314

■Chapter 8: Working with Interfaces������������������������������������������������������������������� 315
Understanding Interface Types������������������������������������������������������������������������������������� 315
Interface Types vs. Abstract Base Classes����������������������������������������������������������������������������������������� 316

Defining Custom Interfaces������������������������������������������������������������������������������������������ 319


Implementing an Interface������������������������������������������������������������������������������������������� 320
Invoking Interface Members at the Object Level���������������������������������������������������������� 322
Obtaining Interface References: The as Keyword������������������������������������������������������������������������������� 323
Obtaining Interface References: The is Keyword (Updated 7.0)��������������������������������������������������������� 324

xiv
■ Table of Contents

Default Implementations (New 8.0)������������������������������������������������������������������������������ 324


Static Constructors and Members (New 8.0)��������������������������������������������������������������� 325
Interfaces as Parameters��������������������������������������������������������������������������������������������� 326
Interfaces as Return Values������������������������������������������������������������������������������������������ 328
Arrays of Interface Types���������������������������������������������������������������������������������������������� 328
Implementing Interfaces Using Visual Studio or Visual Studio Code���������������������������� 330
Explicit Interface Implementation�������������������������������������������������������������������������������� 331
Designing Interface Hierarchies����������������������������������������������������������������������������������� 334
Interface Hierarchies with Default Implementations (New 8.0)���������������������������������������������������������� 335
Multiple Inheritance with Interface Types������������������������������������������������������������������������������������������� 337

The IEnumerable and IEnumerator Interfaces�������������������������������������������������������������� 339


Building Iterator Methods with the yield Keyword������������������������������������������������������������������������������ 342
Building a Named Iterator������������������������������������������������������������������������������������������������������������������� 344

The ICloneable Interface���������������������������������������������������������������������������������������������� 345


A More Elaborate Cloning Example���������������������������������������������������������������������������������������������������� 347

The IComparable Interface������������������������������������������������������������������������������������������� 350


Specifying Multiple Sort Orders with IComparer�������������������������������������������������������������������������������� 353
Custom Properties and Custom Sort Types���������������������������������������������������������������������������������������� 354

Summary���������������������������������������������������������������������������������������������������������������������� 355

■Chapter 9: Understanding Object Lifetime��������������������������������������������������������� 357
Classes, Objects, and References�������������������������������������������������������������������������������� 357
The Basics of Object Lifetime��������������������������������������������������������������������������������������� 359
The CIL of new������������������������������������������������������������������������������������������������������������������������������������ 359
Setting Object References to null������������������������������������������������������������������������������������������������������� 361

Determining If an Object Is Live����������������������������������������������������������������������������������� 361


Understanding Object Generations������������������������������������������������������������������������������� 363
Ephemeral Generations and Segments���������������������������������������������������������������������������������������������� 365

Garbage Collection Types��������������������������������������������������������������������������������������������� 365


Background Garbage Collection��������������������������������������������������������������������������������������������������������� 365

xv
■ Table of Contents

The System.GC Type����������������������������������������������������������������������������������������������������� 366


Forcing a Garbage Collection�������������������������������������������������������������������������������������������������������������� 367

Building Finalizable Objects����������������������������������������������������������������������������������������� 370


Overriding System.Object.Finalize()���������������������������������������������������������������������������������������������������� 371
Detailing the Finalization Process������������������������������������������������������������������������������������������������������ 373

Building Disposable Objects����������������������������������������������������������������������������������������� 373


Reusing the C# using Keyword����������������������������������������������������������������������������������������������������������� 375
Using Declarations (New 8.0)������������������������������������������������������������������������������������������������������������� 377
Building Finalizable and Disposable Types������������������������������������������������������������������� 378
A Formalized Disposal Pattern����������������������������������������������������������������������������������������������������������� 378

Understanding Lazy Object Instantiation���������������������������������������������������������������������� 380


Customizing the Creation of the Lazy Data����������������������������������������������������������������������������������������� 383

Summary���������������������������������������������������������������������������������������������������������������������� 384


■Part IV: Advanced C# Programming����������������������������������������������� 385

■Chapter 10: Collections and Generics���������������������������������������������������������������� 387
The Motivation for Collection Classes�������������������������������������������������������������������������� 387
The System.Collections Namespace�������������������������������������������������������������������������������������������������� 389
A Survey of System.Collections.Specialized Namespace������������������������������������������������������������������� 390

The Problems of Nongeneric Collections��������������������������������������������������������������������� 391


The Issue of Performance������������������������������������������������������������������������������������������������������������������� 392
The Issue of Type Safety��������������������������������������������������������������������������������������������������������������������� 395
A First Look at Generic CollectionsT��������������������������������������������������������������������������������������������������� 398

The Role of Generic Type Parameters�������������������������������������������������������������������������� 399


Specifying Type Parameters for Generic Classes/Structures������������������������������������������������������������� 400
Specifying Type Parameters for Generic Members����������������������������������������������������������������������������� 402
Specifying Type Parameters for Generic Interfaces���������������������������������������������������������������������������� 402

The System.Collections.Generic Namespace��������������������������������������������������������������� 403


Understanding Collection Initialization Syntax����������������������������������������������������������������������������������� 405
Working with the List<T> Class��������������������������������������������������������������������������������������������������������� 406
Working with the Stack<T> Class������������������������������������������������������������������������������������������������������ 408

xvi
■ Table of Contents

Working with the Queue<T> Class����������������������������������������������������������������������������������������������������� 409


Working with the PriorityQueue<TElement, TPriority> Class (New 10)���������������������������������������������� 410
Working with the SortedSet<T> Class����������������������������������������������������������������������������������������������� 411
Working with the Dictionary<TKey, TValue> Class����������������������������������������������������������������������������� 413

The System.Collections.ObjectModel Namespace������������������������������������������������������� 414


Working with ObservableCollection<T>��������������������������������������������������������������������������������������������� 414

Creating Custom Generic Methods������������������������������������������������������������������������������� 416


Inference of Type Parameters������������������������������������������������������������������������������������������������������������� 418

Creating Custom Generic Structures and Classes�������������������������������������������������������� 419


Default Value Expressions with Generics������������������������������������������������������������������������������������������� 420
Default Literal Expressions (New 7.1)������������������������������������������������������������������������������������������������� 422
Pattern Matching with Generics (New 7.1)����������������������������������������������������������������������������������������� 422

Constraining Type Parameters�������������������������������������������������������������������������������������� 423


Examples of Using the where Keyword���������������������������������������������������������������������������������������������� 423
The Lack of Operator Constraints������������������������������������������������������������������������������������������������������� 425

Summary���������������������������������������������������������������������������������������������������������������������� 426

■Chapter 11: Advanced C# Language Features��������������������������������������������������� 427
Understanding Indexer Methods���������������������������������������������������������������������������������� 427
Indexing Data Using String Values������������������������������������������������������������������������������������������������������ 429
Overloading Indexer Methods������������������������������������������������������������������������������������������������������������� 430
Indexers with Multiple Dimensions���������������������������������������������������������������������������������������������������� 431
Indexer Definitions on Interface Types������������������������������������������������������������������������������������������������ 432
Understanding Operator Overloading��������������������������������������������������������������������������� 432
Overloading Binary Operators������������������������������������������������������������������������������������������������������������� 433
What of the += and –= Operators?���������������������������������������������������������������������������������������������������� 435
Overloading Unary Operators������������������������������������������������������������������������������������������������������������� 436
Overloading Equality Operators���������������������������������������������������������������������������������������������������������� 437
Overloading Comparison Operators���������������������������������������������������������������������������������������������������� 437
Final Thoughts Regarding Operator Overloading�������������������������������������������������������������������������������� 438

xvii
■ Table of Contents

Understanding Custom Type Conversions�������������������������������������������������������������������� 439


Recall: Numerical Conversions����������������������������������������������������������������������������������������������������������� 439
Recall: Conversions Among Related Class Types�������������������������������������������������������������������������������� 439
Creating Custom Conversion Routines����������������������������������������������������������������������������������������������� 440
Additional Explicit Conversions for the Square Type�������������������������������������������������������������������������� 443
Defining Implicit Conversion Routines������������������������������������������������������������������������������������������������ 443

Understanding Extension Methods������������������������������������������������������������������������������� 444


Defining Extension Methods��������������������������������������������������������������������������������������������������������������� 445
Invoking Extension Methods��������������������������������������������������������������������������������������������������������������� 446
Importing Extension Methods������������������������������������������������������������������������������������������������������������� 447
Extending Types Implementing Specific Interfaces���������������������������������������������������������������������������� 447
Extension Method GetEnumerator Support (New 9.0)������������������������������������������������������������������������ 449

Understanding Anonymous Types�������������������������������������������������������������������������������� 450


Defining an Anonymous Type�������������������������������������������������������������������������������������������������������������� 451
The Internal Representation of Anonymous Types������������������������������������������������������������������������������ 452
The Implementation of ToString() and GetHashCode()������������������������������������������������������������������������ 453
The Semantics of Equality for Anonymous Types������������������������������������������������������������������������������� 454
Anonymous Types Containing Anonymous Types������������������������������������������������������������������������������� 456

Working with Pointer Types������������������������������������������������������������������������������������������ 456


The unsafe Keyword��������������������������������������������������������������������������������������������������������������������������� 459
Working with the * and & Operators��������������������������������������������������������������������������������������������������� 461
An Unsafe (and Safe) Swap Function������������������������������������������������������������������������������������������������� 462
Field Access via Pointers (the -> Operator)���������������������������������������������������������������������������������������� 463
The stackalloc Keyword���������������������������������������������������������������������������������������������������������������������� 463
Pinning a Type via the fixed Keyword������������������������������������������������������������������������������������������������� 464
The sizeof Keyword���������������������������������������������������������������������������������������������������������������������������� 465

Summary���������������������������������������������������������������������������������������������������������������������� 465

■Chapter 12: Delegates, Events, and Lambda Expressions��������������������������������� 467
Understanding the Delegate Type��������������������������������������������������������������������������������� 468
Defining a Delegate Type in C#����������������������������������������������������������������������������������������������������������� 468
The System.MulticastDelegate and System.Delegate Base Classes�������������������������������������������������� 470

xviii
■ Table of Contents

The Simplest Possible Delegate Example�������������������������������������������������������������������� 472


Investigating a Delegate Object���������������������������������������������������������������������������������������������������������� 474

Sending Object State Notifications Using Delegates���������������������������������������������������� 475


Enabling Multicasting������������������������������������������������������������������������������������������������������������������������� 478
Removing Targets from a Delegate’s Invocation List�������������������������������������������������������������������������� 480
Method Group Conversion Syntax������������������������������������������������������������������������������������������������������ 481

Understanding Generic Delegates�������������������������������������������������������������������������������� 482


The Generic Action<> and Func<> Delegates����������������������������������������������������������������������������������� 483

Understanding C# Events��������������������������������������������������������������������������������������������� 485


The C# event Keyword������������������������������������������������������������������������������������������������������������������������ 486
Events Under the Hood����������������������������������������������������������������������������������������������������������������������� 488
Listening to Incoming Events������������������������������������������������������������������������������������������������������������� 489
Simplifying Event Registration Using Visual Studio���������������������������������������������������������������������������� 490
Creating Custom Event Arguments����������������������������������������������������������������������������������������������������� 491
The Generic EventHandler<T> Delegate�������������������������������������������������������������������������������������������� 493

Understanding C# Anonymous Methods���������������������������������������������������������������������� 494


Accessing Local Variables������������������������������������������������������������������������������������������������������������������ 495
Using static with Anonymous Methods (New 9.0)������������������������������������������������������������������������������ 496
Discards with Anonymous Methods (New 9.0)����������������������������������������������������������������������������������� 497

Understanding Lambda Expressions���������������������������������������������������������������������������� 498


Dissecting a Lambda Expression�������������������������������������������������������������������������������������������������������� 500
Processing Arguments Within Multiple Statements���������������������������������������������������������������������������� 501
Lambda Expressions with Multiple (or Zero) Parameters������������������������������������������������������������������� 502
Using static with Lambda Expressions (New 9.0)������������������������������������������������������������������������������ 504
Discards with Lambda Expressions (New 9.0)����������������������������������������������������������������������������������� 504
Retrofitting the CarEvents Example Using Lambda Expressions�������������������������������������������������������� 505
Lambdas and Expression-Bodied Members (Updated 7.0)����������������������������������������������������������������� 505

Summary���������������������������������������������������������������������������������������������������������������������� 506

xix
■ Table of Contents


■Chapter 13: LINQ to Objects������������������������������������������������������������������������������� 509
LINQ-Specific Programming Constructs����������������������������������������������������������������������� 509
Implicit Typing of Local Variables������������������������������������������������������������������������������������������������������� 510
Object and Collection Initialization Syntax����������������������������������������������������������������������������������������� 511
Lambda Expressions��������������������������������������������������������������������������������������������������������������������������� 511
Extension Methods����������������������������������������������������������������������������������������������������������������������������� 512
Anonymous Types������������������������������������������������������������������������������������������������������������������������������� 513
Understanding the Role of LINQ����������������������������������������������������������������������������������� 513
LINQ Expressions Are Strongly Typed������������������������������������������������������������������������������������������������� 514
The Core LINQ Assemblies������������������������������������������������������������������������������������������������������������������ 514

Applying LINQ Queries to Primitive Arrays������������������������������������������������������������������� 514


Once Again, Using Extension Methods����������������������������������������������������������������������������������������������� 516
Once Again, Without LINQ������������������������������������������������������������������������������������������������������������������� 517
Reflecting Over a LINQ Result Set������������������������������������������������������������������������������������������������������ 517
LINQ and Implicitly Typed Local Variables������������������������������������������������������������������������������������������ 519
LINQ and Extension Methods�������������������������������������������������������������������������������������������������������������� 520
The Role of Deferred Execution���������������������������������������������������������������������������������������������������������� 521
The Role of Immediate Execution������������������������������������������������������������������������������������������������������� 523

Returning the Result of a LINQ Query��������������������������������������������������������������������������� 525


Returning LINQ Results via Immediate Execution������������������������������������������������������������������������������ 526

Applying LINQ Queries to Collection Objects���������������������������������������������������������������� 527


Accessing Contained Subobjects������������������������������������������������������������������������������������������������������� 528
Applying LINQ Queries to Nongeneric Collections������������������������������������������������������������������������������ 528
Filtering Data Using OfType<T>()������������������������������������������������������������������������������������������������������� 529

Investigating the C# LINQ Query Operators������������������������������������������������������������������ 530


Basic Selection Syntax����������������������������������������������������������������������������������������������������������������������� 531
Obtaining Subsets of Data������������������������������������������������������������������������������������������������������������������ 532
Paging Data���������������������������������������������������������������������������������������������������������������������������������������� 533
Paging Data with Ranges (New 10.0)������������������������������������������������������������������������������������������������� 534
Paging Data with Chunks (New 10.0)������������������������������������������������������������������������������������������������� 535
Projecting New Data Types����������������������������������������������������������������������������������������������������������������� 535

xx
■ Table of Contents

Projecting to Different Data Types������������������������������������������������������������������������������������������������������ 537


Obtaining Counts Using Enumerable�������������������������������������������������������������������������������������������������� 537
Obtaining Nonenumerated Counts (New 10.0)����������������������������������������������������������������������������������� 538
Reversing Result Sets������������������������������������������������������������������������������������������������������������������������� 539
Sorting Expressions���������������������������������������������������������������������������������������������������������������������������� 539
LINQ As a Better Venn Diagramming Tool������������������������������������������������������������������������������������������� 539
Removing Duplicates�������������������������������������������������������������������������������������������������������������������������� 543
LINQ Aggregation Operations�������������������������������������������������������������������������������������������������������������� 544

The Internal Representation of LINQ Query Statements����������������������������������������������� 544


Building Query Expressions with Query Operators (Revisited)����������������������������������������������������������� 545
Building Query Expressions Using the Enumerable Type and Lambda Expressions��������������������������� 546
Building Query Expressions Using the Enumerable Type and Anonymous Methods�������������������������� 547
Building Query Expressions Using the Enumerable Type and Raw Delegates������������������������������������ 548

Summary���������������������������������������������������������������������������������������������������������������������� 549

■Chapter 14: Processes, AppDomains, and Load Contexts��������������������������������� 551
The Role of a Windows Process����������������������������������������������������������������������������������� 551
The Role of Threads���������������������������������������������������������������������������������������������������������������������������� 552

Interacting with Processes Using .NET Core���������������������������������������������������������������� 553


Enumerating Running Processes�������������������������������������������������������������������������������������������������������� 555
Investigating a Specific Process��������������������������������������������������������������������������������������������������������� 556
Investigating a Process’s Thread Set�������������������������������������������������������������������������������������������������� 557
Investigating a Process’s Module Set������������������������������������������������������������������������������������������������� 558
Starting and Stopping Processes Programmatically�������������������������������������������������������������������������� 560
Controlling Process Startup Using the ProcessStartInfo Class����������������������������������������������������������� 561
Leveraging OS Verbs with ProcessStartInfo��������������������������������������������������������������������������������������� 562

Understanding .NET Application Domains�������������������������������������������������������������������� 563


The System.AppDomain Class������������������������������������������������������������������������������������������������������������ 564
Interacting with the Default Application Domain�������������������������������������������������������������������������������� 564
Enumerating Loaded Assemblies������������������������������������������������������������������������������������������������������� 565

Assembly Isolation with Application Load Contexts����������������������������������������������������� 566

xxi
■ Table of Contents

Summarizing Processes, AppDomains, and Load Contexts������������������������������������������ 569


Summary���������������������������������������������������������������������������������������������������������������������� 570

■Chapter 15: Multithreaded, Parallel, and Async Programming������������������������� 571
The Process/AppDomain/Context/Thread Relationship������������������������������������������������ 571
The Problem of Concurrency�������������������������������������������������������������������������������������������������������������� 572
The Role of Thread Synchronization��������������������������������������������������������������������������������������������������� 573

The System.Threading Namespace������������������������������������������������������������������������������ 573


The System.Threading.Thread Class���������������������������������������������������������������������������� 574
Obtaining Statistics About the Current Thread of Execution��������������������������������������������������������������� 575
The Name Property����������������������������������������������������������������������������������������������������������������������������� 576
The Priority Property��������������������������������������������������������������������������������������������������������������������������� 576

Manually Creating Secondary Threads������������������������������������������������������������������������� 577


Working with the ThreadStart Delegate���������������������������������������������������������������������������������������������� 577
Working with the ParameterizedThreadStart Delegate���������������������������������������������������������������������� 579
The AutoResetEvent Class������������������������������������������������������������������������������������������������������������������ 580
Foreground Threads and Background Threads����������������������������������������������������������������������������������� 581

The Issue of Concurrency��������������������������������������������������������������������������������������������� 582


Synchronization Using the C# lock Keyword�������������������������������������������������������������������������������������� 584
Synchronization Using the System.Threading.Monitor Type��������������������������������������������������������������� 586
Synchronization Using the System.Threading.Interlocked Type��������������������������������������������������������� 587

Programming with Timer Callbacks����������������������������������������������������������������������������� 588


Using a Stand-Alone Discard (New 7.0)���������������������������������������������������������������������������������������������� 589

Understanding the ThreadPool������������������������������������������������������������������������������������� 590


Parallel Programming Using the Task Parallel Library������������������������������������������������� 591
The System.Threading.Tasks Namespace������������������������������������������������������������������������������������������ 591
The Role of the Parallel Class������������������������������������������������������������������������������������������������������������� 591
Data Parallelism with the Parallel Class��������������������������������������������������������������������������������������������� 592
Accessing UI Elements on Secondary Threads����������������������������������������������������������������������������������� 596
The Task Class������������������������������������������������������������������������������������������������������������������������������������ 597
Handling Cancellation Request����������������������������������������������������������������������������������������������������������� 597
Task Parallelism Using the Parallel Class������������������������������������������������������������������������������������������� 599
xxii
■ Table of Contents

Parallel LINQ Queries (PLINQ)��������������������������������������������������������������������������������������� 602


Opting in to a PLINQ Query����������������������������������������������������������������������������������������������������������������� 603
Cancelling a PLINQ Query������������������������������������������������������������������������������������������������������������������� 603

Async Calls Using the async/await Pattern������������������������������������������������������������������ 605


A First Look at the C# async and await Keywords (Updated 7.1, 9.0)������������������������������������������������ 605
SynchronizationContext and async/await������������������������������������������������������������������������������������������� 607
The Role of ConfigureAwait���������������������������������������������������������������������������������������������������������������� 607
Naming Conventions for Asynchronous Methods������������������������������������������������������������������������������� 608
Async Methods That Don’t Return Data���������������������������������������������������������������������������������������������� 608
Async Methods with Multiple Awaits�������������������������������������������������������������������������������������������������� 611
Calling Async Methods from Synchronous Methods�������������������������������������������������������������������������� 613
Await in catch and finally Blocks�������������������������������������������������������������������������������������������������������� 614
Generalized Async Return Types (New 7.0)���������������������������������������������������������������������������������������� 615
Local Functions with async/await (New 7.0)�������������������������������������������������������������������������������������� 615
Cancelling async/await Operations���������������������������������������������������������������������������������������������������� 616
Asynchronous Streams (New 8.0)������������������������������������������������������������������������������������������������������ 619
The Parallel.ForEachAsync() Method (New 10.0)�������������������������������������������������������������������������������� 620
Update the Book Reader App with async/await���������������������������������������������������������������������������������� 621
Wrapping Up async and await������������������������������������������������������������������������������������������������������������ 622

Summary���������������������������������������������������������������������������������������������������������������������� 622


■Part V: Programming with .NET Core Assemblies�������������������������� 623

■Chapter 16: Building and Configuring Class Libraries��������������������������������������� 625
Defining Custom Namespaces (Updated 10.0)������������������������������������������������������������� 625
Resolving Name Clashes with Fully Qualified Names������������������������������������������������������������������������ 627
Resolving Name Clashes with Aliases������������������������������������������������������������������������������������������������ 628
Creating Nested Namespaces������������������������������������������������������������������������������������������������������������ 629
Change the Root Namespace Using Visual Studio 2022��������������������������������������������������������������������� 630
Change the Root Namespace Using the Project File�������������������������������������������������������������������������� 630

The Role of .NET Assemblies���������������������������������������������������������������������������������������� 631


Assemblies Promote Code Reuse������������������������������������������������������������������������������������������������������� 631
Assemblies Establish a Type Boundary���������������������������������������������������������������������������������������������� 632

xxiii
■ Table of Contents

Assemblies Are Versionable Units������������������������������������������������������������������������������������������������������ 632


Assemblies Are Self-Describing��������������������������������������������������������������������������������������������������������� 632

Understanding the Format of a .NET Assembly������������������������������������������������������������ 632


Installing the C++ Profiling Tools������������������������������������������������������������������������������������������������������� 633
The Operating System (Windows) File Header����������������������������������������������������������������������������������� 633
The CLR File Header��������������������������������������������������������������������������������������������������������������������������� 634
CIL Code, Type Metadata, and the Assembly Manifest������������������������������������������������������������������������ 635
Optional Assembly Resources������������������������������������������������������������������������������������������������������������ 635

Class Libraries vs. Console Applications���������������������������������������������������������������������� 636


.NET Standard vs. .NET (Core) Class Libraries�������������������������������������������������������������� 636
Configuring Applications with Configuration Files������������������������������������������������������� 637
Multiple Configuration Files���������������������������������������������������������������������������������������������������������������� 639
Working with Objects (Updated 10.0)������������������������������������������������������������������������������������������������� 639
Additional Configuration Options�������������������������������������������������������������������������������������������������������� 642

Building and Consuming a .NET Class Library������������������������������������������������������������� 643


Exploring the Manifest������������������������������������������������������������������������������������������������������������������������ 645
Exploring the CIL��������������������������������������������������������������������������������������������������������������������������������� 647
Exploring the Type Metadata�������������������������������������������������������������������������������������������������������������� 648
Building a C# Client Application���������������������������������������������������������������������������������������������������������� 648
Building a Visual Basic Client Application������������������������������������������������������������������������������������������� 650
Cross-Language Inheritance in Action������������������������������������������������������������������������������������������������ 651
Exposing internal Types to Other Assemblies������������������������������������������������������������������������������������� 652

NuGet and .NET Core���������������������������������������������������������������������������������������������������� 653


Packaging Assemblies with NuGet����������������������������������������������������������������������������������������������������� 653
Referencing NuGet Packages������������������������������������������������������������������������������������������������������������� 654

Publishing Console Applications (Updated .NET 5/6)��������������������������������������������������� 655


Publishing Framework-Dependent Applications��������������������������������������������������������������������������������� 656
Publishing Self-Contained Applications���������������������������������������������������������������������������������������������� 656

How .NET Locates Assemblies������������������������������������������������������������������������������������� 658


Summary���������������������������������������������������������������������������������������������������������������������� 660

xxiv
■ Table of Contents


■Chapter 17: Type Reflection, Late Binding, Attribute, and Dynamic Types�������� 661
The Necessity of Type Metadata����������������������������������������������������������������������������������� 661
Viewing (Partial) Metadata for the EngineStateEnum Enumeration��������������������������������������������������� 662
Viewing (Partial) Metadata for the Car Type��������������������������������������������������������������������������������������� 663
Examining a TypeRef�������������������������������������������������������������������������������������������������������������������������� 665
Documenting the Defining Assembly�������������������������������������������������������������������������������������������������� 665
Documenting Referenced Assemblies������������������������������������������������������������������������������������������������ 665
Documenting String Literals��������������������������������������������������������������������������������������������������������������� 666
Understanding Reflection��������������������������������������������������������������������������������������������� 667
The System.Type Class����������������������������������������������������������������������������������������������������������������������� 667
Obtaining a Type Reference Using System.Object.GetType()�������������������������������������������������������������� 668
Obtaining a Type Reference Using typeof()����������������������������������������������������������������������������������������� 669
Obtaining a Type Reference Using System.Type.GetType()����������������������������������������������������������������� 669

Building a Custom Metadata Viewer���������������������������������������������������������������������������� 670


Reflecting on Methods������������������������������������������������������������������������������������������������������������������������ 670
Reflecting on Fields and Properties���������������������������������������������������������������������������������������������������� 671
Reflecting on Implemented Interfaces����������������������������������������������������������������������������������������������� 671
Displaying Various Odds and Ends����������������������������������������������������������������������������������������������������� 672
Adding the Top-Level Statements������������������������������������������������������������������������������������������������������� 672
Reflecting on Static Types������������������������������������������������������������������������������������������������������������������ 674
Reflecting on Generic Types��������������������������������������������������������������������������������������������������������������� 674
Reflecting on Method Parameters and Return Values������������������������������������������������������������������������ 674

Dynamically Loading Assemblies��������������������������������������������������������������������������������� 676


Reflecting on Framework Assemblies�������������������������������������������������������������������������� 677
Understanding Late Binding����������������������������������������������������������������������������������������� 679
The System.Activator Class���������������������������������������������������������������������������������������������������������������� 679
Invoking Methods with No Parameters����������������������������������������������������������������������������������������������� 681
Invoking Methods with Parameters���������������������������������������������������������������������������������������������������� 681

Understanding the Role of .NET Attributes������������������������������������������������������������������� 682


Attribute Consumers��������������������������������������������������������������������������������������������������������������������������� 683
Applying Attributes in C#�������������������������������������������������������������������������������������������������������������������� 683

xxv
■ Table of Contents

C# Attribute Shorthand Notation��������������������������������������������������������������������������������������������������������� 684


Specifying Constructor Parameters for Attributes������������������������������������������������������������������������������ 685
The Obsolete Attribute in Action��������������������������������������������������������������������������������������������������������� 685

Building Custom Attributes������������������������������������������������������������������������������������������� 687


Applying Custom Attributes���������������������������������������������������������������������������������������������������������������� 687
Named Property Syntax���������������������������������������������������������������������������������������������������������������������� 688
Restricting Attribute Usage����������������������������������������������������������������������������������������������������������������� 688

Assembly-Level Attributes������������������������������������������������������������������������������������������� 689


Using a Separate File for Assembly Attributes����������������������������������������������������������������������������������� 690

Using the Project File for Assembly Attributes������������������������������������������������������������� 690


Reflecting on Attributes Using Early Binding���������������������������������������������������������������� 691
Reflecting on Attributes Using Late Binding����������������������������������������������������������������� 692
Putting Reflection, Late Binding, and Custom Attributes in Perspective���������������������� 694
Building an Extendable Application������������������������������������������������������������������������������ 694
Building the Multiproject ExtendableApp Solution����������������������������������������������������������������������������� 695
Building CommonSnappableTypes.dll������������������������������������������������������������������������������������������������ 699
Building the C# Snap-In���������������������������������������������������������������������������������������������������������������������� 699
Building the Visual Basic Snap-In������������������������������������������������������������������������������������������������������� 700
Adding the Code for the ExtendableApp��������������������������������������������������������������������������������������������� 700

The Role of the C# dynamic Keyword��������������������������������������������������������������������������� 702


Calling Members on Dynamically Declared Data�������������������������������������������������������������������������������� 704
The Scope of the dynamic Keyword��������������������������������������������������������������������������������������������������� 706
Limitations of the dynamic Keyword�������������������������������������������������������������������������������������������������� 706
Practical Uses of the dynamic Keyword��������������������������������������������������������������������������������������������� 707

The Role of the Dynamic Language Runtime��������������������������������������������������������������� 707


The Role of Expression Trees�������������������������������������������������������������������������������������������������������������� 708
Dynamic Runtime Lookup of Expression Trees����������������������������������������������������������������������������������� 708

Simplifying Late-Bound Calls Using Dynamic Types���������������������������������������������������� 709


Leveraging the dynamic Keyword to Pass Arguments����������������������������������������������������������������������� 710

Summary���������������������������������������������������������������������������������������������������������������������� 712

xxvi
■ Table of Contents


■Chapter 18: Understanding CIL and the Role of Dynamic Assemblies��������������� 713
Motivations for Learning the Grammar of CIL�������������������������������������������������������������� 713
Examining CIL Directives, Attributes, and Opcodes������������������������������������������������������ 715
The Role of CIL Directives������������������������������������������������������������������������������������������������������������������� 715
The Role of CIL Attributes������������������������������������������������������������������������������������������������������������������� 715
The Role of CIL Opcodes��������������������������������������������������������������������������������������������������������������������� 716
The CIL Opcode/CIL Mnemonic Distinction����������������������������������������������������������������������������������������� 716
Pushing and Popping: The Stack-Based Nature of CIL������������������������������������������������� 717
Understanding Round-Trip Engineering����������������������������������������������������������������������� 718
The Role of CIL Code Labels��������������������������������������������������������������������������������������������������������������� 721
Interacting with CIL: Modifying an *.il File������������������������������������������������������������������������������������������ 721
Compiling CIL Code with ILASM.EXE�������������������������������������������������������������������������������������������������� 722
Compiling CIL Code with Microsoft.NET.Sdk.il Projects���������������������������������������������������������������������� 722

Understanding CIL Directives and Attributes���������������������������������������������������������������� 724


Specifying Externally Referenced Assemblies in CIL�������������������������������������������������������������������������� 724
Defining the Current Assembly in CIL������������������������������������������������������������������������������������������������� 725
Defining Namespaces in CIL��������������������������������������������������������������������������������������������������������������� 726
Defining Class Types in CIL����������������������������������������������������������������������������������������������������������������� 726
Defining and Implementing Interfaces in CIL������������������������������������������������������������������������������������� 727
Defining Structures in CIL������������������������������������������������������������������������������������������������������������������� 728
Defining Enums in CIL������������������������������������������������������������������������������������������������������������������������ 728
Defining Generics in CIL��������������������������������������������������������������������������������������������������������������������� 729
Compiling the CILTypes.il File������������������������������������������������������������������������������������������������������������� 730

.NET Base Class Library, C#, and CIL Data Type Mappings������������������������������������������� 730
Defining Type Members in CIL�������������������������������������������������������������������������������������� 731
Defining Field Data in CIL������������������������������������������������������������������������������������������������������������������� 731
Defining Type Constructors in CIL������������������������������������������������������������������������������������������������������� 732
Defining Properties in CIL������������������������������������������������������������������������������������������������������������������� 732
Defining Member Parameters������������������������������������������������������������������������������������������������������������� 733

xxvii
■ Table of Contents

Examining CIL Opcodes������������������������������������������������������������������������������������������������ 734


The .maxstack Directive��������������������������������������������������������������������������������������������������������������������� 736
Declaring Local Variables in CIL��������������������������������������������������������������������������������������������������������� 736
Mapping Parameters to Local Variables in CIL����������������������������������������������������������������������������������� 737
The Hidden this Reference����������������������������������������������������������������������������������������������������������������� 738
Representing Iteration Constructs in CIL�������������������������������������������������������������������������������������������� 738
The Final Word on CIL������������������������������������������������������������������������������������������������������������������������� 739
Understanding Dynamic Assemblies���������������������������������������������������������������������������� 739
Exploring the System.Reflection.Emit Namespace����������������������������������������������������������������������������� 740
The Role of the System.Reflection.Emit.ILGenerator�������������������������������������������������������������������������� 741
Emitting a Dynamic Assembly������������������������������������������������������������������������������������������������������������ 742
Emitting the Assembly and Module Set���������������������������������������������������������������������������������������������� 744
The Role of the ModuleBuilder TypeC������������������������������������������������������������������������������������������������� 744
Emitting the HelloClass Type and the String Member Variable����������������������������������������������������������� 745
Emitting the Constructors������������������������������������������������������������������������������������������������������������������� 746
Emitting the SayHello() Method���������������������������������������������������������������������������������������������������������� 746
Using the Dynamically Generated Assembly�������������������������������������������������������������������������������������� 747

Summary���������������������������������������������������������������������������������������������������������������������� 748


■Part VI: File Handling, Object Serialization, and Data Access�������� 749

■Chapter 19: File I/O and Object Serialization���������������������������������������������������� 751
Exploring the System.IO Namespace��������������������������������������������������������������������������� 751
The Directory(Info) and File(Info) Types������������������������������������������������������������������������ 752
The Abstract FileSystemInfo Base Class�������������������������������������������������������������������������������������������� 753

Working with the DirectoryInfo Type���������������������������������������������������������������������������� 753


Enumerating Files with the DirectoryInfo Type����������������������������������������������������������������������������������� 755
Creating Subdirectories with the DirectoryInfo Type�������������������������������������������������������������������������� 756

Working with the Directory Type���������������������������������������������������������������������������������� 757


Working with the DriveInfo Class Type������������������������������������������������������������������������� 758
Working with the FileInfo Class������������������������������������������������������������������������������������ 759
The FileInfo.Create() Method�������������������������������������������������������������������������������������������������������������� 760

xxviii
■ Table of Contents

The FileInfo.Open() Method����������������������������������������������������������������������������������������������������������������� 761


The FileInfo.OpenRead() and FileInfo.OpenWrite() Methods��������������������������������������������������������������� 762
The FileInfo.OpenText() Method���������������������������������������������������������������������������������������������������������� 763
The FileInfo.CreateText() and FileInfo.AppendText() Methods������������������������������������������������������������� 763

Working with the File Type������������������������������������������������������������������������������������������� 764


Additional File-centric Members�������������������������������������������������������������������������������������������������������� 764

The Abstract Stream Class������������������������������������������������������������������������������������������� 765


Working with FileStreams������������������������������������������������������������������������������������������������������������������ 766

Working with StreamWriters and StreamReaders������������������������������������������������������� 768


Writing to a Text File��������������������������������������������������������������������������������������������������������������������������� 768
Reading from a Text File��������������������������������������������������������������������������������������������������������������������� 769
Directly Creating StreamWriter/StreamReader Types������������������������������������������������������������������������� 770

Working with StringWriters and StringReaders����������������������������������������������������������� 771


Working with BinaryWriters and BinaryReaders���������������������������������������������������������� 772
Watching Files Programmatically��������������������������������������������������������������������������������� 774
Understanding Object Serialization������������������������������������������������������������������������������ 776
The Role of Object Graphs������������������������������������������������������������������������������������������������������������������ 776
Creating the Sample Types and Top-Level Statements����������������������������������������������������������������������� 777
Extensible Markup Language (XML)��������������������������������������������������������������������������������������������������� 779
JavaScript Object Notation (JSON) Serialization�������������������������������������������������������������������������������� 784

Summary���������������������������������������������������������������������������������������������������������������������� 796

■Chapter 20: Data Access with ADO.NET������������������������������������������������������������� 797
ADO.NET vs. ADO���������������������������������������������������������������������������������������������������������� 797
Understanding ADO.NET Data Providers����������������������������������������������������������������������� 798
ADO.NET Data Providers��������������������������������������������������������������������������������������������������������������������� 799

The Types of the System.Data Namespace������������������������������������������������������������������ 800


The Role of the IDbConnection Interface�������������������������������������������������������������������������������������������� 801
The Role of the IDbTransaction Interface�������������������������������������������������������������������������������������������� 801
The Role of the IDbCommand Interface���������������������������������������������������������������������������������������������� 801
The Role of the IDbDataParameter and IDataParameter Interfaces��������������������������������������������������� 802

xxix
■ Table of Contents

The Role of the IDbDataAdapter and IDataAdapter Interfaces������������������������������������������������������������ 803


The Role of the IDataReader and IDataRecord Interfaces������������������������������������������������������������������ 803

Abstracting Data Providers Using Interfaces���������������������������������������������������������������� 804


Setting Up SQL Server and Azure Data Studio������������������������������������������������������������� 807
Installing SQL Server�������������������������������������������������������������������������������������������������������������������������� 807
Installing a SQL Server IDE����������������������������������������������������������������������������������������������������������������� 809
Connecting to SQL Server������������������������������������������������������������������������������������������������������������������� 810

Restoring the AutoLot Database Backup���������������������������������������������������������������������� 812


Copying the Backup File to Your Container����������������������������������������������������������������������������������������� 813
Restoring the Database with SSMS���������������������������������������������������������������������������������������������������� 813
Restoring the Database with Azure Data Studio��������������������������������������������������������������������������������� 815

Creating the AutoLot Database������������������������������������������������������������������������������������� 816


Creating the Database������������������������������������������������������������������������������������������������������������������������ 817
Creating the Tables����������������������������������������������������������������������������������������������������������������������������� 817
Creating the Table Relationships�������������������������������������������������������������������������������������������������������� 819
Creating the GetPetName() Stored Procedure������������������������������������������������������������������������������������ 821
Adding Test Records��������������������������������������������������������������������������������������������������������������������������� 821

The ADO.NET Data Provider Factory Model������������������������������������������������������������������ 823


A Complete Data Provider Factory Example��������������������������������������������������������������������������������������� 824
A Potential Drawback with the Data Provider Factory Model������������������������������������������������������������� 828

Diving Deeper into Connections, Commands, and DataReaders���������������������������������� 828


Working with Connection Objects������������������������������������������������������������������������������������������������������� 829
Working with Command Objects�������������������������������������������������������������������������������������������������������� 832
Working with Data Readers���������������������������������������������������������������������������������������������������������������� 833

Working with Create, Update, and Delete Queries�������������������������������������������������������� 835


Create the Car and CarViewModel Classes���������������������������������������������������������������������������������������� 836
Adding the InventoryDal Class������������������������������������������������������������������������������������������������������������ 836
Adding the Deletion Logic������������������������������������������������������������������������������������������������������������������� 841
Adding the Update Logic�������������������������������������������������������������������������������������������������������������������� 841

xxx
■ Table of Contents

Working with Parameterized Command Objects�������������������������������������������������������������������������������� 842


Executing a Stored Procedure������������������������������������������������������������������������������������������������������������ 845

Creating a Console-Based Client Application��������������������������������������������������������������� 846


Understanding Database Transactions������������������������������������������������������������������������� 847
Key Members of an ADO.NET Transaction Object������������������������������������������������������������������������������� 848

Adding a Transaction Method to InventoryDal�������������������������������������������������������������� 849


Testing Your Database Transaction����������������������������������������������������������������������������������������������������� 851

Executing Bulk Copies with ADO.NET��������������������������������������������������������������������������� 852


Exploring the SqlBulkCopy Class�������������������������������������������������������������������������������������������������������� 852
Creating a Custom Data Reader��������������������������������������������������������������������������������������������������������� 852
Executing the Bulk Copy��������������������������������������������������������������������������������������������������������������������� 856
Testing the Bulk Copy������������������������������������������������������������������������������������������������������������������������� 857

Summary���������������������������������������������������������������������������������������������������������������������� 858


■Part VII: Entity Framework Core����������������������������������������������������� 859

■Chapter 21: Introducing Entity Framework Core����������������������������������������������� 861
Object-Relational Mappers������������������������������������������������������������������������������������������� 862
Understanding the Role of the Entity Framework Core������������������������������������������������ 862
The Building Blocks of the Entity Framework�������������������������������������������������������������� 863
The DbContext Class��������������������������������������������������������������������������������������������������������������������������� 864
The DbSet<T> Class��������������������������������������������������������������������������������������������������������������������������� 869
The ChangeTracker����������������������������������������������������������������������������������������������������������������������������� 870
Entities������������������������������������������������������������������������������������������������������������������������������������������������ 872
Owned Entity Types���������������������������������������������������������������������������������������������������������������������������� 903
Query Types���������������������������������������������������������������������������������������������������������������������������������������� 906

Query Execution����������������������������������������������������������������������������������������������������������� 909


Mixed Client-Server Evaluation���������������������������������������������������������������������������������������������������������� 909

Tracking vs. NoTracking Queries���������������������������������������������������������������������������������� 910


Code First vs. Database First��������������������������������������������������������������������������������������� 910

xxxi
■ Table of Contents

The EF Core Global Tool CLI Commands����������������������������������������������������������������������� 911


The Migrations Commands����������������������������������������������������������������������������������������������������������������� 913
The Database Commands������������������������������������������������������������������������������������������������������������������� 917
The DbContext Commands����������������������������������������������������������������������������������������������������������������� 918

Summary���������������������������������������������������������������������������������������������������������������������� 920

■Chapter 22: Exploring Entity Framework Core�������������������������������������������������� 921
Creating Records���������������������������������������������������������������������������������������������������������� 921
Entity State����������������������������������������������������������������������������������������������������������������������������������������� 922
Add a Single Record Using Add���������������������������������������������������������������������������������������������������������� 922
Add a Single Record Using Attach������������������������������������������������������������������������������������������������������ 923
Add Multiple Records at Once������������������������������������������������������������������������������������������������������������ 924
Identity Column Considerations When Adding Records���������������������������������������������������������������������� 925
Adding an Object Graph���������������������������������������������������������������������������������������������������������������������� 927
Add Many-to-Many Records��������������������������������������������������������������������������������������������������������������� 928
Add Sample Records�������������������������������������������������������������������������������������������������������������������������� 929

Clear the Sample Data������������������������������������������������������������������������������������������������� 930


Querying Data��������������������������������������������������������������������������������������������������������������� 931
Get All Records����������������������������������������������������������������������������������������������������������������������������������� 931
Filter Records������������������������������������������������������������������������������������������������������������������������������������� 932
Sort Records��������������������������������������������������������������������������������������������������������������������������������������� 933
Paging������������������������������������������������������������������������������������������������������������������������������������������������� 935
Retrieve a Single Record�������������������������������������������������������������������������������������������������������������������� 936
Aggregation Methods������������������������������������������������������������������������������������������������������������������������� 942
Any( ) and All( )����������������������������������������������������������������������������������������������������������������������������������� 943
Getting Data from Stored Procedures������������������������������������������������������������������������������������������������� 944

Querying Related Data������������������������������������������������������������������������������������������������� 945


Eager Loading������������������������������������������������������������������������������������������������������������������������������������� 945
Explicit Loading���������������������������������������������������������������������������������������������������������������������������������� 949
Lazy Loading��������������������������������������������������������������������������������������������������������������������������������������� 951

xxxii
■ Table of Contents

Updating Records��������������������������������������������������������������������������������������������������������� 954


Entity State����������������������������������������������������������������������������������������������������������������������������������������� 954
Update Tracked Entities���������������������������������������������������������������������������������������������������������������������� 954
Update Nontracked Entities���������������������������������������������������������������������������������������������������������������� 955

Deleting Records���������������������������������������������������������������������������������������������������������� 956


Entity State����������������������������������������������������������������������������������������������������������������������������������������� 956
Delete Tracked Records���������������������������������������������������������������������������������������������������������������������� 956
Delete Nontracked Entities����������������������������������������������������������������������������������������������������������������� 957
Catch Cascade Delete Failures����������������������������������������������������������������������������������������������������������� 958

Notable EF Core Features��������������������������������������������������������������������������������������������� 958


Global Query Filters���������������������������������������������������������������������������������������������������������������������������� 958
Raw SQL Queries with LINQ���������������������������������������������������������������������������������������������������������������� 962
Projections������������������������������������������������������������������������������������������������������������������������������������������ 963
Handling Database-Generated Values������������������������������������������������������������������������������������������������ 964
Concurrency Checking������������������������������������������������������������������������������������������������������������������������ 966
Connection Resiliency������������������������������������������������������������������������������������������������������������������������ 968
Database Function Mapping��������������������������������������������������������������������������������������������������������������� 969
EF.Functions���������������������������������������������������������������������������������������������������������������������������������������� 971
Batching of Statements���������������������������������������������������������������������������������������������������������������������� 973
Value Converters�������������������������������������������������������������������������������������������������������������������������������� 974
Shadow Properties����������������������������������������������������������������������������������������������������������������������������� 977
SQL Server Temporal Table Support��������������������������������������������������������������������������������������������������� 979

Summary���������������������������������������������������������������������������������������������������������������������� 989

■Chapter 23: Build a Data Access Layer with Entity Framework Core���������������� 991
Create the AutoLot.Dal and AutoLot.Models Projects��������������������������������������������������� 991
Add the Database View������������������������������������������������������������������������������������������������ 992
Scaffold the DbContext and Entities����������������������������������������������������������������������������� 993
Examine the Results��������������������������������������������������������������������������������������������������������������������������� 993

xxxiii
■ Table of Contents

Switch to Code First����������������������������������������������������������������������������������������������������� 994


Create the DbContext Design-Time Factory��������������������������������������������������������������������������������������� 994
Create the Initial Migration����������������������������������������������������������������������������������������������������������������� 994
Applying the Migration����������������������������������������������������������������������������������������������������������������������� 995

Create the GlobalUsings Files��������������������������������������������������������������������������������������� 996


Create Custom Exceptions������������������������������������������������������������������������������������������� 997
Finalize the Entities and ViewModel����������������������������������������������������������������������������� 998
The Entities����������������������������������������������������������������������������������������������������������������������������������������� 998
The View Models������������������������������������������������������������������������������������������������������������������������������� 1018

Update the ApplicationDbContext������������������������������������������������������������������������������� 1022


Add the Mapped Database Functions����������������������������������������������������������������������������������������������� 1022
Handling DbContext and ChangeTracker Events������������������������������������������������������������������������������� 1022
Override the Conventions����������������������������������������������������������������������������������������������������������������� 1024
Override the SaveChanges Method�������������������������������������������������������������������������������������������������� 1024

Create the Next Migration and Update the Database������������������������������������������������� 1025


Use EF Migrations to Create/Update Database Objects��������������������������������������������� 1025
Add the MigrationHelpers Class������������������������������������������������������������������������������������������������������� 1025
Create and Update the Migration������������������������������������������������������������������������������������������������������ 1027
Apply the Migration�������������������������������������������������������������������������������������������������������������������������� 1027

Add the Repositories�������������������������������������������������������������������������������������������������� 1028


Add the IBaseViewRepo Interface���������������������������������������������������������������������������������������������������� 1028
Add the BaseViewRepo Implementation������������������������������������������������������������������������������������������� 1028
Add the IBaseRepo Interface������������������������������������������������������������������������������������������������������������ 1030
Add the BaseRepo Implementation�������������������������������������������������������������������������������������������������� 1031
Add the ITemporalTableBaseRepo Interface������������������������������������������������������������������������������������� 1033
Add the TemporalTableBaseRepo Implementation��������������������������������������������������������������������������� 1034
Entity-Specific Repo Interfaces�������������������������������������������������������������������������������������������������������� 1035
Implement the Entity-Specific Repositories������������������������������������������������������������������������������������� 1038
Update the GlobalUsings.cs Files����������������������������������������������������������������������������������������������������� 1044

Programmatic Database and Migration Handling������������������������������������������������������ 1044


Drop, Create, and Clean the Database���������������������������������������������������������������������������������������������� 1045

xxxiv
■ Table of Contents

Data Initialization�������������������������������������������������������������������������������������������������������� 1047


Create the Sample Data�������������������������������������������������������������������������������������������������������������������� 1047
Load the Sample Data���������������������������������������������������������������������������������������������������������������������� 1049

Summary�������������������������������������������������������������������������������������������������������������������� 1050

■Chapter 24: Test-Driving AutoLot�������������������������������������������������������������������� 1051
Setting Up the Test-Drives������������������������������������������������������������������������������������������ 1051
Create the Project����������������������������������������������������������������������������������������������������������������������������� 1051
Make the AutoLot.Dal Internals Visible to AutoLot.Dal.Tests������������������������������������������������������������� 1053
Add the GlobalUsings File����������������������������������������������������������������������������������������������������������������� 1053
A First Look at xUnit������������������������������������������������������������������������������������������������������������������������� 1053
Configure the Project and DbContext Instances������������������������������������������������������������������������������� 1055
Add the BaseTest Class�������������������������������������������������������������������������������������������������������������������� 1056
Add the EnsureAutoLotDatabase Test Fixture Class������������������������������������������������������������������������� 1058
Add the Integration Test Classes������������������������������������������������������������������������������������������������������ 1059

Querying the Database����������������������������������������������������������������������������������������������� 1062


LINQ Queries������������������������������������������������������������������������������������������������������������������������������������� 1062
Temporal Queries������������������������������������������������������������������������������������������������������������������������������ 1082
SQL Queries with LINQ���������������������������������������������������������������������������������������������������������������������� 1083
Aggregate Methods�������������������������������������������������������������������������������������������������������������������������� 1084
Any() and All()����������������������������������������������������������������������������������������������������������������������������������� 1086
Getting Data from Stored Procedures����������������������������������������������������������������������������������������������� 1087

Creating Records�������������������������������������������������������������������������������������������������������� 1087


Add a Single Record������������������������������������������������������������������������������������������������������������������������� 1088
Add a Single Record Using Attach���������������������������������������������������������������������������������������������������� 1088
Add Multiple Records at Once���������������������������������������������������������������������������������������������������������� 1089
Adding an Object Graph�������������������������������������������������������������������������������������������������������������������� 1090

Updating Records������������������������������������������������������������������������������������������������������� 1091


Update Tracked Entities�������������������������������������������������������������������������������������������������������������������� 1092
Update Nontracked Entities�������������������������������������������������������������������������������������������������������������� 1092
Concurrency Checking When Updating Records������������������������������������������������������������������������������� 1093

xxxv
■ Table of Contents

Deleting Records�������������������������������������������������������������������������������������������������������� 1094


Delete Tracked Records�������������������������������������������������������������������������������������������������������������������� 1094
Delete Nontracked Entities��������������������������������������������������������������������������������������������������������������� 1095
Catch Cascade Delete Failures��������������������������������������������������������������������������������������������������������� 1095
Concurrency Checking When Deleting Records�������������������������������������������������������������������������������� 1096

Summary�������������������������������������������������������������������������������������������������������������������� 1096


■Part VIII: Windows Client Development���������������������������������������� 1097

■Chapter 25: Introducing Windows Presentation Foundation and XAML���������� 1099
The Motivation Behind WPF���������������������������������������������������������������������������������������� 1099
Unifying Diverse APIs������������������������������������������������������������������������������������������������������������������������ 1100
Providing a Separation of Concerns via XAML���������������������������������������������������������������������������������� 1100
Providing an Optimized Rendering Model���������������������������������������������������������������������������������������� 1101
Simplifying Complex UI Programming���������������������������������������������������������������������������������������������� 1101

Investigating the WPF Assemblies������������������������������������������������������������������������������ 1102


The Role of the Application Class����������������������������������������������������������������������������������������������������� 1103
Constructing an Application Class���������������������������������������������������������������������������������������������������� 1104
Enumerating the Windows Collection����������������������������������������������������������������������������������������������� 1105
The Role of the Window Class���������������������������������������������������������������������������������������������������������� 1105

Understanding the Syntax of WPF XAML�������������������������������������������������������������������� 1110


Introducing Kaxaml��������������������������������������������������������������������������������������������������������������������������� 1110
XAML XML Namespaces and XAML “Keywords”������������������������������������������������������������������������������ 1112
Controlling Class and Member Variable Visibility������������������������������������������������������������������������������ 1114
XAML Elements, XAML Attributes, and Type Converters������������������������������������������������������������������� 1115
Understanding XAML Property-Element Syntax������������������������������������������������������������������������������� 1116
Understanding XAML Attached Properties���������������������������������������������������������������������������������������� 1116
Understanding XAML Markup Extensions����������������������������������������������������������������������������������������� 1117

Building WPF Applications Using Visual Studio���������������������������������������������������������� 1119


The WPF Project Templates�������������������������������������������������������������������������������������������������������������� 1120
The Toolbox and XAML Designer/Editor�������������������������������������������������������������������������������������������� 1121
Setting Properties Using the Properties Window������������������������������������������������������������������������������ 1122

xxxvi
■ Table of Contents

Handling Events Using the Properties Window��������������������������������������������������������������������������������� 1124


Handling Events in the XAML Editor������������������������������������������������������������������������������������������������� 1125
The Document Outline Window�������������������������������������������������������������������������������������������������������� 1126
Enable or Disable the XAML Debugger��������������������������������������������������������������������������������������������� 1126
Examining the App.xaml File������������������������������������������������������������������������������������������������������������ 1128
Mapping the Window XAML Markup to C# Code������������������������������������������������������������������������������ 1129
The Role of BAML����������������������������������������������������������������������������������������������������������������������������� 1131
Solving the Mystery of Main()����������������������������������������������������������������������������������������������������������� 1131
Interacting with Application-Level Data�������������������������������������������������������������������������������������������� 1132
Handling the Closing of a Window Object����������������������������������������������������������������������������������������� 1133
Intercepting Mouse Events��������������������������������������������������������������������������������������������������������������� 1134
Intercepting Keyboard Events����������������������������������������������������������������������������������������������������������� 1135

Summary�������������������������������������������������������������������������������������������������������������������� 1136

■Chapter 26: WPF Controls, Layouts, Events, and Data Binding������������������������ 1137
A Survey of the Core WPF Controls���������������������������������������������������������������������������� 1137
The WPF Ink Controls������������������������������������������������������������������������������������������������������������������������ 1138
The WPF Document Controls������������������������������������������������������������������������������������������������������������ 1138
WPF Common Dialog Boxes�������������������������������������������������������������������������������������������������������������� 1138

A Brief Review of the Visual Studio WPF Designer����������������������������������������������������� 1139


Working with WPF Controls Using Visual Studio������������������������������������������������������������������������������� 1139
Working with the Document Outline Editor�������������������������������������������������������������������������������������� 1140
Controlling Content Layout Using Panels������������������������������������������������������������������� 1140
Positioning Content Within Canvas Panels��������������������������������������������������������������������������������������� 1142
Positioning Content Within WrapPanel Panels���������������������������������������������������������������������������������� 1143
Positioning Content Within StackPanel Panels��������������������������������������������������������������������������������� 1145
Positioning Content Within Grid Panels�������������������������������������������������������������������������������������������� 1146
Grids with GridSplitter Types������������������������������������������������������������������������������������������������������������ 1148
Positioning Content Within DockPanel Panels���������������������������������������������������������������������������������� 1149
Enabling Scrolling for Panel Types��������������������������������������������������������������������������������������������������� 1150
Configuring Panels Using the Visual Studio Designers��������������������������������������������������������������������� 1151

xxxvii
■ Table of Contents

Building a Window’s Frame Using Nested Panels������������������������������������������������������ 1155


Building the Menu System���������������������������������������������������������������������������������������������������������������� 1156
Building Menus Visually�������������������������������������������������������������������������������������������������������������������� 1157
Building the Toolbar�������������������������������������������������������������������������������������������������������������������������� 1158
Building the Status Bar��������������������������������������������������������������������������������������������������������������������� 1158
Finalizing the UI Design�������������������������������������������������������������������������������������������������������������������� 1158
Implementing the MouseEnter/MouseLeave Event Handlers����������������������������������������������������������� 1159
Implementing the Spell-Checking Logic������������������������������������������������������������������������������������������� 1160

Understanding WPF Commands��������������������������������������������������������������������������������� 1160


The Intrinsic Command Objects�������������������������������������������������������������������������������������������������������� 1161
Connecting Commands to the Command Property��������������������������������������������������������������������������� 1162
Connecting Commands to Arbitrary Actions������������������������������������������������������������������������������������� 1162
Working with the Open and Save Commands���������������������������������������������������������������������������������� 1163

Understanding Routed Events������������������������������������������������������������������������������������ 1165


The Role of Routed Bubbling Events������������������������������������������������������������������������������������������������� 1166
Continuing or Halting Bubbling��������������������������������������������������������������������������������������������������������� 1167
The Role of Routed Tunneling Events����������������������������������������������������������������������������������������������� 1168

A Deeper Look at WPF APIs and Controls������������������������������������������������������������������� 1169


Working with the TabControl������������������������������������������������������������������������������������������������������������� 1170

Building the Ink API Tab���������������������������������������������������������������������������������������������� 1170


Designing the Toolbar����������������������������������������������������������������������������������������������������������������������� 1171
The RadioButton Control������������������������������������������������������������������������������������������������������������������� 1171
Add the Save, Load, and Delete Buttons������������������������������������������������������������������������������������������� 1172
Add the InkCanvas Control��������������������������������������������������������������������������������������������������������������� 1172
Preview the Window������������������������������������������������������������������������������������������������������������������������� 1172
Handling Events for the Ink API Tab�������������������������������������������������������������������������������������������������� 1173
Add Controls to the Toolbox�������������������������������������������������������������������������������������������������������������� 1173
The InkCanvas Control���������������������������������������������������������������������������������������������������������������������� 1174
The ComboBox Control��������������������������������������������������������������������������������������������������������������������� 1176
Saving, Loading, and Clearing InkCanvas Data��������������������������������������������������������������������������������� 1178

xxxviii
■ Table of Contents

Introducing the WPF Data-Binding Model������������������������������������������������������������������ 1179


Building the Data Binding Tab����������������������������������������������������������������������������������������������������������� 1179
Establishing Data Bindings��������������������������������������������������������������������������������������������������������������� 1180
The DataContext Property����������������������������������������������������������������������������������������������������������������� 1180
Formatting the Bound Data�������������������������������������������������������������������������������������������������������������� 1181
Data Conversion Using IValueConverter������������������������������������������������������������������������������������������� 1182
Establishing Data Bindings in Code�������������������������������������������������������������������������������������������������� 1183
Building the DataGrid Tab����������������������������������������������������������������������������������������������������������������� 1184
Understanding the Role of Dependency Properties���������������������������������������������������� 1186
Examining an Existing Dependency Property����������������������������������������������������������������������������������� 1188
Important Notes Regarding CLR Property Wrappers������������������������������������������������������������������������� 1190

Building a Custom Dependency Property������������������������������������������������������������������� 1191


Adding a Data Validation Routine����������������������������������������������������������������������������������������������������� 1193
Responding to the Property Change������������������������������������������������������������������������������������������������� 1194

Summary�������������������������������������������������������������������������������������������������������������������� 1195

■Chapter 27: WPF Graphics Rendering Services����������������������������������������������� 1197
Understanding WPF’s Graphical Rendering Services������������������������������������������������� 1197
WPF Graphical Rendering Options���������������������������������������������������������������������������������������������������� 1198

Rendering Graphical Data Using Shapes�������������������������������������������������������������������� 1199


Adding Rectangles, Ellipses, and Lines to a Canvas������������������������������������������������������������������������� 1200
Removing Rectangles, Ellipses, and Lines from a Canvas���������������������������������������������������������������� 1203
Working with Polylines and Polygons����������������������������������������������������������������������������������������������� 1203
Working with Paths�������������������������������������������������������������������������������������������������������������������������� 1204

WPF Brushes and Pens���������������������������������������������������������������������������������������������� 1207


Configuring Brushes Using Visual Studio����������������������������������������������������������������������������������������� 1208
Configuring Brushes in Code������������������������������������������������������������������������������������������������������������ 1211
Configuring Pens������������������������������������������������������������������������������������������������������������������������������ 1212

Applying Graphical Transformations��������������������������������������������������������������������������� 1212


A First Look at Transformations�������������������������������������������������������������������������������������������������������� 1213
Transforming Your Canvas Data�������������������������������������������������������������������������������������������������������� 1214

xxxix
■ Table of Contents

Working with the Visual Studio Transform Editor������������������������������������������������������� 1216


Building the Initial Layout����������������������������������������������������������������������������������������������������������������� 1216
Applying Transformations at Design Time���������������������������������������������������������������������������������������� 1218
Transforming the Canvas in Code����������������������������������������������������������������������������������������������������� 1219

Rendering Graphical Data Using Drawings and Geometries�������������������������������������� 1220


Building a DrawingBrush Using Geometries������������������������������������������������������������������������������������� 1220
Painting with the DrawingBrush������������������������������������������������������������������������������������������������������� 1221
Containing Drawing Types in a DrawingImage��������������������������������������������������������������������������������� 1222
Working with Vector Images��������������������������������������������������������������������������������������� 1222
Converting a Sample Vector Graphic File into XAML������������������������������������������������������������������������ 1223
Importing the Graphical Data into a WPF Project������������������������������������������������������������������������������ 1224
Interacting with the Sign������������������������������������������������������������������������������������������������������������������ 1225

Rendering Graphical Data Using the Visual Layer������������������������������������������������������ 1225


The Visual Base Class and Derived Child Classes���������������������������������������������������������������������������� 1225
A First Look at Using the DrawingVisual Class��������������������������������������������������������������������������������� 1226
Rendering Visual Data to a Custom Layout Manager������������������������������������������������������������������������ 1228
Responding to Hit-Test Operations��������������������������������������������������������������������������������������������������� 1230

Summary�������������������������������������������������������������������������������������������������������������������� 1231

■Chapter 28: WPF Resources, Animations, Styles, and Templates�������������������� 1233
Understanding the WPF Resource System����������������������������������������������������������������� 1233
Working with Binary Resources������������������������������������������������������������������������������������������������������� 1234

Working with Object (Logical) Resources������������������������������������������������������������������� 1237


The Role of the Resources Property������������������������������������������������������������������������������������������������� 1238
Defining Window-wide Resources���������������������������������������������������������������������������������������������������� 1238
The {StaticResource} Markup Extension������������������������������������������������������������������������������������������� 1241
The {DynamicResource} Markup Extension�������������������������������������������������������������������������������������� 1241
Application-Level Resources������������������������������������������������������������������������������������������������������������ 1242
Defining Merged Resource Dictionaries������������������������������������������������������������������������������������������� 1243
Defining a Resource-Only Assembly������������������������������������������������������������������������������������������������� 1244

xl
■ Table of Contents

Understanding WPF’s Animation Services������������������������������������������������������������������ 1245


The Role of the Animation Class Types��������������������������������������������������������������������������������������������� 1245
The To, From, and By Properties������������������������������������������������������������������������������������������������������� 1246
The Role of the Timeline Base Class������������������������������������������������������������������������������������������������� 1246
Authoring an Animation in C# Code�������������������������������������������������������������������������������������������������� 1247
Controlling the Pace of an Animation����������������������������������������������������������������������������������������������� 1248
Reversing and Looping an Animation����������������������������������������������������������������������������������������������� 1249
Authoring Animations in XAML����������������������������������������������������������������������������������� 1250
The Role of Storyboards������������������������������������������������������������������������������������������������������������������� 1251
The Role of Event Triggers���������������������������������������������������������������������������������������������������������������� 1251
Animation Using Discrete Key Frames��������������������������������������������������������������������������������������������� 1252

Understanding the Role of WPF Styles����������������������������������������������������������������������� 1253


Defining and Applying a Style����������������������������������������������������������������������������������������������������������� 1253
Overriding Style Settings������������������������������������������������������������������������������������������������������������������ 1254
The Effect of TargetType on Styles���������������������������������������������������������������������������������������������������� 1254
Subclassing Existing Styles�������������������������������������������������������������������������������������������������������������� 1256
Defining Styles with Triggers������������������������������������������������������������������������������������������������������������ 1256
Defining Styles with Multiple Triggers���������������������������������������������������������������������������������������������� 1257
Animated Styles�������������������������������������������������������������������������������������������������������������������������������� 1258
Assigning Styles Programmatically�������������������������������������������������������������������������������������������������� 1258

Logical Trees, Visual Trees, and Default Templates���������������������������������������������������� 1260


Programmatically Inspecting a Logical Tree������������������������������������������������������������������������������������� 1260
Programmatically Inspecting a Visual Tree��������������������������������������������������������������������������������������� 1262
Programmatically Inspecting a Control’s Default Template�������������������������������������������������������������� 1263

Building a Control Template with the Trigger Framework������������������������������������������ 1266


Templates as Resources������������������������������������������������������������������������������������������������������������������� 1267
Incorporating Visual Cues Using Triggers����������������������������������������������������������������������������������������� 1268
The Role of the {TemplateBinding} Markup Extension���������������������������������������������������������������������� 1269
The Role of ContentPresenter����������������������������������������������������������������������������������������������������������� 1270
Incorporating Templates into Styles������������������������������������������������������������������������������������������������� 1270

Summary�������������������������������������������������������������������������������������������������������������������� 1271

xli
■ Table of Contents


■Chapter 29: WPF Notifications, Validations, Commands, and MVVM��������������� 1273
Introducing Model-View-ViewModel�������������������������������������������������������������������������� 1273
The Model����������������������������������������������������������������������������������������������������������������������������������������� 1273
The View������������������������������������������������������������������������������������������������������������������������������������������� 1274
The View Model�������������������������������������������������������������������������������������������������������������������������������� 1274
Anemic Models or Anemic View Models������������������������������������������������������������������������������������������� 1274

The WPF Binding Notification System������������������������������������������������������������������������ 1275


Observable Models and Collections�������������������������������������������������������������������������������������������������� 1275
Adding Bindings and Data���������������������������������������������������������������������������������������������������������������� 1277
Programmatically Changing the Vehicle Data����������������������������������������������������������������������������������� 1278
Observable Models��������������������������������������������������������������������������������������������������������������������������� 1278
Observable Collections��������������������������������������������������������������������������������������������������������������������� 1280
Wrapping Up Notifications and Observables������������������������������������������������������������������������������������ 1282

WPF Validations���������������������������������������������������������������������������������������������������������� 1282


Updating the Sample for the Validation Examples���������������������������������������������������������������������������� 1283
The Validation Class�������������������������������������������������������������������������������������������������������������������������� 1283
Validation Options����������������������������������������������������������������������������������������������������������������������������� 1283
Leverage Data Annotations with WPF����������������������������������������������������������������������������������������������� 1293
Customizing the ErrorTemplate�������������������������������������������������������������������������������������������������������� 1296
Wrapping Up Validations������������������������������������������������������������������������������������������������������������������� 1298

Creating Custom Commands�������������������������������������������������������������������������������������� 1298


Implementing the ICommand Interface�������������������������������������������������������������������������������������������� 1299
Adding the ChangeColorCommand��������������������������������������������������������������������������������������������������� 1299
Creating the CommandBase Class��������������������������������������������������������������������������������������������������� 1301
Adding the AddCarCommand Class�������������������������������������������������������������������������������������������������� 1302
RelayCommands������������������������������������������������������������������������������������������������������������������������������� 1304
Wrapping Up Commands������������������������������������������������������������������������������������������������������������������ 1306

Migrate Code and Data to a View Model�������������������������������������������������������������������� 1306


Moving the MainWindow.xaml.cs Code�������������������������������������������������������������������������������������������� 1306
Updating the MainWindow Code and Markup���������������������������������������������������������������������������������� 1307

xlii
■ Table of Contents

Updating the Control Markup������������������������������������������������������������������������������������������������������������ 1308


Wrapping Up View Models���������������������������������������������������������������������������������������������������������������� 1308

Updating AutoLot.Dal for MVVM��������������������������������������������������������������������������������� 1308


Summary�������������������������������������������������������������������������������������������������������������������� 1309

■Part IX: ASP.NET Core�������������������������������������������������������������������� 1311

■Chapter 30: Introducing ASP.NET Core������������������������������������������������������������ 1313
A Quick Look Back at ASP.NET MVC��������������������������������������������������������������������������� 1313
Introducing the MVC Pattern������������������������������������������������������������������������������������������������������������ 1313
ASP.NET Core and the MVC Pattern�������������������������������������������������������������������������������������������������� 1314

ASP.NET Core and .NET Core�������������������������������������������������������������������������������������� 1314


One Framework, Many Uses������������������������������������������������������������������������������������������������������������� 1315

Create and Configure the Solution and Projects�������������������������������������������������������� 1315


Using Visual Studio 2022������������������������������������������������������������������������������������������������������������������ 1315
Using the Command Line������������������������������������������������������������������������������������������������������������������ 1320
Update the Entity Framework Core Package Reference������������������������������������������������������������������� 1322
Disable Nullable Reference Types For All Projects��������������������������������������������������������������������������� 1323
Create a GlobalUsing.cs Class in Each Project��������������������������������������������������������������������������������� 1323

Running ASP.NET Core Applications��������������������������������������������������������������������������� 1323


Using Visual Studio��������������������������������������������������������������������������������������������������������������������������� 1324
Using Visual Studio Code������������������������������������������������������������������������������������������������������������������ 1325
Using the Command Line or Terminal Window��������������������������������������������������������������������������������� 1325
Changing Code While Debugging������������������������������������������������������������������������������������������������������ 1325
Debugging ASP.NET Core Applications���������������������������������������������������������������������������������������������� 1325
Update the AutoLot.Api and AutoLot.Web Kestrel Ports�������������������������������������������������������������������� 1327

ASP.NET Core Concepts from MVC/Web API��������������������������������������������������������������� 1328


Convention over Configuration��������������������������������������������������������������������������������������������������������� 1328
Controllers and Actions (MVC Based Web Apps and RESTful Services)�������������������������������������������� 1329
Directory Structure Conventions������������������������������������������������������������������������������������������������������ 1332
Routing��������������������������������������������������������������������������������������������������������������������������������������������� 1333

xliii
■ Table of Contents

Model Binding����������������������������������������������������������������������������������������������������������������������������������� 1343


Model Validation������������������������������������������������������������������������������������������������������������������������������� 1350
Filters������������������������������������������������������������������������������������������������������������������������������������������������ 1352

Summary�������������������������������������������������������������������������������������������������������������������� 1353

■Chapter 31: Diving Into ASP.NET Core�������������������������������������������������������������� 1355
What’s New in ASP.NET Core�������������������������������������������������������������������������������������� 1355
Razor Pages��������������������������������������������������������������������������������������������������������������� 1355
The Razor Page File�������������������������������������������������������������������������������������������������������������������������� 1356
The PageModel Class����������������������������������������������������������������������������������������������������������������������� 1356
Page Handler Methods��������������������������������������������������������������������������������������������������������������������� 1357

Environmental Awareness������������������������������������������������������������������������������������������ 1358


Determining the Runtime Environment�������������������������������������������������������������������������������������������� 1358

The WebAppBuilder and WebApp������������������������������������������������������������������������������� 1361


The Program.cs File with RESTful Services�������������������������������������������������������������������������������������� 1361
The Program.cs File with MVC Style Applications���������������������������������������������������������������������������� 1362
The Program.cs File with Razor Page Based Applications��������������������������������������������������������������� 1363

Application Configuration������������������������������������������������������������������������������������������� 1364


Built-in Dependency Injection������������������������������������������������������������������������������������ 1365
Adding Web App Support To The Dependency Injection Container��������������������������������������������������� 1366
Adding Derived DbContext Classes into the DI Container����������������������������������������������������������������� 1367
Adding Custom Services To The Dependency Injection Container���������������������������������������������������� 1368
Dependency Hierarchies������������������������������������������������������������������������������������������������������������������� 1369
Injecting Dependencies�������������������������������������������������������������������������������������������������������������������� 1369
Getting Dependencies in Program.cs����������������������������������������������������������������������������������������������� 1370
Build the Shared Data Services�������������������������������������������������������������������������������������������������������� 1371

The Options Pattern in ASP.NET Core������������������������������������������������������������������������� 1376


Using the Options Pattern����������������������������������������������������������������������������������������������������������������� 1377

The HTTP Client Factory��������������������������������������������������������������������������������������������� 1379


Basic Usage�������������������������������������������������������������������������������������������������������������������������������������� 1379
Named Clients���������������������������������������������������������������������������������������������������������������������������������� 1380

xliv
■ Table of Contents

Typed Clients������������������������������������������������������������������������������������������������������������������������������������ 1380


The AutoLot API Service Wrapper����������������������������������������������������������������������������������������������������� 1381

Deploying ASP.NET Core Applications������������������������������������������������������������������������� 1391


Lightweight and Modular HTTP Request Pipeline������������������������������������������������������ 1391
Logging���������������������������������������������������������������������������������������������������������������������� 1391
Add Logging with Serilog����������������������������������������������������������������������������������������������������������������� 1392
The AutoLot Logging Framework������������������������������������������������������������������������������������������������������ 1398
Add Logging to the Data Services���������������������������������������������������������������������������������������������������� 1403
Test-Drive the Logging Framework�������������������������������������������������������������������������������������������������� 1405

String Utilities������������������������������������������������������������������������������������������������������������� 1405


Summary�������������������������������������������������������������������������������������������������������������������� 1406

■Chapter 32: RESTful Services with ASP.NET Core�������������������������������������������� 1407
Introducing ASP.NET Core RESTful Services��������������������������������������������������������������� 1407
Controller Actions with RESTful Services������������������������������������������������������������������� 1408
Formatted JSON Response Results�������������������������������������������������������������������������������������������������� 1408
The ApiController Attribute��������������������������������������������������������������������������������������������������������������� 1412

API Versioning������������������������������������������������������������������������������������������������������������ 1417


Microsoft’s REST API Guidelines������������������������������������������������������������������������������������������������������� 1417
Add Versioning NuGet Packages������������������������������������������������������������������������������������������������������� 1418
Add API Version Support������������������������������������������������������������������������������������������������������������������� 1419
The API Version Attributes����������������������������������������������������������������������������������������������������������������� 1422
Version Interleaving�������������������������������������������������������������������������������������������������������������������������� 1423
Query String Version Requests and Routing������������������������������������������������������������������������������������� 1425
Getting the API Version in Requests�������������������������������������������������������������������������������������������������� 1426
Route Updates for URL Segment Versioning������������������������������������������������������������������������������������� 1427
Deprecating Versions������������������������������������������������������������������������������������������������������������������������ 1428
Unsupported Version Requests��������������������������������������������������������������������������������������������������������� 1428
Add the API Version Explorer������������������������������������������������������������������������������������������������������������ 1429

Update the Swagger/OpenAPI Settings���������������������������������������������������������������������� 1430


Add the XML Documentation File����������������������������������������������������������������������������������������������������� 1430
The Application’s Swagger Settings������������������������������������������������������������������������������������������������� 1434
xlv
Discovering Diverse Content Through
Random Scribd Documents
external; the bearing and the end of it is the material prosperity of the little land
of Judah. From this Merx concludes that the book is not an original work, but a
mere summary of passages from previous prophets, that with a few reflections of
the life of the Jews after the Return lead us to assign it to that period of literary
culture which Nehemiah inaugurated by the collection of national writings and
which was favoured by the cessation of all political disturbance. Joel gathered up
the pictures of the Messianic age in the older prophets, and welded them together
in one long prayer by the fervid belief that that age was near. But while the older
prophets spoke upon the ground of actual fact and rose from this to a majestic
picture of the last punishment, the still life of Joel’s time had nothing such to offer
him and he had to seek another basis for his prophetic flight. It is probable that he
sought this in the relation of Type and Antitype. The Antitype he found in the
liberation from Egypt, the darkness and the locusts of which he transferred to his
canvas from Exodus x. 4–6. The locusts, therefore, are neither real nor symbolic,
but ideal. This is the method of the Midrash and Haggada in Jewish literature,
which constantly placed over against each other the deliverance from Egypt and
the last judgment. It is a method that is already found in such portions of the Old
Testament as Ezekiel xxxvii. and Psalm lxxviii. Joel’s locusts are borrowed from the
Egyptian plagues, but are presented as the signs of the Last Day. They will bring it
near to Israel by famine, drought and the interruption of worship described in
chap. i. Chap. ii., which Merx keeps distinct from chap. i., is based on a study of
Ezekiel, from whom Joel has borrowed, among other things, the expressions the
garden of Eden and the Northerner. The two verses generally held to be historic,
18 and 19, Merx takes to be the continuation of the prayer of the priests, pointing
the verbs so as to turn them from perfects into futures.[1155] The rest of the book,
Merx strives to show, is pieced together from many prophets, chiefly Isaiah and
Ezekiel, but without the tender spiritual feeling of the one, or the colossal
magnificence of the other. Special nations are mentioned, but in this portion of the
work we have to do not with events already past, but with general views, and
these not original, but conditioned by the expressions of earlier writers. There is
no history in the book: it is all ideal, mystical, apocalyptic. That is to say, according
to Merx, there is no real prophet or prophetic fire, only an old man warming his
feeble hands over a few embers that he has scraped together from the ashes of
ancient fires, now nearly wholly dead.
Merx has traced Joel’s relations to other prophets, and reflection of a late date
in Israel’s history, with care and ingenuity; but his treatment of the text and
exegesis of the prophet’s meaning are alike forced and fanciful. In face of the
support which the Massoretic reading of the hinge of the book, chap. ii. 18 ff.,
receives from the ancient versions, and of its inherent probability and harmony
with the context, Merx’s textual emendation is unnecessary, besides being in itself
unnatural.[1156] While the very same objections which we have already found valid
against the allegorical interpretation equally dispose of this mystical one. Merx
outrages the evident features of the book almost as much as Hengstenberg and
Pusey have done. He has lifted out of time altogether that which plainly purports
to be historical. His literary criticism is as unsound as his textual. It is only by
ignoring the beautiful poetry of chap. i. that he transplants it to the future. Joel’s
figures are too vivid, too actual, to be predictive or mystical. And the whole
interpretation wrecks itself in the same verse as the allegorical, the verse, viz., in
which Joel plainly speaks of himself as having suffered with his hearers the plague
he describes.[1157]

We may, therefore, with confidence conclude that the allegorical


and mystical interpretations of Joel are impossible; and that the only
reasonable view of our prophet is that which regards him as calling,
in chap. i. 2—ii. 17, upon his contemporaries to repent in face of a
plague of locusts, so unusually severe that he has felt it to be
ominous of even the Day of the Lord; and in the rest of his book, as
promising material, political and spiritual triumphs to Israel in
consequence of their repentance, either already consummated, or
anticipated by the prophet as certain.
It is true that the account of the locusts appears to bear features
which conflict with the literal interpretation. Some of these, however,
vanish upon a fuller knowledge of the awful degree which such a
plague has been testified to reach by competent observers within
our own era.[1158] Those that remain may be attributed partly to the
poetic hyperbole of Joel’s style, and partly to the fact that he sees in
the plague far more than itself. The locusts are signs of the Day of
Jehovah. Joel treats them as we found Zephaniah treating the
Scythian hordes of his day. They are as real as the latter, but on
them as on the latter the lurid glare of Apocalypse has fallen,
magnifying them and investing them with that air of ominousness
which is the sole justification of the allegorical and mystic
interpretation of their appearance.
To the same sense of their office as heralds of the last day, we
owe the description of the locusts as the Northerner.[1159] The North
is not the quarter from which locusts usually reach Palestine, nor is
there any reason to suppose that by naming the North Joel meant
only to emphasise the unusual character of these swarms. Rather he
takes a name employed in Israel since Jeremiah’s time to express
the instruments of Jehovah’s wrath in the day of His judgment of
Israel. The name is typical of Doom, and therefore Joel applies it to
his fateful locusts.

3. STATE OF THE TEXT AND THE STYLE OF THE BOOK.


Joel’s style is fluent and clear, both when he is describing the
locusts, in which part of his book he is most original, and when he is
predicting, in apocalyptic language largely borrowed from earlier
prophets, the Day of Jehovah. To the ease of understanding him we
may attribute the sound state of the text and its freedom from
glosses. In this, like most of the books of the post-exilic prophets,
especially the Books of Haggai, “Malachi” and Jonah, Joel’s book
contrasts very favourably with those of the older prophets; and that
also, to some degree, is proof of the lateness of his date. The Greek
translators have, on the whole, understood Joel easily and with little
error. In their version there are the usual differences of grammatical
construction, especially in the pronominal suffixes and verbs, and of
punctuation; but very few bits of expansion and no real additions.
These are all noted in the translation below.
CHAPTER XXVIII

THE LOCUSTS AND THE DAY OF THE LORD


JOEL i.—ii. 17

Joel, as we have seen, found the motive of his prophecy in a recent


plague of locusts, the appearance of which and the havoc they
worked are described by him in full detail. Writing not only as a poet
but as a seer, who reads in the locusts signs of the great Day of the
Lord, Joel has necessarily put into his picture several features which
carry the imagination beyond the limits of experience. And yet, if we
ourselves had lived through such a plague, we should be able to
recognise how little license the poet has taken, and that the seer, so
far from unduly mixing with his facts the colours of Apocalypse,
must have experienced in the terrible plague itself enough to
provoke all the religious and monitory use which he makes of it.
The present writer has seen but one swarm of locusts, in which,
though it was small and soon swept away by the wind, he felt not
only many of the features that Joel describes, but even some degree
of that singular helplessness before a calamity of portent far beyond
itself, something of that supernatural edge and accent, which, by the
confession of so many observers, characterise the locust-plague and
the earthquake above all other physical disasters. One summer
afternoon, upon the plain of Hauran, a long bank of mist grew
rapidly from the western horizon. The day was dull, and as the mist
rose athwart the sunbeams, struggling through clouds, it gleamed
cold and white, like the front of a distant snow-storm. When it came
near, it seemed to be more than a mile broad, and was dense
enough to turn the atmosphere raw and dirty, with a chill as of a
summer sea-fog, only that this was not due to any fall in the
temperature. Nor was there the silence of a mist. We were
enveloped by a noise, less like the whirring of wings than the rattle
of hail or the crackling of bush on fire. Myriads upon myriads of
locusts were about us, covering the ground, and shutting out the
view in all directions. Though they drifted before the wind, there was
no confusion in their ranks. They sailed in unbroken lines, sometimes
straight, sometimes wavy; and when they passed pushing through
our caravan, they left almost no stragglers, except from the last
battalion, and only the few dead which we had caught in our hands.
After several minutes they were again but a lustre on the air, and so
melted away into some heavy clouds in the east.
Modern travellers furnish us with terrible impressions of the
innumerable multitudes of a locust-plague, the succession of their
swarms through days and weeks, and the utter desolation they leave
behind them. Mr. Doughty writes:[1160] “There hopped before our
feet a minute brood of second locusts, of a leaden colour, with
budding wings like the spring leaves, and born of those gay swarms
which a few weeks before had passed over and despoiled the desert.
After forty days these also would fly as a pestilence, yet more
hungry than the former, and fill the atmosphere.” And later: “The
clouds of the second locust brood which the Arabs call ‘Am’dan,
pillars, flew over us for some days, invaded the booths and for blind
hunger even bit our shins.”[1161] It was “a storm of rustling
wings.”[1162] “This year was remembered for the locust swarms and
great summer heat.”[1163] A traveller in South Africa[1164] says: “For
the space of ten miles on each side of the Sea-Cow river and eighty
or ninety miles in length, an area of sixteen or eighteen hundred
square miles, the whole surface might literally be said to be covered
with them.” In his recently published book on South Africa, Mr. Bryce
writes:—[1165]
“It is a strange sight, beautiful if you can forget the destruction it
brings with it. The whole air, to twelve or even eighteen feet above
the ground, is filled with the insects, reddish brown in body, with
bright, gauzy wings. When the sun’s rays catch them it is like the
sea sparkling with light. When you see them against a cloud they are
like the dense flakes of a driving snow-storm. You feel as if you had
never before realised immensity in number. Vast crowds of men
gathered at a festival, countless tree-tops rising along the slope of a
forest ridge, the chimneys of London houses from the top of St.
Paul’s—all are as nothing to the myriads of insects that blot out the
sun above and cover the ground beneath and fill the air whichever
way one looks. The breeze carries them swiftly past, but they come
on in fresh clouds, a host of which there is no end, each of them a
harmless creature which you can catch and crush in your hand, but
appalling in their power of collective devastation.”
And take three testimonies from Syria: “The quantity of these
insects is a thing incredible to any one who has not seen it himself;
the ground is covered by them for several leagues.”[1166] “The whole
face of the mountain[1167] was black with them. On they came like a
living deluge. We dug trenches and kindled fires, and beat and burnt
to death heaps upon heaps, but the effort was utterly useless. They
rolled up the mountain-side, and poured over rocks, walls, ditches
and hedges, those behind covering up and passing over the masses
already killed. For some days they continued to pass. The noise
made by them in marching and foraging was like that of a heavy
shower falling upon a distant forest.”[1168] “The roads were covered
with them, all marching and in regular lines, like armies of soldiers,
with their leaders in front; and all the opposition of man to resist
their progress was in vain.” Having consumed the plantations in the
country, they entered the towns and villages. “When they
approached our garden all the farm servants were employed to keep
them off, but to no avail; though our men broke their ranks for a
moment, no sooner had they passed the men, than they closed
again, and marched forward through hedges and ditches as before.
Our garden finished, they continued their march toward the town,
devastating one garden after another. They have also penetrated
into most of our rooms: whatever one is doing one hears their noise
from without, like the noise of armed hosts, or the running of many
waters. When in an erect position their appearance at a little
distance is like that of a well-armed horseman.”[1169]
Locusts are notoriously adapted for a plague, “since to strength
incredible for so small a creature, they add saw-like teeth, admirably
calculated to eat up all the herbs in the land.”[1170] They are the
incarnation of hunger. No voracity is like theirs, the voracity of little
creatures, whose million separate appetites nothing is too minute to
escape. They devour first grass and leaves, fruit and foliage,
everything that is green and juicy. Then they attack the young
branches of trees, and then the hard bark of the trunks.[1171] “After
eating up the corn, they fell upon the vines, the pulse, the willows,
and even the hemp, notwithstanding its great bitterness.”[1172] “The
bark of figs, pomegranates and oranges, bitter, hard and corrosive,
escaped not their voracity.”[1173] “They are particularly injurious to
the palm-trees; these they strip of every leaf and green particle, the
trees remaining like skeletons with bare branches.”[1174] “For eighty
or ninety miles they devoured every green herb and every blade of
grass.”[1175] “The gardens outside Jaffa are now completely stripped,
even the bark of the young trees having been devoured, and look
like a birch-tree forest in winter.”[1176] “The bushes were eaten quite
bare, though the animals could not have been long on the spot.
They sat by hundreds on a bush gnawing the rind and the woody
fibres.”[1177] “Bamboo groves have been stripped of their leaves and
left standing like saplings after a rapid bush fire, and grass has been
devoured so that the bare ground appeared as if burned.”[1178] “The
country did not seem to be burnt, but to be much covered with snow
through the whiteness of the trees and the dryness of the
herbs.”[1179] The fields finished, they invade towns and houses, in
search of stores. Victual of all kinds, hay, straw, and even linen and
woollen clothes and leather bottles, they consume or tear in pieces.
[1180] They flood through the open, unglazed windows and lattices:
nothing can keep them out.
These extracts prove to us what little need Joel had of hyperbole
in order to read his locusts as signs of the Day of Jehovah; especially
if we keep in mind that locusts are worst in very hot summers, and
often accompany an absolute drought along with its consequence of
prairie and forest fires. Some have thought that, in introducing the
effects of fire, Joel only means to paint the burnt look of a land after
locusts have ravaged it. But locusts do not drink up the streams, nor
cause the seed to shrivel in the earth.[1181] By these the prophet
must mean drought, and by the flame that has burned all the trees
of the field,[1182] the forest fire, finding an easy prey in the trees
which have been reduced to firewood by the locusts’ teeth.
Even in the great passage in which he passes from history to
Apocalypse, from the gloom and terror of the locusts to the lurid
dawn of Jehovah’s Day, Joel keeps within the actual facts of
experience:—

Day of darkness and murk,


Day of cloud and heavy mist,
Like dawn scattered on the mountains,
A people many and powerful.

No one who has seen a cloud of locusts can question the realism
even of this picture: the heavy gloom of the immeasurable mass of
them, shot by gleams of light where a few of the sun’s imprisoned
beams have broken through or across the storm of lustrous wings.
This is like dawn beaten down upon the hilltops, and crushed by
rolling masses of cloud, in conspiracy to prolong the night. No: the
only point at which Joel leaves absolute fact for the wilder
combinations of Apocalypse is at the very close of his description,
chap. ii. 10 and 11, and just before his call to repentance. Here we
find, mixed with the locusts, earthquake and thunderstorm; and Joel
has borrowed these from the classic pictures of the Day of the Lord,
using some of the very phrases of the latter:—

Earth trembles before them,


Heaven quakes,
Sun and moon become black,
The stars withdraw their shining,
And Jehovah utters His voice before His army.

Joel, then, describes, and does not unduly enhance, the terrors
of an actual plague. At first his whole strength is so bent to make his
people feel these, that, though about to call to repentance, he does
not detail the national sins which require it. In his opening verses he
summons the drunkards,[1183] but that is merely to lend vividness to
his picture of facts, because men of such habits will be the first to
feel a plague of this kind. Nor does Joel yet ask his hearers what the
calamity portends. At first he only demands that they shall feel it, in
its uniqueness and its own sheer force.
Hence the peculiar style of the passage. Letter for letter, this is
one of the heaviest passages in prophecy. The proportion in Hebrew
of liquids to the other letters is not large; but here it is smaller than
ever. The explosives and dentals are very numerous. There are
several keywords, with hard consonants and long vowels, used again
and again: Shuddadh, ‘ābhlah, ‘umlal, hôbhîsh. The longer lines into
which Hebrew parallelism tends to run are replaced by a rapid series
of short, heavy phrases, falling like blows. Critics have called it
rhetoric. But it is rhetoric of a very high order and perfectly suited to
the prophet’s purpose. Look at chap. i. 10: Shuddadh sadheh,
‘ābhlah ‘adhamah, shuddadh daghan, hôbhîsh tîrôsh, ‘umlal yiṣḥar.
[1184]Joel loads his clauses with the most leaden letters he can find,
and drops them in quick succession, repeating the same heavy word
again and again, as if he would stun the careless people into some
sense of the bare, brutal weight of the calamity which has befallen
them.
Now Joel does this because he believes that, if his people feel the
plague in its proper violence, they must be convinced that it comes
from Jehovah. The keynote of this part of the prophecy is found in
chap. i. 15: “Keshôdh mishshaddhai,” like violence from the All-
violent doth it come. “If you feel this as it is, you will feel Jehovah
Himself in it. By these very blows, He and His Day are near. We had
been forgetting how near.” Joel mentions no crime, nor enforces any
virtue: how could he have done so in so strong a sense that “the
Judge was at the door”? To make men feel that they had forgotten
they were in reach of that Almighty Hand, which could strike so
suddenly and so hard—Joel had time only to make men feel that,
and to call them to repentance. In this we probably see some
reflection of the age: an age when men’s thoughts were thrusting
the Deity further and further from their life; when they put His Law
and Temple between Him and themselves; and when their religion,
devoid of the sense of His Presence, had become a set of formal
observances, the rending of garments and not of hearts. But He,
whom His own ordinances had hidden from His people, has burst
forth through nature and in sheer force of calamity. He has revealed
Himself, El-Shaddhai, God All-violent, as He was known to their
fathers, who had no elaborate law or ritual to put between their
fearful hearts and His terrible strength, but cowered before Him,
helpless on the stripped soil, and naked beneath His thunder. By just
these means did Elijah and Amos bring God home to the hearts of
ancient Israel. In Joel we see the revival of the old nature-religion,
and the revenge that it was bound to take upon the elaborate
systems which had displaced it, but which by their formalism and
their artificial completeness had made men forget that near
presence and direct action of the Almighty which it is nature’s own
office to enforce upon the heart.
The thing is true, and permanently valid. Only the great natural
processes can break up the systems of dogma and ritual in which we
make ourselves comfortable and formal, and drive us out into God’s
open air of reality. In the crash of nature’s forces even our particular
sins are forgotten, and we feel, as in the immediate presence of
God, our whole, deep need of repentance. So far from blaming the
absence of special ethics in Joel’s sermon, we accept it as natural
and proper to the occasion.
Such, then, appears to be the explanation of the first part of the
prophecy, and its development towards the call to repentance, which
follows it. If we are correct, the assertion[1185] is false that no plan
was meant by the prophet. For not only is there a plan, but the plan
is most suitable to the requirements of Israel, after their adoption of
the whole Law in 445, and forms one of the most necessary and
interesting developments of all religion: the revival, in an artificial
period, of those primitive forces of religion which nature alone
supplies, and which are needed to correct formalism and the
forgetfulness of the near presence of the Almighty. We see in this,
too, the reason of Joel’s archaic style, both of conception and
expression: that likeness of his to early prophets which has led so
many to place him between Elijah and Amos.[1186] They are wrong.
Joel’s simplicity is that not of early prophecy, but of the austere
forces of this revived and applied to the artificiality of a later age.
One other proof of Joel’s conviction of the religious meaning of
the plague might also have been pled by the earlier prophets, but
certainly not in the terms in which Joel expresses it. Amos and
Hosea had both described the destruction of the country’s fertility in
their day as God’s displeasure on His people and (as Hosea puts it)
His divorce of His Bride from Himself.[1187] But by them the physical
calamities were not threatened alone: banishment from the land and
from enjoyment of its fruits was to follow upon drought, locusts and
famine. In threatening no captivity Joel differs entirely from the early
prophets. It is a mark of his late date. And he also describes the
divorce between Jehovah and Israel, through the interruption of the
ritual by the plague, in terms and with an accent which could hardly
have been employed in Israel before the Exile. After the rebuilding of
the Temple and restoration of the daily sacrifices morning and
evening, the regular performance of the latter was regarded by the
Jews with a most superstitious sense of its indispensableness to the
national life. Before the Exile, Jeremiah, for instance, attaches no
importance to it, in circumstances in which it would have been not
unnatural for him, priest as he was, to do so.[1188] But after the
Exile, the greater scrupulousness of the religious life, and its
absorption in ritual, laid extraordinary emphasis upon the daily
offering, which increased to a most painful degree of anxiety as the
centuries went on.[1189] The New Testament speaks of the Twelve
Tribes constantly serving God day and night;[1190] and Josephus,
while declaring that in no siege of Jerusalem before the last did the
interruption ever take place in spite of the stress of famine and war
combined, records the awful impression made alike on Jew and
heathen by the giving up of the daily sacrifice on the 17th of July,
A.D.70, during the investment of the city by Titus.[1191] This disaster,
which Judaism so painfully feared at every crisis in its history,
actually happened, Joel tells us, during the famine caused by the
locusts. Cut off are the meal and the drink offerings from the house
of Jehovah.[1192] Is not food cut off from our eyes, joy and gladness
from the house of our God?[1193] Perhaps He will turn and relent,
and leave a blessing behind Him, meal and drink offering for
Jehovah our God.[1194] The break “of the continual symbol of
gracious intercourse between Jehovah and His people, and the main
office of religion,” means divorce between Jehovah and Israel. Wail
like a bride girt in sackcloth for the husband of her youth! Wail, O
ministers of the altar, O ministers of God![1195] This then was
another reason for reading in the plague of locusts more than a
physical meaning. This was another proof, only too intelligible to
scrupulous Jews, that the great and terrible Day of the Lord was at
hand.
Thus Joel reaches the climax of his argument. Jehovah is near,
His Day is about to break. From this it is impossible to escape on the
narrow path of disaster by which the prophet has led up to it. But
beneath that path the prophet passes the ground of a broad truth,
and on that truth, while judgment remains still as real, there is room
for the people to turn from it. If experience has shown that God is in
the present, near and inevitable, faith remembers that He is there
not willingly for judgment, but with all His ancient feeling for Israel
and His zeal to save her. If the people choose to turn, Jehovah, as
their God and as one who works for their sake, will save them. Of
this God assures them by His own word. For the first time in the
prophecy He speaks for Himself. Hitherto the prophet has been
describing the plague and summoning to penitence. But now oracle
of Jehovah of Hosts.[1196] The great covenant name, Jehovah your
God, is solemnly repeated as if symbolic of the historic origin and
age-long endurance of Jehovah’s relation to Israel; and the very
words of blessing are repeated which were given when Israel was
called at Sinai and the covenant ratified:—

For He is gracious and merciful,


Long-suffering and plenteous in leal love,
And relents Him of the evil

He has threatened upon you. Once more the nation is summoned


to try Him by prayer: the solemn prayer of all Israel, pleading that
He should not give His people to reproach.
The Word of Jehovah
which came to Jo’el the son of Pethû’el.[1197]

Hear this, ye old men,


And give ear, all inhabitants of the land!
Has the like been in your days,
Or in the days of your fathers?
Tell it to your children,
And your children to their children,
And their children to the generation that follows.
That which the Shearer left the Swarmer hath
eaten,
And that which the Swarmer left the Lapper hath
eaten.
And that which the Lapper left the Devourer hath
eaten.

These are four different names for locusts, which it is best to


translate by their literal meaning. Some think that they represent
one swarm of locusts in four stages of development, but this cannot
be, because the same swarm never returns upon its path, to
complete the work of destruction which it had begun in an earlier
stage of its growth. Nor can the first-named be the adult brood from
whose eggs the others spring, as Doughty has described,[1198] for
that would account only for two of the four names. Joel rather
describes successive swarms of the insect, without reference to the
stages of its growth, and he does so as a poet, using, in order to
bring out the full force of its devastation, several of the Hebrew
names, that were given to the locust as epithets of various aspects
of its destructive power. The names, it is true, cannot be said to rise
in climax, but at least the most sinister is reserved to the last.[1199]
Rouse ye, drunkards, and weep,
And wail, all ye bibbers of wine!
The new wine is cut off from your mouth!
For a nation is come up on My land,
Powerful and numberless;
His teeth are the teeth of the lion,
And the fangs[1200] of the lioness his.
My vine he has turned to waste,
And My fig-tree to splinters;
He hath peeled it and strawed it,
Bleached are its branches!

Wail as a bride girt in sackcloth for the spouse of


her youth.
Cut off are the meal and drink offerings from the
house of Jehovah!
In grief are the priests, the ministers of Jehovah.
The fields are blasted, the ground is in grief,
Blasted is the corn, abashed is the new wine, the oil
pines away.
Be ye abashed, O ploughmen!
Wail, O vine-dressers,
For the wheat and the barley;
The harvest is lost from the field!
The vine is abashed, and the fig-tree is drooping;
Pomegranate, palm too and apple,
All trees of the field are dried up:
Yea, joy is abashed and away from the children of
men.
In this passage the same feeling is attributed to men and to the
fruits of the land: In grief are the priests, the ground is in grief. And
it is repeatedly said that all alike are abashed. By this heavy word we
have sought to render the effect of the similarly sounding
“hôbhîsha,” that our English version renders ashamed. It signifies to
be frustrated, and so disheartened, put out: soured would be an
equivalent, applicable to the vine and to joy and to men’s hearts.
Put on mourning, O priests, beat the breast;
Wail, ye ministers of the altar;
Come, lie down in sackcloth, O ministers of my God:
For meal-offering and drink-offering are cut off
from the house of your God.

Hallow a fast, summon an assembly,


Gather[1201] all the inhabitants of the land to the
house of your God;
And cry to Jehovah:
“Alas for the Day! At hand is the Day of
Jehovah!
And as vehemence from the Vehement[1202] doth it come.”
Is not food cut off from before us,
Gladness and joy from the house of our God?
The grains shrivel under their hoes,[1203]
The garners are desolate, the barns broken down,
For the corn is withered—what shall we put in
them?[1204]
The herds of cattle huddle together,[1205] for they have
no pasture;
Yea, the flocks of sheep are forlorn.[1206]
To Thee, Jehovah, do I cry:
For fire has devoured the pastures of the steppes,[1207]
And the flame hath scorched all the trees of the field.
The wild beasts pant up to Thee:
For the watercourses are dry,
And fire has devoured the pastures of the steppes.
Here, with the close of chap. i., Joel’s discourse takes pause, and
in chap. ii. he begins a second with another call to repentance in
face of the same plague. But the plague has progressed. The locusts
are described now in their invasion not of the country but of the
towns, to which they pass after the country is stripped. For
illustration of the latter see above, p. 401. The horn which is to be
blown, ver. 1, is an alarm horn,[1208] to warn the people of the
approach of the Day of the Lord, and not the Shophar which called
the people to a general assembly, as in ver. 15.
Blow a horn in Zion,
Sound the alarm in My holy mountain!
Let all inhabitants of the land tremble,
For the Day of Jehovah comes—it is near!
Day of darkness and murk, day of cloud and
heavy mist.[1209]
Like dawn scattered[1210] on the mountains,
A people many and powerful;
Its like has not been from of old,
And shall not again be for years of generation upon
generation.
Before it the fire devours,[1211]
And behind the flame consumes.
Like the garden of Eden[1212] is the land in front,
And behind it a desolate desert;
Yea, it lets nothing escape.
Their visage is the visage of horses,
And like horsemen they run.
They rattle like chariots over the tops of the hills,
Like the crackle of flames devouring stubble,
Like a powerful people prepared for battle.
Peoples are writhing before them,
Every face gathers blackness.

Like warriors they run,


Like fighting-men they come up the wall;
They march every man by himself,[1213]
And they ravel[1214] not their paths.
None jostles his comrade,
They march every man on his track,[1215]
And plunge through the missiles unbroken.[1216]
They scour the city, run upon the walls,
Climb into the houses, and enter the windows like a
thief.
Earth trembles before them,
Heaven quakes,
Sun and moon become black,
The stars withdraw their shining.
And Jehovah utters His voice before His army:
For very great is His host;
Yea, powerful is He that performeth His word.
Great is the Day of Jehovah, and very awful:
Who may abide it?[1217]

But now hear the oracle of Jehovah:


Turn ye to Me with all your heart,
And with fasting and weeping and mourning.
Rend ye your hearts and not your garments,
And turn to Jehovah your God:
For He is gracious and merciful,
Long-suffering and plenteous in love,
And relents of the evil.
Who knows but He will turn and relent,
And leave behind Him a blessing,
Meal-offering and drink-offering to Jehovah your
God?

Blow a horn in Zion,


Hallow a fast, summon the assembly!
G th th l h ll th ti
Gather the people, hallow the congregation,
Assemble the old men,[1218] gather the children, and
infants at the breast;
Let the bridegroom come forth from his chamber,
And the bride from her bower.[1219]
Let the priests, the ministers of Jehovah, weep
between porch and altar;
Let them say, Spare, O Jehovah, Thy people,
And give not Thine heritage to dishonour, for the
heathen to mock them:[1220]
Why should it be said among the nations, Where is
their God?
CHAPTER XXIX

PROSPERITY AND THE SPIRIT


JOEL ii. 18–32 (Eng.; ii. 18—iii. Heb.)

Then did Jehovah become jealous for His land, and took pity upon
His people—with these words Joel opens the second half of his book.
Our Authorised Version renders them in the future tense, as the
continuation of the prophet’s discourse, which had threatened the
Day of the Lord, urged the people to penitence, and now promises
that their penitence shall be followed by the Lord’s mercy. But such a
rendering forces the grammar;[1221] and the Revised English Version
is right in taking the verbs, as the vast majority of critics do, in the
past. Joel’s call to repentance has closed, and has been successful.
The fast has been hallowed, the prayers are heard. Probably an
interval has elapsed between vv. 17 and 18, but in any case, the
people having repented, nothing more is said of their need of doing
so, and instead we have from God Himself a series of promises, vv.
19–27, in answer to their cry for mercy. These promises relate to the
physical calamity which has been suffered. God will destroy the
locusts, still impending on the land, and restore the years which His
great army has eaten. There follows in vv. 28–32 (Eng.; Heb. chap,
iii.) the promise of a great outpouring of the Spirit on all Israel, amid
terrible manifestations in heaven and earth.

1. THE RETURN OF PROSPERITY (ii. 19–27).


And Jehovah answered and said to His people:
Lo, I will send you corn and wine and oil,
And your fill shall ye have of them;
And I will not again make you a reproach among
the heathen.
And the Northern Foe[1222] will I remove far
from you;
And I will push him into a land barren and waste,
His van to the eastern sea and his rear to the
western,[1223]
Till the stench of him rises,[1224]
Because he hath done greatly.

Locusts disappear with the same suddenness as they arrive. A


wind springs up and they are gone.[1225] Dead Sea and
Mediterranean are at the extremes of the compass, but there is no
reason to suppose that the prophet has abandoned the realism
which has hitherto distinguished his treatment of the locusts. The
plague covered the whole land, on whose high watershed the winds
suddenly veer and change. The dispersion of the locusts upon the
deserts and the opposite seas was therefore possible at one and the
same time. Jerome vouches for an instance in his own day. The
other detail is also true to life. Jerome says that the beaches of the
two seas were strewn with putrifying locusts, and Augustine[1226]
quotes heathen writers in evidence of large masses of locusts, driven
from Africa upon the sea, and then cast up on the shore, which gave
rise to a pestilence. “The south and east winds,” says Volney of
Syria, “drive the clouds of locusts with violence into the
Mediterranean, and drown them in such quantities, that when their
dead are cast on the shore they infect the air to a great
distance.”[1227] The prophet continues, celebrating this destruction of
the locusts as if it were already realised—the Lord hath done greatly,
ver. 21. That among the blessings he mentions a full supply of rain
proves that we were right in interpreting him to have spoken of
drought as accompanying the locusts.[1228]
Fear not, O Land! Rejoice and be glad,
For Jehovah hath done greatly.[1229]
Fear not, O beasts of the field!
For the pastures of the steppes are springing with
new grass,
The trees bear their fruit,
Fig-tree and vine yield their substance.
O sons of Zion, be glad,
And rejoice in Jehovah your God:
For He hath given you the early rain in
normal measure,[1230]
And poured[1231] on you winter rain[1232] and latter
rain as before[1233].
And the threshing-floors shall be full of wheat,
And the vats stream over with new wine and oil.
And I will restore to you the years which the
Swarmer has eaten,
The Lapper, the Devourer and the Shearer,
My great army whom I sent among you.
And ye shall eat your food and be full,
And praise the Name of Jehovah your God,
Who hath dealt so wondrously with you;
And My people shall be abashed nevermore.
Ye shall know I am in the midst of Israel,
That I am Jehovah your God and none else;
And nevermore shall My people be abashed.

You might also like