{"id":456,"date":"2024-10-13T22:47:40","date_gmt":"2024-10-13T14:47:40","guid":{"rendered":"https:\/\/www.hyy.net\/?p=456"},"modified":"2024-10-13T22:47:40","modified_gmt":"2024-10-13T14:47:40","slug":"c-12-and-net-8-modern-cross-platform-development-fundamentals","status":"publish","type":"post","link":"https:\/\/diji.net\/?p=456","title":{"rendered":"C# 12 and .NET 8 \u2013 Modern Cross- Platform Development Fundamentals"},"content":{"rendered":"<style type=\"text\/css\">\n.c0-consolepackt {\n  display: block;\n  font-family: Georgia, Cambria, \"Times New Roman\", Times, serif;\n}\n.calibre {\n  display: block;\n  font-size: 1em;\n  margin-bottom: 0;\n  margin-left: 5pt;\n  margin-right: 5pt;\n  margin-top: 0;\n  padding-left: 0;\n  padding-right: 0;\n}\n.calibre1 {\n  display: block;\n}\n.calibre2 {\n  font-weight: bold;\n}\n.calibre3 {\n  display: list-item;\n}\n.calibre4 {\n  display: block;\n  font-family: Georgia, Cambria, \"Times New Roman\", Times, serif;\n  page-break-after: always;\n}\n.calibre5 {\n  -epub-hyphens: none;\n  display: block;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n  font-size: 1.66667em;\n  font-weight: 300;\n  line-height: 1.2;\n  margin-bottom: 0.83em;\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 0.83em;\n}\n.calibre6 {\n  height: auto;\n  margin-left: auto;\n  margin-right: auto;\n  margin-top: 1rem;\n  max-width: 100%;\n  page-break-before: auto;\n  page-break-inside: avoid;\n  text-align: center;\n  width: 10em;\n}\n.calibre7 {\n  display: block;\n  list-style-type: disc;\n  margin-bottom: 1em;\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 1em;\n}\n.calibre8 {\n  -epub-hyphens: none;\n  display: block;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n  font-size: 1.29167em;\n  font-weight: 300;\n  line-height: 1.2;\n  margin-bottom: 1em;\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 1em;\n}\n.calibre9 {\n  font-family: monospace;\n  margin-bottom: 0;\n  margin-left: 0.2rem;\n  margin-right: 0.2rem;\n  margin-top: 0;\n  white-space: nowrap;\n}\n.calibre10 {\n  font-style: italic;\n}\n.calibre11 {\n  margin-left: auto;\n  margin-right: auto;\n  max-width: 100%;\n  text-align: center;\n  width: 100%;\n}\n.calibre12 {\n  height: auto;\n  margin-left: auto;\n  margin-right: auto;\n  margin-top: 1rem;\n  max-width: 100%;\n  page-break-before: auto;\n  page-break-inside: avoid;\n  text-align: center;\n  width: 100%;\n}\n.calibre13 {\n  font-style: italic;\n  text-align: center;\n}\n.calibre14 {\n  display: block;\n  margin-bottom: 1em;\n  margin-left: 1em;\n  margin-right: 1em;\n  margin-top: 1em;\n}\n.calibre15 {\n  -epub-hyphens: none;\n  display: block;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n  font-weight: 300;\n  margin-bottom: 1.33em;\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 1.33em;\n}\n.calibre16 {\n  display: block;\n  list-style-type: circle;\n  margin-bottom: 0;\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 0;\n}\n.calibre17 {\n  border-collapse: separate;\n  border-spacing: 2px;\n  display: table;\n  margin-bottom: 0;\n  margin-top: 0;\n  text-indent: 0;\n}\n.calibre18 {\n  display: table-column-group;\n}\n.calibre19 {\n  display: table-column;\n  width: 50%;\n}\n.calibre20 {\n  display: table-row-group;\n  vertical-align: middle;\n}\n.calibre21 {\n  display: table-cell;\n  padding-bottom: 1px;\n  padding-left: 1px;\n  padding-right: 1px;\n  padding-top: 1px;\n  text-align: inherit;\n  vertical-align: inherit;\n}\n.calibre22 {\n  display: block;\n  font-family: monospace;\n  margin-bottom: 1em;\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 1em;\n  white-space: pre-wrap;\n}\n.calibre23 {\n  display: block;\n  font-family: monospace;\n  margin-bottom: 0;\n  margin-left: 0.2rem;\n  margin-right: 0.2rem;\n  margin-top: 0;\n  white-space: pre;\n}\n.calibre24 {\n  margin-left: -2.5em;\n  margin-right: auto;\n  max-width: 100%;\n  text-align: center;\n  width: 100%;\n}\n.calibre25 {\n  display: table-column;\n  width: 33%;\n}\n.calibre26 {\n  font-size: 0.75em;\n  line-height: normal;\n  vertical-align: super;\n}\n.odd {\n  display: table-row;\n  vertical-align: top;\n}\n.rights {\n  -epub-hyphens: none;\n  display: block;\n  margin-bottom: 1em;\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 1em;\n}\n.title {\n  -epub-hyphens: none;\n  display: block;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n  font-size: 2em;\n  font-weight: 300;\n  line-height: 1.2;\n  margin-bottom: 0.67em;\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 0.67em;\n}\n.toc {\n  display: block;\n  list-style-type: decimal;\n  margin-bottom: 1em;\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 1em;\n}\n.toc1 {\n  display: block;\n  list-style-type: upper-roman;\n  margin-bottom: 0;\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 0;\n}\n.toc2 {\n  display: block;\n  list-style-type: lower-roman;\n  margin-bottom: 0;\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 0;\n}<\/p>\n<p>@page {\n  margin-bottom: 5pt;\n  margin-top: 5pt;\n}<\/p>\n<\/style>\n<p><title>C# 12 and .NET 8 Modern Cross-Platform Development Fundamentals<\/title><\/p>\n<div class=\"calibre\" id=\"calibre_link-7\">\n<div id=\"calibre_link-942\" class=\"calibre1\">\n<section type=\"titlepage\">\n<h1 class=\"title\">C# 12 and .NET 8 &ndash; Modern Cross-Platform Development Fundamentals<\/h1>\n<p class=\"rights\">Copyright \u00a9 2023 Packt Publishing<\/p>\n<p class=\"rights\">All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.<\/p>\n<p class=\"rights\">Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.<\/p>\n<p class=\"rights\">Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.<\/p>\n<p class=\"rights\"><strong class=\"calibre2\">Early Access Publication<\/strong>: C# 12 and .NET 8 &ndash; Modern Cross-Platform Development Fundamentals<\/p>\n<p class=\"rights\"><strong class=\"calibre2\">Early Access Production Reference<\/strong>: B19586<\/p>\n<p class=\"rights\">Published by Packt Publishing Ltd.<\/p>\n<p class=\"rights\">Livery Place<\/p>\n<p class=\"rights\">35 Livery Street<\/p>\n<p class=\"rights\">Birmingham<\/p>\n<p class=\"rights\">B3 2PB, UK<\/p>\n<p class=\"rights\"><strong class=\"calibre2\">ISBN<\/strong>: 978-1-83763-587-0<\/p>\n<p><a href=\"https:\/\/www.packt.com\">www.packt.com<\/a><br \/>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-10\">\n<div id=\"calibre_link-943\" class=\"calibre1\">\n<nav type=\"toc\" id=\"calibre_link-931\">\n<h1 id=\"calibre_link-944\" class=\"title\">Table of Contents<\/h1>\n<ol class=\"toc\">\n<li id=\"calibre_link-945\" class=\"calibre3\"><a href=\"\/#calibre_link-11\">C# 12 and .NET 8 &ndash; Modern Cross-Platform Development Fundamentals, Eighth Edition: Start building websites and services with ASP.NET Core 8, Blazor, and EF Core 8<\/a><\/li>\n<li id=\"calibre_link-946\" class=\"calibre3\"><a href=\"\/#calibre_link-12\">1 Hello, C#! Welcome, .NET!<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-947\" class=\"calibre3\"><a href=\"\/#calibre_link-13\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-948\" class=\"calibre3\"><a href=\"\/#calibre_link-14\">Introducing this book and its contents<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-949\" class=\"calibre3\"><a href=\"\/#calibre_link-15\">Getting code solutions for this book<\/a><\/li>\n<li id=\"calibre_link-950\" class=\"calibre3\"><a href=\"\/#calibre_link-16\">.NET terms used in this book<\/a><\/li>\n<li id=\"calibre_link-951\" class=\"calibre3\"><a href=\"\/#calibre_link-17\">The structure and style of this book<\/a><\/li>\n<li id=\"calibre_link-952\" class=\"calibre3\"><a href=\"\/#calibre_link-18\">Topics covered by this book<\/a><\/li>\n<li id=\"calibre_link-953\" class=\"calibre3\"><a href=\"\/#calibre_link-19\">Topics covered by Apps and Services with .NET 8<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-954\" class=\"calibre3\"><a href=\"\/#calibre_link-20\">Setting up your development environment<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-955\" class=\"calibre3\"><a href=\"\/#calibre_link-21\">Choosing the appropriate tool and application type for learning<\/a><\/li>\n<li id=\"calibre_link-956\" class=\"calibre3\"><a href=\"\/#calibre_link-22\">Deploying cross-platform<\/a><\/li>\n<li id=\"calibre_link-957\" class=\"calibre3\"><a href=\"\/#calibre_link-23\">Downloading and installing Visual Studio 2022<\/a><\/li>\n<li id=\"calibre_link-958\" class=\"calibre3\"><a href=\"\/#calibre_link-24\">Downloading and installing Visual Studio Code<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-959\" class=\"calibre3\"><a href=\"\/#calibre_link-25\">Understanding .NET<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-960\" class=\"calibre3\"><a href=\"\/#calibre_link-26\">Understanding .NET support<\/a><\/li>\n<li id=\"calibre_link-961\" class=\"calibre3\"><a href=\"\/#calibre_link-27\">Understanding .NET support phases<\/a><\/li>\n<li id=\"calibre_link-962\" class=\"calibre3\"><a href=\"\/#calibre_link-28\">Understanding .NET Runtime and .NET SDK versions<\/a><\/li>\n<li id=\"calibre_link-963\" class=\"calibre3\"><a href=\"\/#calibre_link-29\">Listing and removing versions of .NET<\/a><\/li>\n<li id=\"calibre_link-964\" class=\"calibre3\"><a href=\"\/#calibre_link-30\">Understanding intermediate language<\/a><\/li>\n<li id=\"calibre_link-965\" class=\"calibre3\"><a href=\"\/#calibre_link-31\">Comparing .NET technologies<\/a><\/li>\n<li id=\"calibre_link-966\" class=\"calibre3\"><a href=\"\/#calibre_link-32\">Managing multiple projects using code editors<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-967\" class=\"calibre3\"><a href=\"\/#calibre_link-33\">Building console apps using Visual Studio 2022<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-968\" class=\"calibre3\"><a href=\"\/#calibre_link-34\">Writing code using Visual Studio 2022<\/a><\/li>\n<li id=\"calibre_link-969\" class=\"calibre3\"><a href=\"\/#calibre_link-35\">Compiling and running code using Visual Studio<\/a><\/li>\n<li id=\"calibre_link-970\" class=\"calibre3\"><a href=\"\/#calibre_link-36\">Understanding the compiler-generated folders and files<\/a><\/li>\n<li id=\"calibre_link-971\" class=\"calibre3\"><a href=\"\/#calibre_link-37\">Understanding top-level programs<\/a><\/li>\n<li id=\"calibre_link-972\" class=\"calibre3\"><a href=\"\/#calibre_link-38\">Requirements for top-level programs<\/a><\/li>\n<li id=\"calibre_link-973\" class=\"calibre3\"><a href=\"\/#calibre_link-39\">Implicitly imported namespaces<\/a><\/li>\n<li id=\"calibre_link-974\" class=\"calibre3\"><a href=\"\/#calibre_link-40\">Revealing the hidden code by throwing an exception<\/a><\/li>\n<li id=\"calibre_link-975\" class=\"calibre3\"><a href=\"\/#calibre_link-41\">Revealing the namespace for the Program class<\/a><\/li>\n<li id=\"calibre_link-976\" class=\"calibre3\"><a href=\"\/#calibre_link-42\">Adding a second project using Visual Studio 2022<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-977\" class=\"calibre3\"><a href=\"\/#calibre_link-43\">Building console apps using Visual Studio Code<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-978\" class=\"calibre3\"><a href=\"\/#calibre_link-44\">Writing code using Visual Studio Code<\/a><\/li>\n<li id=\"calibre_link-979\" class=\"calibre3\"><a href=\"\/#calibre_link-45\">Compiling and running code using the dotnet CLI<\/a><\/li>\n<li id=\"calibre_link-980\" class=\"calibre3\"><a href=\"\/#calibre_link-46\">Adding a second project using Visual Studio Code<\/a><\/li>\n<li id=\"calibre_link-981\" class=\"calibre3\"><a href=\"\/#calibre_link-47\">Summary of steps for Visual Studio Code<\/a><\/li>\n<li id=\"calibre_link-982\" class=\"calibre3\"><a href=\"\/#calibre_link-48\">Summary of other project types used in this book<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-983\" class=\"calibre3\"><a href=\"\/#calibre_link-49\">Making good use of the GitHub repository for this book<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-984\" class=\"calibre3\"><a href=\"\/#calibre_link-50\">Understanding the solution code on GitHub<\/a><\/li>\n<li id=\"calibre_link-985\" class=\"calibre3\"><a href=\"\/#calibre_link-51\">Raising issues with the book<\/a><\/li>\n<li id=\"calibre_link-986\" class=\"calibre3\"><a href=\"\/#calibre_link-52\">Giving me feedback<\/a><\/li>\n<li id=\"calibre_link-987\" class=\"calibre3\"><a href=\"\/#calibre_link-53\">Avoiding common mistakes<\/a><\/li>\n<li id=\"calibre_link-988\" class=\"calibre3\"><a href=\"\/#calibre_link-54\">Downloading solution code from the GitHub repository<\/a><\/li>\n<li id=\"calibre_link-989\" class=\"calibre3\"><a href=\"\/#calibre_link-55\">Using Git with Visual Studio Code and the command prompt<\/a><\/li>\n<li id=\"calibre_link-990\" class=\"calibre3\"><a href=\"\/#calibre_link-56\">Cloning the book solution code repository<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-991\" class=\"calibre3\"><a href=\"\/#calibre_link-57\">Looking for help<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-992\" class=\"calibre3\"><a href=\"\/#calibre_link-58\">Reading the documentation on Microsoft Learn<\/a><\/li>\n<li id=\"calibre_link-993\" class=\"calibre3\"><a href=\"\/#calibre_link-59\">Documentation links in this book<\/a><\/li>\n<li id=\"calibre_link-994\" class=\"calibre3\"><a href=\"\/#calibre_link-60\">Getting help for the dotnet tool<\/a><\/li>\n<li id=\"calibre_link-995\" class=\"calibre3\"><a href=\"\/#calibre_link-61\">Getting definitions of types and their members<\/a><\/li>\n<li id=\"calibre_link-996\" class=\"calibre3\"><a href=\"\/#calibre_link-62\">Configuring inline aka inlay hints<\/a><\/li>\n<li id=\"calibre_link-997\" class=\"calibre3\"><a href=\"\/#calibre_link-63\">Looking for answers on Stack Overflow<\/a><\/li>\n<li id=\"calibre_link-998\" class=\"calibre3\"><a href=\"\/#calibre_link-64\">Searching for answers using Google<\/a><\/li>\n<li id=\"calibre_link-999\" class=\"calibre3\"><a href=\"\/#calibre_link-65\">Searching the .NET source code<\/a><\/li>\n<li id=\"calibre_link-1000\" class=\"calibre3\"><a href=\"\/#calibre_link-66\">Subscribing to the official .NET blog<\/a><\/li>\n<li id=\"calibre_link-1001\" class=\"calibre3\"><a href=\"\/#calibre_link-67\">Watching Scott Hanselman's videos<\/a><\/li>\n<li id=\"calibre_link-1002\" class=\"calibre3\"><a href=\"\/#calibre_link-68\">AI tools like ChatGPT and GitHub Copilot<\/a><\/li>\n<li id=\"calibre_link-1003\" class=\"calibre3\"><a href=\"\/#calibre_link-69\">Disabling tools when they get in the way<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1004\" class=\"calibre3\"><a href=\"\/#calibre_link-70\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1005\" class=\"calibre3\"><a href=\"\/#calibre_link-71\">Exercise 1.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1006\" class=\"calibre3\"><a href=\"\/#calibre_link-72\">Exercise 1.2 &ndash; Practice C# anywhere with a browser<\/a><\/li>\n<li id=\"calibre_link-1007\" class=\"calibre3\"><a href=\"\/#calibre_link-73\">Exercise 1.3 &ndash; Explore topics<\/a><\/li>\n<li id=\"calibre_link-1008\" class=\"calibre3\"><a href=\"\/#calibre_link-74\">Exercise 1.4 &ndash; Explore Polyglot Notebooks<\/a><\/li>\n<li id=\"calibre_link-1009\" class=\"calibre3\"><a href=\"\/#calibre_link-75\">Exercise 1.5 &ndash; Explore themes of modern .NET<\/a><\/li>\n<li id=\"calibre_link-1010\" class=\"calibre3\"><a href=\"\/#calibre_link-76\">Exercise 1.6 &ndash; Free Code Camp and C# Certification<\/a><\/li>\n<li id=\"calibre_link-1011\" class=\"calibre3\"><a href=\"\/#calibre_link-77\">Exercise 1.7 &ndash; Alpha versions of .NET<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1012\" class=\"calibre3\"><a href=\"\/#calibre_link-78\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1013\" class=\"calibre3\"><a href=\"\/#calibre_link-79\">2 Speaking C#<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1014\" class=\"calibre3\"><a href=\"\/#calibre_link-80\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1015\" class=\"calibre3\"><a href=\"\/#calibre_link-81\">Introducing the C# language<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1016\" class=\"calibre3\"><a href=\"\/#calibre_link-82\">C# language versions and features<\/a><\/li>\n<li id=\"calibre_link-1017\" class=\"calibre3\"><a href=\"\/#calibre_link-83\">Understanding C# standards<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1018\" class=\"calibre3\"><a href=\"\/#calibre_link-84\">Discovering your C# compiler version<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1019\" class=\"calibre3\"><a href=\"\/#calibre_link-85\">How to output the SDK version<\/a><\/li>\n<li id=\"calibre_link-1020\" class=\"calibre3\"><a href=\"\/#calibre_link-86\">Enabling a specific language version compiler<\/a><\/li>\n<li id=\"calibre_link-1021\" class=\"calibre3\"><a href=\"\/#calibre_link-87\">Using future C# compiler versions<\/a><\/li>\n<li id=\"calibre_link-1022\" class=\"calibre3\"><a href=\"\/#calibre_link-88\">Switching the C# compiler for .NET 8 to a future version<\/a><\/li>\n<li id=\"calibre_link-1023\" class=\"calibre3\"><a href=\"\/#calibre_link-89\">Showing the compiler version<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1024\" class=\"calibre3\"><a href=\"\/#calibre_link-90\">Understanding C# grammar and vocabulary<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1025\" class=\"calibre3\"><a href=\"\/#calibre_link-91\">Understanding C# grammar<\/a><\/li>\n<li id=\"calibre_link-1026\" class=\"calibre3\"><a href=\"\/#calibre_link-92\">Statements<\/a><\/li>\n<li id=\"calibre_link-1027\" class=\"calibre3\"><a href=\"\/#calibre_link-93\">Comments<\/a><\/li>\n<li id=\"calibre_link-1028\" class=\"calibre3\"><a href=\"\/#calibre_link-94\">Blocks<\/a><\/li>\n<li id=\"calibre_link-1029\" class=\"calibre3\"><a href=\"\/#calibre_link-95\">Regions<\/a><\/li>\n<li id=\"calibre_link-1030\" class=\"calibre3\"><a href=\"\/#calibre_link-96\">Examples of statements and blocks<\/a><\/li>\n<li id=\"calibre_link-1031\" class=\"calibre3\"><a href=\"\/#calibre_link-97\">Formatting code using white space<\/a><\/li>\n<li id=\"calibre_link-1032\" class=\"calibre3\"><a href=\"\/#calibre_link-98\">Understanding C# vocabulary<\/a><\/li>\n<li id=\"calibre_link-1033\" class=\"calibre3\"><a href=\"\/#calibre_link-99\">Comparing programming languages to human languages<\/a><\/li>\n<li id=\"calibre_link-1034\" class=\"calibre3\"><a href=\"\/#calibre_link-100\">Changing the color scheme for C# syntax<\/a><\/li>\n<li id=\"calibre_link-1035\" class=\"calibre3\"><a href=\"\/#calibre_link-101\">Help for writing correct code<\/a><\/li>\n<li id=\"calibre_link-1036\" class=\"calibre3\"><a href=\"\/#calibre_link-102\">Importing namespaces<\/a><\/li>\n<li id=\"calibre_link-1037\" class=\"calibre3\"><a href=\"\/#calibre_link-103\">Implicitly and globally importing namespaces<\/a><\/li>\n<li id=\"calibre_link-1038\" class=\"calibre3\"><a href=\"\/#calibre_link-104\">Verbs are methods<\/a><\/li>\n<li id=\"calibre_link-1039\" class=\"calibre3\"><a href=\"\/#calibre_link-105\">Nouns are types, variables, fields, and properties<\/a><\/li>\n<li id=\"calibre_link-1040\" class=\"calibre3\"><a href=\"\/#calibre_link-106\">Revealing the extent of the C# vocabulary<\/a><\/li>\n<li id=\"calibre_link-1041\" class=\"calibre3\"><a href=\"\/#calibre_link-107\">Example of asking ChatGPT to explain code<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1042\" class=\"calibre3\"><a href=\"\/#calibre_link-108\">Working with variables<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1043\" class=\"calibre3\"><a href=\"\/#calibre_link-109\">Naming things and assigning values<\/a><\/li>\n<li id=\"calibre_link-1044\" class=\"calibre3\"><a href=\"\/#calibre_link-110\">Literal values<\/a><\/li>\n<li id=\"calibre_link-1045\" class=\"calibre3\"><a href=\"\/#calibre_link-111\">Storing text<\/a><\/li>\n<li id=\"calibre_link-1046\" class=\"calibre3\"><a href=\"\/#calibre_link-112\">Storing numbers<\/a><\/li>\n<li id=\"calibre_link-1047\" class=\"calibre3\"><a href=\"\/#calibre_link-113\">Storing real numbers<\/a><\/li>\n<li id=\"calibre_link-1048\" class=\"calibre3\"><a href=\"\/#calibre_link-114\">Storing Booleans<\/a><\/li>\n<li id=\"calibre_link-1049\" class=\"calibre3\"><a href=\"\/#calibre_link-115\">Storing any type of object<\/a><\/li>\n<li id=\"calibre_link-1050\" class=\"calibre3\"><a href=\"\/#calibre_link-116\">Storing dynamic types<\/a><\/li>\n<li id=\"calibre_link-1051\" class=\"calibre3\"><a href=\"\/#calibre_link-117\">Declaring local variables<\/a><\/li>\n<li id=\"calibre_link-1052\" class=\"calibre3\"><a href=\"\/#calibre_link-118\">Getting and setting the default values for types<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1053\" class=\"calibre3\"><a href=\"\/#calibre_link-119\">Exploring more about console apps<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1054\" class=\"calibre3\"><a href=\"\/#calibre_link-120\">Displaying output to the user<\/a><\/li>\n<li id=\"calibre_link-1055\" class=\"calibre3\"><a href=\"\/#calibre_link-121\">Getting text input from the user<\/a><\/li>\n<li id=\"calibre_link-1056\" class=\"calibre3\"><a href=\"\/#calibre_link-122\">Simplifying the usage of the console<\/a><\/li>\n<li id=\"calibre_link-1057\" class=\"calibre3\"><a href=\"\/#calibre_link-123\">Getting key input from the user<\/a><\/li>\n<li id=\"calibre_link-1058\" class=\"calibre3\"><a href=\"\/#calibre_link-124\">Passing arguments to a console app<\/a><\/li>\n<li id=\"calibre_link-1059\" class=\"calibre3\"><a href=\"\/#calibre_link-125\">Setting options with arguments<\/a><\/li>\n<li id=\"calibre_link-1060\" class=\"calibre3\"><a href=\"\/#calibre_link-126\">Handling platforms that do not support an API<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1061\" class=\"calibre3\"><a href=\"\/#calibre_link-127\">Understanding async and await<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1062\" class=\"calibre3\"><a href=\"\/#calibre_link-128\">Improving responsiveness for console apps<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1063\" class=\"calibre3\"><a href=\"\/#calibre_link-129\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1064\" class=\"calibre3\"><a href=\"\/#calibre_link-130\">Exercise 2.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1065\" class=\"calibre3\"><a href=\"\/#calibre_link-131\">Exercise 2.2 &ndash; Test your knowledge of number types<\/a><\/li>\n<li id=\"calibre_link-1066\" class=\"calibre3\"><a href=\"\/#calibre_link-132\">Exercise 2.3 &ndash; Practice number sizes and ranges<\/a><\/li>\n<li id=\"calibre_link-1067\" class=\"calibre3\"><a href=\"\/#calibre_link-133\">Exercise 2.4 &ndash; Explore topics<\/a><\/li>\n<li id=\"calibre_link-1068\" class=\"calibre3\"><a href=\"\/#calibre_link-134\">Exercise 2.5 &ndash; Explore Spectre<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1069\" class=\"calibre3\"><a href=\"\/#calibre_link-135\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1070\" class=\"calibre3\"><a href=\"\/#calibre_link-136\">3 Controlling Flow, Converting Types, and Handling Exceptions<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1071\" class=\"calibre3\"><a href=\"\/#calibre_link-137\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1072\" class=\"calibre3\"><a href=\"\/#calibre_link-138\">Operating on variables<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1073\" class=\"calibre3\"><a href=\"\/#calibre_link-139\">Understanding binary operators<\/a><\/li>\n<li id=\"calibre_link-1074\" class=\"calibre3\"><a href=\"\/#calibre_link-140\">Understanding unary operators<\/a><\/li>\n<li id=\"calibre_link-1075\" class=\"calibre3\"><a href=\"\/#calibre_link-141\">Understanding ternary operators<\/a><\/li>\n<li id=\"calibre_link-1076\" class=\"calibre3\"><a href=\"\/#calibre_link-142\">Exploring unary operators<\/a><\/li>\n<li id=\"calibre_link-1077\" class=\"calibre3\"><a href=\"\/#calibre_link-143\">Exploring binary arithmetic operators<\/a><\/li>\n<li id=\"calibre_link-1078\" class=\"calibre3\"><a href=\"\/#calibre_link-144\">Assignment operators<\/a><\/li>\n<li id=\"calibre_link-1079\" class=\"calibre3\"><a href=\"\/#calibre_link-145\">Null-coalescing operators<\/a><\/li>\n<li id=\"calibre_link-1080\" class=\"calibre3\"><a href=\"\/#calibre_link-146\">Exploring logical operators<\/a><\/li>\n<li id=\"calibre_link-1081\" class=\"calibre3\"><a href=\"\/#calibre_link-147\">Exploring conditional logical operators<\/a><\/li>\n<li id=\"calibre_link-1082\" class=\"calibre3\"><a href=\"\/#calibre_link-148\">Exploring bitwise and binary shift operators<\/a><\/li>\n<li id=\"calibre_link-1083\" class=\"calibre3\"><a href=\"\/#calibre_link-149\">Miscellaneous operators<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1084\" class=\"calibre3\"><a href=\"\/#calibre_link-150\">Understanding selection statements<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1085\" class=\"calibre3\"><a href=\"\/#calibre_link-151\">Branching with the if statement<\/a><\/li>\n<li id=\"calibre_link-1086\" class=\"calibre3\"><a href=\"\/#calibre_link-152\">Why you should always use braces with if statements<\/a><\/li>\n<li id=\"calibre_link-1087\" class=\"calibre3\"><a href=\"\/#calibre_link-153\">Pattern matching with the if statement<\/a><\/li>\n<li id=\"calibre_link-1088\" class=\"calibre3\"><a href=\"\/#calibre_link-154\">Branching with the switch statement<\/a><\/li>\n<li id=\"calibre_link-1089\" class=\"calibre3\"><a href=\"\/#calibre_link-155\">Adding a new item to a project using Visual Studio 2022<\/a><\/li>\n<li id=\"calibre_link-1090\" class=\"calibre3\"><a href=\"\/#calibre_link-156\">Pattern matching with the switch statement<\/a><\/li>\n<li id=\"calibre_link-1091\" class=\"calibre3\"><a href=\"\/#calibre_link-157\">Simplifying switch statements with switch expressions<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1092\" class=\"calibre3\"><a href=\"\/#calibre_link-158\">Understanding iteration statements<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1093\" class=\"calibre3\"><a href=\"\/#calibre_link-159\">Looping with the while statement<\/a><\/li>\n<li id=\"calibre_link-1094\" class=\"calibre3\"><a href=\"\/#calibre_link-160\">Looping with the do statement<\/a><\/li>\n<li id=\"calibre_link-1095\" class=\"calibre3\"><a href=\"\/#calibre_link-161\">Looping with the for statement<\/a><\/li>\n<li id=\"calibre_link-1096\" class=\"calibre3\"><a href=\"\/#calibre_link-162\">Looping with the foreach statement<\/a><\/li>\n<li id=\"calibre_link-1097\" class=\"calibre3\"><a href=\"\/#calibre_link-163\">Understanding how foreach works internally<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1098\" class=\"calibre3\"><a href=\"\/#calibre_link-164\">Storing multiple values in an array<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1099\" class=\"calibre3\"><a href=\"\/#calibre_link-165\">Working with single-dimensional arrays<\/a><\/li>\n<li id=\"calibre_link-1100\" class=\"calibre3\"><a href=\"\/#calibre_link-166\">Working with multi-dimensional arrays<\/a><\/li>\n<li id=\"calibre_link-1101\" class=\"calibre3\"><a href=\"\/#calibre_link-167\">Working with jagged arrays<\/a><\/li>\n<li id=\"calibre_link-1102\" class=\"calibre3\"><a href=\"\/#calibre_link-168\">List pattern matching with arrays<\/a><\/li>\n<li id=\"calibre_link-1103\" class=\"calibre3\"><a href=\"\/#calibre_link-169\">Understanding inline arrays<\/a><\/li>\n<li id=\"calibre_link-1104\" class=\"calibre3\"><a href=\"\/#calibre_link-170\">Summarizing arrays<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1105\" class=\"calibre3\"><a href=\"\/#calibre_link-171\">Casting and converting between types<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1106\" class=\"calibre3\"><a href=\"\/#calibre_link-172\">Casting numbers implicitly and explicitly<\/a><\/li>\n<li id=\"calibre_link-1107\" class=\"calibre3\"><a href=\"\/#calibre_link-173\">How negative numbers are represented in binary<\/a><\/li>\n<li id=\"calibre_link-1108\" class=\"calibre3\"><a href=\"\/#calibre_link-174\">Converting with the System.Convert type<\/a><\/li>\n<li id=\"calibre_link-1109\" class=\"calibre3\"><a href=\"\/#calibre_link-175\">Rounding numbers and the default rounding rules<\/a><\/li>\n<li id=\"calibre_link-1110\" class=\"calibre3\"><a href=\"\/#calibre_link-176\">Taking control of rounding rules<\/a><\/li>\n<li id=\"calibre_link-1111\" class=\"calibre3\"><a href=\"\/#calibre_link-177\">Converting from any type to a string<\/a><\/li>\n<li id=\"calibre_link-1112\" class=\"calibre3\"><a href=\"\/#calibre_link-178\">Converting from a binary object to a string<\/a><\/li>\n<li id=\"calibre_link-1113\" class=\"calibre3\"><a href=\"\/#calibre_link-179\">Parsing from strings to numbers or dates and times<\/a><\/li>\n<li id=\"calibre_link-1114\" class=\"calibre3\"><a href=\"\/#calibre_link-180\">Avoiding Parse exceptions by using the TryParse method<\/a><\/li>\n<li id=\"calibre_link-1115\" class=\"calibre3\"><a href=\"\/#calibre_link-181\">Understanding the Try method naming convention<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1116\" class=\"calibre3\"><a href=\"\/#calibre_link-182\">Handling exceptions<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1117\" class=\"calibre3\"><a href=\"\/#calibre_link-183\">Wrapping error-prone code in a try block<\/a><\/li>\n<li id=\"calibre_link-1118\" class=\"calibre3\"><a href=\"\/#calibre_link-184\">Catching all exceptions<\/a><\/li>\n<li id=\"calibre_link-1119\" class=\"calibre3\"><a href=\"\/#calibre_link-185\">Catching specific exceptions<\/a><\/li>\n<li id=\"calibre_link-1120\" class=\"calibre3\"><a href=\"\/#calibre_link-186\">Catching with filters<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1121\" class=\"calibre3\"><a href=\"\/#calibre_link-187\">Checking for overflow<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1122\" class=\"calibre3\"><a href=\"\/#calibre_link-188\">Throwing overflow exceptions with the checked statement<\/a><\/li>\n<li id=\"calibre_link-1123\" class=\"calibre3\"><a href=\"\/#calibre_link-189\">Disabling compiler overflow checks with the unchecked statement<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1124\" class=\"calibre3\"><a href=\"\/#calibre_link-190\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1125\" class=\"calibre3\"><a href=\"\/#calibre_link-191\">Exercise 3.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1126\" class=\"calibre3\"><a href=\"\/#calibre_link-192\">Exercise 3.2 &ndash; Explore loops and overflow<\/a><\/li>\n<li id=\"calibre_link-1127\" class=\"calibre3\"><a href=\"\/#calibre_link-193\">Exercise 3.3 &ndash; Test your knowledge of operators<\/a><\/li>\n<li id=\"calibre_link-1128\" class=\"calibre3\"><a href=\"\/#calibre_link-194\">Exercise 3.4 &ndash; Practice loops and operators<\/a><\/li>\n<li id=\"calibre_link-1129\" class=\"calibre3\"><a href=\"\/#calibre_link-195\">Exercise 3.5 &ndash; Practice exception handling<\/a><\/li>\n<li id=\"calibre_link-1130\" class=\"calibre3\"><a href=\"\/#calibre_link-196\">Exercise 3.6 &ndash; Explore C# 101 notebooks<\/a><\/li>\n<li id=\"calibre_link-1131\" class=\"calibre3\"><a href=\"\/#calibre_link-197\">Exercise 3.7 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1132\" class=\"calibre3\"><a href=\"\/#calibre_link-198\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1133\" class=\"calibre3\"><a href=\"\/#calibre_link-199\">4 Writing, Debugging, and Testing Functions<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1134\" class=\"calibre3\"><a href=\"\/#calibre_link-200\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1135\" class=\"calibre3\"><a href=\"\/#calibre_link-201\">Writing functions<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1136\" class=\"calibre3\"><a href=\"\/#calibre_link-202\">Exploring top-level programs, functions, and namespaces<\/a><\/li>\n<li id=\"calibre_link-1137\" class=\"calibre3\"><a href=\"\/#calibre_link-203\">Defining a partial Program class with a static function<\/a><\/li>\n<li id=\"calibre_link-1138\" class=\"calibre3\"><a href=\"\/#calibre_link-204\">Times table example<\/a><\/li>\n<li id=\"calibre_link-1139\" class=\"calibre3\"><a href=\"\/#calibre_link-205\">A brief aside about arguments and parameters<\/a><\/li>\n<li id=\"calibre_link-1140\" class=\"calibre3\"><a href=\"\/#calibre_link-206\">Writing a function that returns a value<\/a><\/li>\n<li id=\"calibre_link-1141\" class=\"calibre3\"><a href=\"\/#calibre_link-207\">Converting numbers from cardinal to ordinal<\/a><\/li>\n<li id=\"calibre_link-1142\" class=\"calibre3\"><a href=\"\/#calibre_link-208\">Calculating factorials with recursion<\/a><\/li>\n<li id=\"calibre_link-1143\" class=\"calibre3\"><a href=\"\/#calibre_link-209\">Documenting functions with XML comments<\/a><\/li>\n<li id=\"calibre_link-1144\" class=\"calibre3\"><a href=\"\/#calibre_link-210\">Using lambdas in function implementations<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1145\" class=\"calibre3\"><a href=\"\/#calibre_link-211\">Debugging during development<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1146\" class=\"calibre3\"><a href=\"\/#calibre_link-212\">Creating code with a deliberate bug<\/a><\/li>\n<li id=\"calibre_link-1147\" class=\"calibre3\"><a href=\"\/#calibre_link-213\">Setting a breakpoint and starting debugging<\/a><\/li>\n<li id=\"calibre_link-1148\" class=\"calibre3\"><a href=\"\/#calibre_link-214\">Navigating with the debugging toolbar<\/a><\/li>\n<li id=\"calibre_link-1149\" class=\"calibre3\"><a href=\"\/#calibre_link-215\">Debugging windows<\/a><\/li>\n<li id=\"calibre_link-1150\" class=\"calibre3\"><a href=\"\/#calibre_link-216\">Stepping through code<\/a><\/li>\n<li id=\"calibre_link-1151\" class=\"calibre3\"><a href=\"\/#calibre_link-217\">Using the Visual Studio Code integrated terminal during debugging<\/a><\/li>\n<li id=\"calibre_link-1152\" class=\"calibre3\"><a href=\"\/#calibre_link-218\">Customizing breakpoints<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1153\" class=\"calibre3\"><a href=\"\/#calibre_link-219\">Hot reloading during development<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1154\" class=\"calibre3\"><a href=\"\/#calibre_link-220\">Hot reloading using Visual Studio 2022<\/a><\/li>\n<li id=\"calibre_link-1155\" class=\"calibre3\"><a href=\"\/#calibre_link-221\">Hot reloading using Visual Studio Code and dotnet watch<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1156\" class=\"calibre3\"><a href=\"\/#calibre_link-222\">Logging during development and runtime<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1157\" class=\"calibre3\"><a href=\"\/#calibre_link-223\">Understanding logging options<\/a><\/li>\n<li id=\"calibre_link-1158\" class=\"calibre3\"><a href=\"\/#calibre_link-224\">Instrumenting with Debug and Trace<\/a><\/li>\n<li id=\"calibre_link-1159\" class=\"calibre3\"><a href=\"\/#calibre_link-225\">Configuring trace listeners<\/a><\/li>\n<li id=\"calibre_link-1160\" class=\"calibre3\"><a href=\"\/#calibre_link-226\">Switching trace levels<\/a><\/li>\n<li id=\"calibre_link-1161\" class=\"calibre3\"><a href=\"\/#calibre_link-227\">Logging information about your source code<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1162\" class=\"calibre3\"><a href=\"\/#calibre_link-228\">Unit testing<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1163\" class=\"calibre3\"><a href=\"\/#calibre_link-229\">Understanding types of testing<\/a><\/li>\n<li id=\"calibre_link-1164\" class=\"calibre3\"><a href=\"\/#calibre_link-230\">Creating a class library that needs testing<\/a><\/li>\n<li id=\"calibre_link-1165\" class=\"calibre3\"><a href=\"\/#calibre_link-231\">Writing unit tests<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1166\" class=\"calibre3\"><a href=\"\/#calibre_link-232\">Throwing and catching exceptions in functions<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1167\" class=\"calibre3\"><a href=\"\/#calibre_link-233\">Understanding usage errors and execution errors<\/a><\/li>\n<li id=\"calibre_link-1168\" class=\"calibre3\"><a href=\"\/#calibre_link-234\">Commonly thrown exceptions in functions<\/a><\/li>\n<li id=\"calibre_link-1169\" class=\"calibre3\"><a href=\"\/#calibre_link-235\">Throwing exceptions using guard clauses<\/a><\/li>\n<li id=\"calibre_link-1170\" class=\"calibre3\"><a href=\"\/#calibre_link-236\">Understanding the call stack<\/a><\/li>\n<li id=\"calibre_link-1171\" class=\"calibre3\"><a href=\"\/#calibre_link-237\">Where to catch exceptions<\/a><\/li>\n<li id=\"calibre_link-1172\" class=\"calibre3\"><a href=\"\/#calibre_link-238\">Rethrowing exceptions<\/a><\/li>\n<li id=\"calibre_link-1173\" class=\"calibre3\"><a href=\"\/#calibre_link-239\">Implementing the tester-doer and try patterns<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1174\" class=\"calibre3\"><a href=\"\/#calibre_link-240\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1175\" class=\"calibre3\"><a href=\"\/#calibre_link-241\">Exercise 4.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1176\" class=\"calibre3\"><a href=\"\/#calibre_link-242\">Exercise 4.2 &ndash; Practice writing functions with debugging and unit testing<\/a><\/li>\n<li id=\"calibre_link-1177\" class=\"calibre3\"><a href=\"\/#calibre_link-243\">Exercise 4.3 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1178\" class=\"calibre3\"><a href=\"\/#calibre_link-244\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1179\" class=\"calibre3\"><a href=\"\/#calibre_link-245\">5 Building Your Own Types with Object-Oriented Programming<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1180\" class=\"calibre3\"><a href=\"\/#calibre_link-246\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1181\" class=\"calibre3\"><a href=\"\/#calibre_link-247\">Talking about OOP<\/a><\/li>\n<li id=\"calibre_link-1182\" class=\"calibre3\"><a href=\"\/#calibre_link-248\">Building class libraries<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1183\" class=\"calibre3\"><a href=\"\/#calibre_link-249\">Creating a class library<\/a><\/li>\n<li id=\"calibre_link-1184\" class=\"calibre3\"><a href=\"\/#calibre_link-250\">Understanding file-scoped namespaces<\/a><\/li>\n<li id=\"calibre_link-1185\" class=\"calibre3\"><a href=\"\/#calibre_link-251\">Defining a class in a namespace<\/a><\/li>\n<li id=\"calibre_link-1186\" class=\"calibre3\"><a href=\"\/#calibre_link-252\">Understanding type access modifiers<\/a><\/li>\n<li id=\"calibre_link-1187\" class=\"calibre3\"><a href=\"\/#calibre_link-253\">Understanding members<\/a><\/li>\n<li id=\"calibre_link-1188\" class=\"calibre3\"><a href=\"\/#calibre_link-254\">Importing a namespace to use a type<\/a><\/li>\n<li id=\"calibre_link-1189\" class=\"calibre3\"><a href=\"\/#calibre_link-255\">Instantiating a class<\/a><\/li>\n<li id=\"calibre_link-1190\" class=\"calibre3\"><a href=\"\/#calibre_link-256\">Inheriting from System.Object<\/a><\/li>\n<li id=\"calibre_link-1191\" class=\"calibre3\"><a href=\"\/#calibre_link-257\">Avoiding a namespace conflict with a using alias<\/a><\/li>\n<li id=\"calibre_link-1192\" class=\"calibre3\"><a href=\"\/#calibre_link-258\">Renaming a type with a using alias<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1193\" class=\"calibre3\"><a href=\"\/#calibre_link-259\">Storing data in fields<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1194\" class=\"calibre3\"><a href=\"\/#calibre_link-260\">Defining fields<\/a><\/li>\n<li id=\"calibre_link-1195\" class=\"calibre3\"><a href=\"\/#calibre_link-261\">Types for fields<\/a><\/li>\n<li id=\"calibre_link-1196\" class=\"calibre3\"><a href=\"\/#calibre_link-262\">Member access modifiers<\/a><\/li>\n<li id=\"calibre_link-1197\" class=\"calibre3\"><a href=\"\/#calibre_link-263\">Setting and outputting field values<\/a><\/li>\n<li id=\"calibre_link-1198\" class=\"calibre3\"><a href=\"\/#calibre_link-264\">Setting field values using object initializer syntax<\/a><\/li>\n<li id=\"calibre_link-1199\" class=\"calibre3\"><a href=\"\/#calibre_link-265\">Storing a value using an enum type<\/a><\/li>\n<li id=\"calibre_link-1200\" class=\"calibre3\"><a href=\"\/#calibre_link-266\">Storing multiple values using an enum type<\/a><\/li>\n<li id=\"calibre_link-1201\" class=\"calibre3\"><a href=\"\/#calibre_link-267\">Storing multiple values using collections<\/a><\/li>\n<li id=\"calibre_link-1202\" class=\"calibre3\"><a href=\"\/#calibre_link-268\">Understanding generic collections<\/a><\/li>\n<li id=\"calibre_link-1203\" class=\"calibre3\"><a href=\"\/#calibre_link-269\">Making a field static<\/a><\/li>\n<li id=\"calibre_link-1204\" class=\"calibre3\"><a href=\"\/#calibre_link-270\">Making a field constant<\/a><\/li>\n<li id=\"calibre_link-1205\" class=\"calibre3\"><a href=\"\/#calibre_link-271\">Making a field read-only<\/a><\/li>\n<li id=\"calibre_link-1206\" class=\"calibre3\"><a href=\"\/#calibre_link-272\">Requiring fields to be set during instantiation<\/a><\/li>\n<li id=\"calibre_link-1207\" class=\"calibre3\"><a href=\"\/#calibre_link-273\">Initializing fields with constructors<\/a><\/li>\n<li id=\"calibre_link-1208\" class=\"calibre3\"><a href=\"\/#calibre_link-274\">Defining multiple constructors<\/a><\/li>\n<li id=\"calibre_link-1209\" class=\"calibre3\"><a href=\"\/#calibre_link-275\">Setting required fields with a constructor<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1210\" class=\"calibre3\"><a href=\"\/#calibre_link-276\">Working with methods and tuples<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1211\" class=\"calibre3\"><a href=\"\/#calibre_link-277\">Returning values from methods<\/a><\/li>\n<li id=\"calibre_link-1212\" class=\"calibre3\"><a href=\"\/#calibre_link-278\">Defining and passing parameters to methods<\/a><\/li>\n<li id=\"calibre_link-1213\" class=\"calibre3\"><a href=\"\/#calibre_link-279\">Overloading methods<\/a><\/li>\n<li id=\"calibre_link-1214\" class=\"calibre3\"><a href=\"\/#calibre_link-280\">Passing optional parameters<\/a><\/li>\n<li id=\"calibre_link-1215\" class=\"calibre3\"><a href=\"\/#calibre_link-281\">Naming parameter values when calling methods<\/a><\/li>\n<li id=\"calibre_link-1216\" class=\"calibre3\"><a href=\"\/#calibre_link-282\">Mixing optional and required parameters<\/a><\/li>\n<li id=\"calibre_link-1217\" class=\"calibre3\"><a href=\"\/#calibre_link-283\">Controlling how parameters are passed<\/a><\/li>\n<li id=\"calibre_link-1218\" class=\"calibre3\"><a href=\"\/#calibre_link-284\">Understanding ref returns<\/a><\/li>\n<li id=\"calibre_link-1219\" class=\"calibre3\"><a href=\"\/#calibre_link-285\">Combining multiple returned values using tuples<\/a><\/li>\n<li id=\"calibre_link-1220\" class=\"calibre3\"><a href=\"\/#calibre_link-286\">Naming the fields of a tuple<\/a><\/li>\n<li id=\"calibre_link-1221\" class=\"calibre3\"><a href=\"\/#calibre_link-287\">Aliasing tuples<\/a><\/li>\n<li id=\"calibre_link-1222\" class=\"calibre3\"><a href=\"\/#calibre_link-288\">Deconstructing tuples<\/a><\/li>\n<li id=\"calibre_link-1223\" class=\"calibre3\"><a href=\"\/#calibre_link-289\">Deconstructing other types using tuples<\/a><\/li>\n<li id=\"calibre_link-1224\" class=\"calibre3\"><a href=\"\/#calibre_link-290\">Implementing functionality using local functions<\/a><\/li>\n<li id=\"calibre_link-1225\" class=\"calibre3\"><a href=\"\/#calibre_link-291\">Splitting classes using partial<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1226\" class=\"calibre3\"><a href=\"\/#calibre_link-292\">Controlling access with properties and indexers<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1227\" class=\"calibre3\"><a href=\"\/#calibre_link-293\">Defining read-only properties<\/a><\/li>\n<li id=\"calibre_link-1228\" class=\"calibre3\"><a href=\"\/#calibre_link-294\">Defining settable properties<\/a><\/li>\n<li id=\"calibre_link-1229\" class=\"calibre3\"><a href=\"\/#calibre_link-295\">Limiting flags enum values<\/a><\/li>\n<li id=\"calibre_link-1230\" class=\"calibre3\"><a href=\"\/#calibre_link-296\">Defining indexers<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1231\" class=\"calibre3\"><a href=\"\/#calibre_link-297\">Pattern matching with objects<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1232\" class=\"calibre3\"><a href=\"\/#calibre_link-298\">Pattern-matching flight passengers<\/a><\/li>\n<li id=\"calibre_link-1233\" class=\"calibre3\"><a href=\"\/#calibre_link-299\">Enhancements to pattern matching in C# 9 or later<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1234\" class=\"calibre3\"><a href=\"\/#calibre_link-300\">Working with record types<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1235\" class=\"calibre3\"><a href=\"\/#calibre_link-301\">Init-only properties<\/a><\/li>\n<li id=\"calibre_link-1236\" class=\"calibre3\"><a href=\"\/#calibre_link-302\">Defining record types<\/a><\/li>\n<li id=\"calibre_link-1237\" class=\"calibre3\"><a href=\"\/#calibre_link-303\">Equality of record types<\/a><\/li>\n<li id=\"calibre_link-1238\" class=\"calibre3\"><a href=\"\/#calibre_link-304\">Positional data members in records<\/a><\/li>\n<li id=\"calibre_link-1239\" class=\"calibre3\"><a href=\"\/#calibre_link-305\">Defining a primary constructor for a class<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1240\" class=\"calibre3\"><a href=\"\/#calibre_link-306\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1241\" class=\"calibre3\"><a href=\"\/#calibre_link-307\">Exercise 5.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1242\" class=\"calibre3\"><a href=\"\/#calibre_link-308\">Exercise 5.2 &ndash; Practice with access modifiers<\/a><\/li>\n<li id=\"calibre_link-1243\" class=\"calibre3\"><a href=\"\/#calibre_link-309\">Exercise 5.3 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1244\" class=\"calibre3\"><a href=\"\/#calibre_link-310\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1245\" class=\"calibre3\"><a href=\"\/#calibre_link-311\">6 Implementing Interfaces and Inheriting Classes<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1246\" class=\"calibre3\"><a href=\"\/#calibre_link-312\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1247\" class=\"calibre3\"><a href=\"\/#calibre_link-313\">Setting up a class library and console application<\/a><\/li>\n<li id=\"calibre_link-1248\" class=\"calibre3\"><a href=\"\/#calibre_link-314\">Static methods and overloading operators<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1249\" class=\"calibre3\"><a href=\"\/#calibre_link-315\">Implementing functionality using methods<\/a><\/li>\n<li id=\"calibre_link-1250\" class=\"calibre3\"><a href=\"\/#calibre_link-316\">Implementing functionality using operators<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1251\" class=\"calibre3\"><a href=\"\/#calibre_link-317\">Making types safely reusable with generics<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1252\" class=\"calibre3\"><a href=\"\/#calibre_link-318\">Working with non-generic types<\/a><\/li>\n<li id=\"calibre_link-1253\" class=\"calibre3\"><a href=\"\/#calibre_link-319\">Working with generic types<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1254\" class=\"calibre3\"><a href=\"\/#calibre_link-320\">Raising and handling events<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1255\" class=\"calibre3\"><a href=\"\/#calibre_link-321\">Calling methods using delegates<\/a><\/li>\n<li id=\"calibre_link-1256\" class=\"calibre3\"><a href=\"\/#calibre_link-322\">Examples of delegate use<\/a><\/li>\n<li id=\"calibre_link-1257\" class=\"calibre3\"><a href=\"\/#calibre_link-323\">Status: It's complicated<\/a><\/li>\n<li id=\"calibre_link-1258\" class=\"calibre3\"><a href=\"\/#calibre_link-324\">Defining and handling delegates<\/a><\/li>\n<li id=\"calibre_link-1259\" class=\"calibre3\"><a href=\"\/#calibre_link-325\">Defining and handling events<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1260\" class=\"calibre3\"><a href=\"\/#calibre_link-326\">Implementing interfaces<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1261\" class=\"calibre3\"><a href=\"\/#calibre_link-327\">Common interfaces<\/a><\/li>\n<li id=\"calibre_link-1262\" class=\"calibre3\"><a href=\"\/#calibre_link-328\">Comparing objects when sorting<\/a><\/li>\n<li id=\"calibre_link-1263\" class=\"calibre3\"><a href=\"\/#calibre_link-329\">Comparing objects using a separate class<\/a><\/li>\n<li id=\"calibre_link-1264\" class=\"calibre3\"><a href=\"\/#calibre_link-330\">Implicit and explicit interface implementations<\/a><\/li>\n<li id=\"calibre_link-1265\" class=\"calibre3\"><a href=\"\/#calibre_link-331\">Defining interfaces with default implementations<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1266\" class=\"calibre3\"><a href=\"\/#calibre_link-332\">Managing memory with reference and value types<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1267\" class=\"calibre3\"><a href=\"\/#calibre_link-333\">Understanding stack and heap memory<\/a><\/li>\n<li id=\"calibre_link-1268\" class=\"calibre3\"><a href=\"\/#calibre_link-334\">Defining reference and value types<\/a><\/li>\n<li id=\"calibre_link-1269\" class=\"calibre3\"><a href=\"\/#calibre_link-335\">How reference and value types are stored in memory<\/a><\/li>\n<li id=\"calibre_link-1270\" class=\"calibre3\"><a href=\"\/#calibre_link-336\">Understanding boxing<\/a><\/li>\n<li id=\"calibre_link-1271\" class=\"calibre3\"><a href=\"\/#calibre_link-337\">Equality of types<\/a><\/li>\n<li id=\"calibre_link-1272\" class=\"calibre3\"><a href=\"\/#calibre_link-338\">Defining struct types<\/a><\/li>\n<li id=\"calibre_link-1273\" class=\"calibre3\"><a href=\"\/#calibre_link-339\">Defining record struct types<\/a><\/li>\n<li id=\"calibre_link-1274\" class=\"calibre3\"><a href=\"\/#calibre_link-340\">Releasing unmanaged resources<\/a><\/li>\n<li id=\"calibre_link-1275\" class=\"calibre3\"><a href=\"\/#calibre_link-341\">Ensuring that Dispose is called<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1276\" class=\"calibre3\"><a href=\"\/#calibre_link-342\">Working with null values<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1277\" class=\"calibre3\"><a href=\"\/#calibre_link-343\">Making a value type nullable<\/a><\/li>\n<li id=\"calibre_link-1278\" class=\"calibre3\"><a href=\"\/#calibre_link-344\">Understanding null-related initialisms<\/a><\/li>\n<li id=\"calibre_link-1279\" class=\"calibre3\"><a href=\"\/#calibre_link-345\">Understanding nullable reference types<\/a><\/li>\n<li id=\"calibre_link-1280\" class=\"calibre3\"><a href=\"\/#calibre_link-346\">Controlling the nullability warning check feature<\/a><\/li>\n<li id=\"calibre_link-1281\" class=\"calibre3\"><a href=\"\/#calibre_link-347\">Disabling null and other compiler warnings<\/a><\/li>\n<li id=\"calibre_link-1282\" class=\"calibre3\"><a href=\"\/#calibre_link-348\">Declaring non-nullable variables and parameters<\/a><\/li>\n<li id=\"calibre_link-1283\" class=\"calibre3\"><a href=\"\/#calibre_link-349\">Checking for null<\/a><\/li>\n<li id=\"calibre_link-1284\" class=\"calibre3\"><a href=\"\/#calibre_link-350\">Checking for null in method parameters<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1285\" class=\"calibre3\"><a href=\"\/#calibre_link-351\">Inheriting from classes<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1286\" class=\"calibre3\"><a href=\"\/#calibre_link-352\">Extending classes to add functionality<\/a><\/li>\n<li id=\"calibre_link-1287\" class=\"calibre3\"><a href=\"\/#calibre_link-353\">Hiding members<\/a><\/li>\n<li id=\"calibre_link-1288\" class=\"calibre3\"><a href=\"\/#calibre_link-354\">Understanding this and base keywords<\/a><\/li>\n<li id=\"calibre_link-1289\" class=\"calibre3\"><a href=\"\/#calibre_link-355\">Overriding members<\/a><\/li>\n<li id=\"calibre_link-1290\" class=\"calibre3\"><a href=\"\/#calibre_link-356\">Inheriting from abstract classes<\/a><\/li>\n<li id=\"calibre_link-1291\" class=\"calibre3\"><a href=\"\/#calibre_link-357\">Choosing between an interface and an abstract class<\/a><\/li>\n<li id=\"calibre_link-1292\" class=\"calibre3\"><a href=\"\/#calibre_link-358\">Preventing inheritance and overriding<\/a><\/li>\n<li id=\"calibre_link-1293\" class=\"calibre3\"><a href=\"\/#calibre_link-359\">Understanding polymorphism<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1294\" class=\"calibre3\"><a href=\"\/#calibre_link-360\">Casting within inheritance hierarchies<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1295\" class=\"calibre3\"><a href=\"\/#calibre_link-361\">Implicit casting<\/a><\/li>\n<li id=\"calibre_link-1296\" class=\"calibre3\"><a href=\"\/#calibre_link-362\">Explicit casting<\/a><\/li>\n<li id=\"calibre_link-1297\" class=\"calibre3\"><a href=\"\/#calibre_link-363\">Avoiding casting exceptions<\/a><\/li>\n<li id=\"calibre_link-1298\" class=\"calibre3\"><a href=\"\/#calibre_link-364\">Using is to check a type<\/a><\/li>\n<li id=\"calibre_link-1299\" class=\"calibre3\"><a href=\"\/#calibre_link-365\">Using as to cast a type<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1300\" class=\"calibre3\"><a href=\"\/#calibre_link-366\">Inheriting and extending .NET types<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1301\" class=\"calibre3\"><a href=\"\/#calibre_link-367\">Inheriting exceptions<\/a><\/li>\n<li id=\"calibre_link-1302\" class=\"calibre3\"><a href=\"\/#calibre_link-368\">Extending types when you can't inherit<\/a><\/li>\n<li id=\"calibre_link-1303\" class=\"calibre3\"><a href=\"\/#calibre_link-369\">Using static methods to reuse functionality<\/a><\/li>\n<li id=\"calibre_link-1304\" class=\"calibre3\"><a href=\"\/#calibre_link-370\">Using extension methods to reuse functionality<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1305\" class=\"calibre3\"><a href=\"\/#calibre_link-371\">Summarizing custom type choices<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1306\" class=\"calibre3\"><a href=\"\/#calibre_link-372\">Categories of custom type and their capabilities<\/a><\/li>\n<li id=\"calibre_link-1307\" class=\"calibre3\"><a href=\"\/#calibre_link-373\">Mutability and records<\/a><\/li>\n<li id=\"calibre_link-1308\" class=\"calibre3\"><a href=\"\/#calibre_link-374\">Comparing inheritance and implementation<\/a><\/li>\n<li id=\"calibre_link-1309\" class=\"calibre3\"><a href=\"\/#calibre_link-375\">Reviewing illustrative code<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1310\" class=\"calibre3\"><a href=\"\/#calibre_link-376\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1311\" class=\"calibre3\"><a href=\"\/#calibre_link-377\">Exercise 6.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1312\" class=\"calibre3\"><a href=\"\/#calibre_link-378\">Exercise 6.2 &ndash; Practice creating an inheritance hierarchy<\/a><\/li>\n<li id=\"calibre_link-1313\" class=\"calibre3\"><a href=\"\/#calibre_link-379\">Exercise 6.3 &ndash; Writing better code<\/a><\/li>\n<li id=\"calibre_link-1314\" class=\"calibre3\"><a href=\"\/#calibre_link-380\">Exercise 6.4 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1315\" class=\"calibre3\"><a href=\"\/#calibre_link-381\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1316\" class=\"calibre3\"><a href=\"\/#calibre_link-382\">7 Packaging and Distributing .NET Types<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1317\" class=\"calibre3\"><a href=\"\/#calibre_link-383\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1318\" class=\"calibre3\"><a href=\"\/#calibre_link-384\">The road to .NET 8<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1319\" class=\"calibre3\"><a href=\"\/#calibre_link-385\">.NET Core 1.0, June 2016<\/a><\/li>\n<li id=\"calibre_link-1320\" class=\"calibre3\"><a href=\"\/#calibre_link-386\">.NET Core 1.1, November 2016<\/a><\/li>\n<li id=\"calibre_link-1321\" class=\"calibre3\"><a href=\"\/#calibre_link-387\">.NET Core 2.0, August 2017<\/a><\/li>\n<li id=\"calibre_link-1322\" class=\"calibre3\"><a href=\"\/#calibre_link-388\">.NET Core 2.1, May 2018<\/a><\/li>\n<li id=\"calibre_link-1323\" class=\"calibre3\"><a href=\"\/#calibre_link-389\">.NET Core 2.2, December 2018<\/a><\/li>\n<li id=\"calibre_link-1324\" class=\"calibre3\"><a href=\"\/#calibre_link-390\">.NET Core 3.0, September 2019<\/a><\/li>\n<li id=\"calibre_link-1325\" class=\"calibre3\"><a href=\"\/#calibre_link-391\">.NET Core 3.1, December 2019<\/a><\/li>\n<li id=\"calibre_link-1326\" class=\"calibre3\"><a href=\"\/#calibre_link-392\">.NET 5, November 2020<\/a><\/li>\n<li id=\"calibre_link-1327\" class=\"calibre3\"><a href=\"\/#calibre_link-393\">.NET 6, November 2021<\/a><\/li>\n<li id=\"calibre_link-1328\" class=\"calibre3\"><a href=\"\/#calibre_link-394\">.NET 7, November 2022<\/a><\/li>\n<li id=\"calibre_link-1329\" class=\"calibre3\"><a href=\"\/#calibre_link-395\">.NET 8, November 2023<\/a><\/li>\n<li id=\"calibre_link-1330\" class=\"calibre3\"><a href=\"\/#calibre_link-396\">Checking your .NET SDKs for updates<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1331\" class=\"calibre3\"><a href=\"\/#calibre_link-397\">Understanding .NET components<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1332\" class=\"calibre3\"><a href=\"\/#calibre_link-398\">Assemblies, NuGet packages, and namespaces<\/a><\/li>\n<li id=\"calibre_link-1333\" class=\"calibre3\"><a href=\"\/#calibre_link-399\">What is a namespace?<\/a><\/li>\n<li id=\"calibre_link-1334\" class=\"calibre3\"><a href=\"\/#calibre_link-400\">Dependent assemblies<\/a><\/li>\n<li id=\"calibre_link-1335\" class=\"calibre3\"><a href=\"\/#calibre_link-401\">Microsoft .NET project SDKs<\/a><\/li>\n<li id=\"calibre_link-1336\" class=\"calibre3\"><a href=\"\/#calibre_link-402\">Namespaces and types in assemblies<\/a><\/li>\n<li id=\"calibre_link-1337\" class=\"calibre3\"><a href=\"\/#calibre_link-403\">NuGet packages<\/a><\/li>\n<li id=\"calibre_link-1338\" class=\"calibre3\"><a href=\"\/#calibre_link-404\">Understanding frameworks<\/a><\/li>\n<li id=\"calibre_link-1339\" class=\"calibre3\"><a href=\"\/#calibre_link-405\">Importing a namespace to use a type<\/a><\/li>\n<li id=\"calibre_link-1340\" class=\"calibre3\"><a href=\"\/#calibre_link-406\">Relating C# keywords to .NET types<\/a><\/li>\n<li id=\"calibre_link-1341\" class=\"calibre3\"><a href=\"\/#calibre_link-407\">Mapping C# aliases to .NET types<\/a><\/li>\n<li id=\"calibre_link-1342\" class=\"calibre3\"><a href=\"\/#calibre_link-408\">Understanding native-sized integers<\/a><\/li>\n<li id=\"calibre_link-1343\" class=\"calibre3\"><a href=\"\/#calibre_link-409\">Revealing the location of a type<\/a><\/li>\n<li id=\"calibre_link-1344\" class=\"calibre3\"><a href=\"\/#calibre_link-410\">Sharing code with legacy platforms using .NET Standard<\/a><\/li>\n<li id=\"calibre_link-1345\" class=\"calibre3\"><a href=\"\/#calibre_link-411\">Understanding defaults for class libraries with different SDKs<\/a><\/li>\n<li id=\"calibre_link-1346\" class=\"calibre3\"><a href=\"\/#calibre_link-412\">Creating a .NET Standard class library<\/a><\/li>\n<li id=\"calibre_link-1347\" class=\"calibre3\"><a href=\"\/#calibre_link-413\">Controlling the .NET SDK<\/a><\/li>\n<li id=\"calibre_link-1348\" class=\"calibre3\"><a href=\"\/#calibre_link-414\">Mixing SDKs and framework targets<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1349\" class=\"calibre3\"><a href=\"\/#calibre_link-415\">Publishing your code for deployment<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1350\" class=\"calibre3\"><a href=\"\/#calibre_link-416\">Creating a console app to publish<\/a><\/li>\n<li id=\"calibre_link-1351\" class=\"calibre3\"><a href=\"\/#calibre_link-417\">Understanding dotnet commands<\/a><\/li>\n<li id=\"calibre_link-1352\" class=\"calibre3\"><a href=\"\/#calibre_link-418\">Getting information about .NET and its environment<\/a><\/li>\n<li id=\"calibre_link-1353\" class=\"calibre3\"><a href=\"\/#calibre_link-419\">Managing projects using the dotnet CLI<\/a><\/li>\n<li id=\"calibre_link-1354\" class=\"calibre3\"><a href=\"\/#calibre_link-420\">Publishing a self-contained app<\/a><\/li>\n<li id=\"calibre_link-1355\" class=\"calibre3\"><a href=\"\/#calibre_link-421\">Publishing a single-file app<\/a><\/li>\n<li id=\"calibre_link-1356\" class=\"calibre3\"><a href=\"\/#calibre_link-422\">Reducing the size of apps using app trimming<\/a><\/li>\n<li id=\"calibre_link-1357\" class=\"calibre3\"><a href=\"\/#calibre_link-423\">Controlling where build artifacts are created<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1358\" class=\"calibre3\"><a href=\"\/#calibre_link-424\">Native ahead-of-time compilation<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1359\" class=\"calibre3\"><a href=\"\/#calibre_link-425\">Limitations of native AOT<\/a><\/li>\n<li id=\"calibre_link-1360\" class=\"calibre3\"><a href=\"\/#calibre_link-426\">Reflection and native AOT<\/a><\/li>\n<li id=\"calibre_link-1361\" class=\"calibre3\"><a href=\"\/#calibre_link-427\">Requirements for native AOT<\/a><\/li>\n<li id=\"calibre_link-1362\" class=\"calibre3\"><a href=\"\/#calibre_link-428\">Enabling native AOT for a project<\/a><\/li>\n<li id=\"calibre_link-1363\" class=\"calibre3\"><a href=\"\/#calibre_link-429\">Building a native AOT project<\/a><\/li>\n<li id=\"calibre_link-1364\" class=\"calibre3\"><a href=\"\/#calibre_link-430\">Publishing a native AOT project<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1365\" class=\"calibre3\"><a href=\"\/#calibre_link-431\">Decompiling .NET assemblies<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1366\" class=\"calibre3\"><a href=\"\/#calibre_link-432\">Decompiling using the ILSpy extension for Visual Studio 2022<\/a><\/li>\n<li id=\"calibre_link-1367\" class=\"calibre3\"><a href=\"\/#calibre_link-433\">Viewing source links with Visual Studio 2022<\/a><\/li>\n<li id=\"calibre_link-1368\" class=\"calibre3\"><a href=\"\/#calibre_link-434\">No, you cannot technically prevent decompilation<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1369\" class=\"calibre3\"><a href=\"\/#calibre_link-435\">Packaging your libraries for NuGet distribution<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1370\" class=\"calibre3\"><a href=\"\/#calibre_link-436\">Referencing a NuGet package<\/a><\/li>\n<li id=\"calibre_link-1371\" class=\"calibre3\"><a href=\"\/#calibre_link-437\">Fixing dependencies<\/a><\/li>\n<li id=\"calibre_link-1372\" class=\"calibre3\"><a href=\"\/#calibre_link-438\">Packaging a library for NuGet<\/a><\/li>\n<li id=\"calibre_link-1373\" class=\"calibre3\"><a href=\"\/#calibre_link-439\">Publishing a package to a public NuGet feed<\/a><\/li>\n<li id=\"calibre_link-1374\" class=\"calibre3\"><a href=\"\/#calibre_link-440\">Publishing a package to a private NuGet feed<\/a><\/li>\n<li id=\"calibre_link-1375\" class=\"calibre3\"><a href=\"\/#calibre_link-441\">Exploring NuGet packages with a tool<\/a><\/li>\n<li id=\"calibre_link-1376\" class=\"calibre3\"><a href=\"\/#calibre_link-442\">Testing your class library package<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1377\" class=\"calibre3\"><a href=\"\/#calibre_link-443\">Working with preview features<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1378\" class=\"calibre3\"><a href=\"\/#calibre_link-444\">Requiring preview features<\/a><\/li>\n<li id=\"calibre_link-1379\" class=\"calibre3\"><a href=\"\/#calibre_link-445\">Enabling preview features<\/a><\/li>\n<li id=\"calibre_link-1380\" class=\"calibre3\"><a href=\"\/#calibre_link-446\">Method interceptors<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1381\" class=\"calibre3\"><a href=\"\/#calibre_link-447\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1382\" class=\"calibre3\"><a href=\"\/#calibre_link-448\">Exercise 7.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1383\" class=\"calibre3\"><a href=\"\/#calibre_link-449\">Exercise 7.2 &ndash; Explore topics<\/a><\/li>\n<li id=\"calibre_link-1384\" class=\"calibre3\"><a href=\"\/#calibre_link-450\">Exercise 7.3 &ndash; Porting from .NET Framework to modern .NET<\/a><\/li>\n<li id=\"calibre_link-1385\" class=\"calibre3\"><a href=\"\/#calibre_link-451\">Exercise 7.4 &ndash; Creating source generators<\/a><\/li>\n<li id=\"calibre_link-1386\" class=\"calibre3\"><a href=\"\/#calibre_link-452\">Exercise 7.5 &ndash; Explore PowerShell<\/a><\/li>\n<li id=\"calibre_link-1387\" class=\"calibre3\"><a href=\"\/#calibre_link-453\">Exercise 7.6 &ndash; Improving performance in .NET<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1388\" class=\"calibre3\"><a href=\"\/#calibre_link-454\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1389\" class=\"calibre3\"><a href=\"\/#calibre_link-455\">8 Working with Common .NET Types<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1390\" class=\"calibre3\"><a href=\"\/#calibre_link-456\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1391\" class=\"calibre3\"><a href=\"\/#calibre_link-457\">Working with numbers<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1392\" class=\"calibre3\"><a href=\"\/#calibre_link-458\">Working with big integers<\/a><\/li>\n<li id=\"calibre_link-1393\" class=\"calibre3\"><a href=\"\/#calibre_link-459\">Working with complex numbers<\/a><\/li>\n<li id=\"calibre_link-1394\" class=\"calibre3\"><a href=\"\/#calibre_link-460\">Generating random numbers for games and similar apps<\/a><\/li>\n<li id=\"calibre_link-1395\" class=\"calibre3\"><a href=\"\/#calibre_link-461\">Generating GUIDs<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1396\" class=\"calibre3\"><a href=\"\/#calibre_link-462\">Working with text<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1397\" class=\"calibre3\"><a href=\"\/#calibre_link-463\">Getting the length of a string<\/a><\/li>\n<li id=\"calibre_link-1398\" class=\"calibre3\"><a href=\"\/#calibre_link-464\">Getting the characters of a string<\/a><\/li>\n<li id=\"calibre_link-1399\" class=\"calibre3\"><a href=\"\/#calibre_link-465\">Splitting a string<\/a><\/li>\n<li id=\"calibre_link-1400\" class=\"calibre3\"><a href=\"\/#calibre_link-466\">Getting part of a string<\/a><\/li>\n<li id=\"calibre_link-1401\" class=\"calibre3\"><a href=\"\/#calibre_link-467\">Checking a string for content<\/a><\/li>\n<li id=\"calibre_link-1402\" class=\"calibre3\"><a href=\"\/#calibre_link-468\">Comparing string values<\/a><\/li>\n<li id=\"calibre_link-1403\" class=\"calibre3\"><a href=\"\/#calibre_link-469\">Joining, formatting, and other string members<\/a><\/li>\n<li id=\"calibre_link-1404\" class=\"calibre3\"><a href=\"\/#calibre_link-470\">Building strings efficiently<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1405\" class=\"calibre3\"><a href=\"\/#calibre_link-471\">Pattern matching with regular expressions<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1406\" class=\"calibre3\"><a href=\"\/#calibre_link-472\">Checking for digits entered as text<\/a><\/li>\n<li id=\"calibre_link-1407\" class=\"calibre3\"><a href=\"\/#calibre_link-473\">Regular expression performance improvements<\/a><\/li>\n<li id=\"calibre_link-1408\" class=\"calibre3\"><a href=\"\/#calibre_link-474\">Understanding the syntax of a regular expression<\/a><\/li>\n<li id=\"calibre_link-1409\" class=\"calibre3\"><a href=\"\/#calibre_link-475\">Examples of regular expressions<\/a><\/li>\n<li id=\"calibre_link-1410\" class=\"calibre3\"><a href=\"\/#calibre_link-476\">Splitting a complex comma-separated string<\/a><\/li>\n<li id=\"calibre_link-1411\" class=\"calibre3\"><a href=\"\/#calibre_link-477\">Activating regular expression syntax coloring<\/a><\/li>\n<li id=\"calibre_link-1412\" class=\"calibre3\"><a href=\"\/#calibre_link-478\">Improving regular expression performance with source generators<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1413\" class=\"calibre3\"><a href=\"\/#calibre_link-479\">Storing multiple objects in collections<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1414\" class=\"calibre3\"><a href=\"\/#calibre_link-480\">Common features of all collections<\/a><\/li>\n<li id=\"calibre_link-1415\" class=\"calibre3\"><a href=\"\/#calibre_link-481\">Working with lists<\/a><\/li>\n<li id=\"calibre_link-1416\" class=\"calibre3\"><a href=\"\/#calibre_link-482\">Working with dictionaries<\/a><\/li>\n<li id=\"calibre_link-1417\" class=\"calibre3\"><a href=\"\/#calibre_link-483\">Sets, stacks, and queues<\/a><\/li>\n<li id=\"calibre_link-1418\" class=\"calibre3\"><a href=\"\/#calibre_link-484\">Collection add and remove methods<\/a><\/li>\n<li id=\"calibre_link-1419\" class=\"calibre3\"><a href=\"\/#calibre_link-485\">Sorting collections<\/a><\/li>\n<li id=\"calibre_link-1420\" class=\"calibre3\"><a href=\"\/#calibre_link-486\">Specialized collections<\/a><\/li>\n<li id=\"calibre_link-1421\" class=\"calibre3\"><a href=\"\/#calibre_link-487\">Read-only, immutable, and frozen collections<\/a><\/li>\n<li id=\"calibre_link-1422\" class=\"calibre3\"><a href=\"\/#calibre_link-488\">Initializing collections using collection expressions<\/a><\/li>\n<li id=\"calibre_link-1423\" class=\"calibre3\"><a href=\"\/#calibre_link-489\">Good practice with collections<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1424\" class=\"calibre3\"><a href=\"\/#calibre_link-490\">Working with spans, indexes, and ranges<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1425\" class=\"calibre3\"><a href=\"\/#calibre_link-491\">Using memory efficiently using spans<\/a><\/li>\n<li id=\"calibre_link-1426\" class=\"calibre3\"><a href=\"\/#calibre_link-492\">Identifying positions with the Index type<\/a><\/li>\n<li id=\"calibre_link-1427\" class=\"calibre3\"><a href=\"\/#calibre_link-493\">Identifying ranges with the Range type<\/a><\/li>\n<li id=\"calibre_link-1428\" class=\"calibre3\"><a href=\"\/#calibre_link-494\">Using indexes, ranges, and spans<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1429\" class=\"calibre3\"><a href=\"\/#calibre_link-495\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1430\" class=\"calibre3\"><a href=\"\/#calibre_link-496\">Exercise 8.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1431\" class=\"calibre3\"><a href=\"\/#calibre_link-497\">Exercise 8.2 &ndash; Practice regular expressions<\/a><\/li>\n<li id=\"calibre_link-1432\" class=\"calibre3\"><a href=\"\/#calibre_link-498\">Exercise 8.3 &ndash; Practice writing extension methods<\/a><\/li>\n<li id=\"calibre_link-1433\" class=\"calibre3\"><a href=\"\/#calibre_link-499\">Exercise 8.4 &ndash; Working with network resources<\/a><\/li>\n<li id=\"calibre_link-1434\" class=\"calibre3\"><a href=\"\/#calibre_link-500\">Exercise 8.5 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1435\" class=\"calibre3\"><a href=\"\/#calibre_link-501\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1436\" class=\"calibre3\"><a href=\"\/#calibre_link-502\">9 Working with Files, Streams, and Serialization<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1437\" class=\"calibre3\"><a href=\"\/#calibre_link-503\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1438\" class=\"calibre3\"><a href=\"\/#calibre_link-504\">Managing the filesystem<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1439\" class=\"calibre3\"><a href=\"\/#calibre_link-505\">Handling cross-platform environments and filesystems<\/a><\/li>\n<li id=\"calibre_link-1440\" class=\"calibre3\"><a href=\"\/#calibre_link-506\">Managing drives<\/a><\/li>\n<li id=\"calibre_link-1441\" class=\"calibre3\"><a href=\"\/#calibre_link-507\">Managing directories<\/a><\/li>\n<li id=\"calibre_link-1442\" class=\"calibre3\"><a href=\"\/#calibre_link-508\">Managing files<\/a><\/li>\n<li id=\"calibre_link-1443\" class=\"calibre3\"><a href=\"\/#calibre_link-509\">Managing paths<\/a><\/li>\n<li id=\"calibre_link-1444\" class=\"calibre3\"><a href=\"\/#calibre_link-510\">Getting file information<\/a><\/li>\n<li id=\"calibre_link-1445\" class=\"calibre3\"><a href=\"\/#calibre_link-511\">Controlling how you work with files<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1446\" class=\"calibre3\"><a href=\"\/#calibre_link-512\">Reading and writing with streams<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1447\" class=\"calibre3\"><a href=\"\/#calibre_link-513\">Understanding abstract and concrete streams<\/a><\/li>\n<li id=\"calibre_link-1448\" class=\"calibre3\"><a href=\"\/#calibre_link-514\">Understanding storage streams<\/a><\/li>\n<li id=\"calibre_link-1449\" class=\"calibre3\"><a href=\"\/#calibre_link-515\">Understanding function streams<\/a><\/li>\n<li id=\"calibre_link-1450\" class=\"calibre3\"><a href=\"\/#calibre_link-516\">Understanding stream helpers<\/a><\/li>\n<li id=\"calibre_link-1451\" class=\"calibre3\"><a href=\"\/#calibre_link-517\">Building a stream pipeline<\/a><\/li>\n<li id=\"calibre_link-1452\" class=\"calibre3\"><a href=\"\/#calibre_link-518\">Writing to text streams<\/a><\/li>\n<li id=\"calibre_link-1453\" class=\"calibre3\"><a href=\"\/#calibre_link-519\">Writing to XML streams<\/a><\/li>\n<li id=\"calibre_link-1454\" class=\"calibre3\"><a href=\"\/#calibre_link-520\">Simplifying disposal by using the using statement<\/a><\/li>\n<li id=\"calibre_link-1455\" class=\"calibre3\"><a href=\"\/#calibre_link-521\">Compressing streams<\/a><\/li>\n<li id=\"calibre_link-1456\" class=\"calibre3\"><a href=\"\/#calibre_link-522\">Reading and writing with random access handles<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1457\" class=\"calibre3\"><a href=\"\/#calibre_link-523\">Encoding and decoding text<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1458\" class=\"calibre3\"><a href=\"\/#calibre_link-524\">Encoding strings as byte arrays<\/a><\/li>\n<li id=\"calibre_link-1459\" class=\"calibre3\"><a href=\"\/#calibre_link-525\">Encoding and decoding text in files<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1460\" class=\"calibre3\"><a href=\"\/#calibre_link-526\">Serializing object graphs<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1461\" class=\"calibre3\"><a href=\"\/#calibre_link-527\">Serializing as XML<\/a><\/li>\n<li id=\"calibre_link-1462\" class=\"calibre3\"><a href=\"\/#calibre_link-528\">Generating compact XML<\/a><\/li>\n<li id=\"calibre_link-1463\" class=\"calibre3\"><a href=\"\/#calibre_link-529\">Deserializing XML files<\/a><\/li>\n<li id=\"calibre_link-1464\" class=\"calibre3\"><a href=\"\/#calibre_link-530\">Serializing with JSON<\/a><\/li>\n<li id=\"calibre_link-1465\" class=\"calibre3\"><a href=\"\/#calibre_link-531\">High-performance JSON processing<\/a><\/li>\n<li id=\"calibre_link-1466\" class=\"calibre3\"><a href=\"\/#calibre_link-532\">Deserializing JSON files<\/a><\/li>\n<li id=\"calibre_link-1467\" class=\"calibre3\"><a href=\"\/#calibre_link-533\">Controlling JSON processing<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1468\" class=\"calibre3\"><a href=\"\/#calibre_link-534\">Working with environment variables<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1469\" class=\"calibre3\"><a href=\"\/#calibre_link-535\">Reading all environment variables<\/a><\/li>\n<li id=\"calibre_link-1470\" class=\"calibre3\"><a href=\"\/#calibre_link-536\">Expanding, setting, and getting an environment variables<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1471\" class=\"calibre3\"><a href=\"\/#calibre_link-537\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1472\" class=\"calibre3\"><a href=\"\/#calibre_link-538\">Exercise 9.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1473\" class=\"calibre3\"><a href=\"\/#calibre_link-539\">Exercise 9.2 &ndash; Practice serializing as XML<\/a><\/li>\n<li id=\"calibre_link-1474\" class=\"calibre3\"><a href=\"\/#calibre_link-540\">Exercise 9.3 &ndash; Working with Tar archives<\/a><\/li>\n<li id=\"calibre_link-1475\" class=\"calibre3\"><a href=\"\/#calibre_link-541\">Exercise 9.4 &ndash; Migrating from Newtonsoft to new JSON<\/a><\/li>\n<li id=\"calibre_link-1476\" class=\"calibre3\"><a href=\"\/#calibre_link-542\">Exercise 9.5 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1477\" class=\"calibre3\"><a href=\"\/#calibre_link-543\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1478\" class=\"calibre3\"><a href=\"\/#calibre_link-544\">10 Working with Data Using Entity Framework Core<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1479\" class=\"calibre3\"><a href=\"\/#calibre_link-545\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1480\" class=\"calibre3\"><a href=\"\/#calibre_link-546\">Understanding modern databases<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1481\" class=\"calibre3\"><a href=\"\/#calibre_link-547\">Understanding legacy Entity Framework<\/a><\/li>\n<li id=\"calibre_link-1482\" class=\"calibre3\"><a href=\"\/#calibre_link-548\">Using the legacy Entity Framework 6.3 or later<\/a><\/li>\n<li id=\"calibre_link-1483\" class=\"calibre3\"><a href=\"\/#calibre_link-549\">Understanding Entity Framework Core<\/a><\/li>\n<li id=\"calibre_link-1484\" class=\"calibre3\"><a href=\"\/#calibre_link-550\">Understanding Database First and Code First<\/a><\/li>\n<li id=\"calibre_link-1485\" class=\"calibre3\"><a href=\"\/#calibre_link-551\">Performance improvements in EF Core<\/a><\/li>\n<li id=\"calibre_link-1486\" class=\"calibre3\"><a href=\"\/#calibre_link-552\">Using a sample relational database<\/a><\/li>\n<li id=\"calibre_link-1487\" class=\"calibre3\"><a href=\"\/#calibre_link-553\">Using SQLite<\/a><\/li>\n<li id=\"calibre_link-1488\" class=\"calibre3\"><a href=\"\/#calibre_link-554\">Using SQL Server or other SQL systems<\/a><\/li>\n<li id=\"calibre_link-1489\" class=\"calibre3\"><a href=\"\/#calibre_link-555\">Setting up SQLite for Windows<\/a><\/li>\n<li id=\"calibre_link-1490\" class=\"calibre3\"><a href=\"\/#calibre_link-556\">Setting up SQLite for macOS and Linux<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1491\" class=\"calibre3\"><a href=\"\/#calibre_link-557\">Setting up EF Core in a .NET project<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1492\" class=\"calibre3\"><a href=\"\/#calibre_link-558\">Creating a console app for working with EF Core<\/a><\/li>\n<li id=\"calibre_link-1493\" class=\"calibre3\"><a href=\"\/#calibre_link-559\">Creating the Northwind sample database for SQLite<\/a><\/li>\n<li id=\"calibre_link-1494\" class=\"calibre3\"><a href=\"\/#calibre_link-560\">If you are using Visual Studio 2022<\/a><\/li>\n<li id=\"calibre_link-1495\" class=\"calibre3\"><a href=\"\/#calibre_link-561\">Managing the Northwind sample database with SQLiteStudio<\/a><\/li>\n<li id=\"calibre_link-1496\" class=\"calibre3\"><a href=\"\/#calibre_link-562\">Using the lightweight ADO.NET database providers<\/a><\/li>\n<li id=\"calibre_link-1497\" class=\"calibre3\"><a href=\"\/#calibre_link-563\">Choosing an EF Core database provider<\/a><\/li>\n<li id=\"calibre_link-1498\" class=\"calibre3\"><a href=\"\/#calibre_link-564\">Connecting to a named SQLite database<\/a><\/li>\n<li id=\"calibre_link-1499\" class=\"calibre3\"><a href=\"\/#calibre_link-565\">Defining the Northwind database context class<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1500\" class=\"calibre3\"><a href=\"\/#calibre_link-566\">Defining EF Core models<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1501\" class=\"calibre3\"><a href=\"\/#calibre_link-567\">Using EF Core conventions to define the model<\/a><\/li>\n<li id=\"calibre_link-1502\" class=\"calibre3\"><a href=\"\/#calibre_link-568\">Using EF Core annotation attributes to define the model<\/a><\/li>\n<li id=\"calibre_link-1503\" class=\"calibre3\"><a href=\"\/#calibre_link-569\">Using the EF Core Fluent API to define the model<\/a><\/li>\n<li id=\"calibre_link-1504\" class=\"calibre3\"><a href=\"\/#calibre_link-570\">Understanding data seeding with the Fluent API<\/a><\/li>\n<li id=\"calibre_link-1505\" class=\"calibre3\"><a href=\"\/#calibre_link-571\">Building EF Core models for the Northwind tables<\/a><\/li>\n<li id=\"calibre_link-1506\" class=\"calibre3\"><a href=\"\/#calibre_link-572\">Defining the Category and Product entity classes<\/a><\/li>\n<li id=\"calibre_link-1507\" class=\"calibre3\"><a href=\"\/#calibre_link-573\">Adding tables to the Northwind database context class<\/a><\/li>\n<li id=\"calibre_link-1508\" class=\"calibre3\"><a href=\"\/#calibre_link-574\">Setting up the dotnet-ef tool<\/a><\/li>\n<li id=\"calibre_link-1509\" class=\"calibre3\"><a href=\"\/#calibre_link-575\">Scaffolding models using an existing database<\/a><\/li>\n<li id=\"calibre_link-1510\" class=\"calibre3\"><a href=\"\/#calibre_link-576\">Customizing the reverse engineering templates<\/a><\/li>\n<li id=\"calibre_link-1511\" class=\"calibre3\"><a href=\"\/#calibre_link-577\">Configuring preconvention models<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1512\" class=\"calibre3\"><a href=\"\/#calibre_link-578\">Querying EF Core models<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1513\" class=\"calibre3\"><a href=\"\/#calibre_link-579\">Filtering included entities<\/a><\/li>\n<li id=\"calibre_link-1514\" class=\"calibre3\"><a href=\"\/#calibre_link-580\">Filtering and sorting products<\/a><\/li>\n<li id=\"calibre_link-1515\" class=\"calibre3\"><a href=\"\/#calibre_link-581\">Getting the generated SQL<\/a><\/li>\n<li id=\"calibre_link-1516\" class=\"calibre3\"><a href=\"\/#calibre_link-582\">Logging EF Core<\/a><\/li>\n<li id=\"calibre_link-1517\" class=\"calibre3\"><a href=\"\/#calibre_link-583\">Filtering logs by provider-specific values<\/a><\/li>\n<li id=\"calibre_link-1518\" class=\"calibre3\"><a href=\"\/#calibre_link-584\">Logging with query tags<\/a><\/li>\n<li id=\"calibre_link-1519\" class=\"calibre3\"><a href=\"\/#calibre_link-585\">Getting a single entity<\/a><\/li>\n<li id=\"calibre_link-1520\" class=\"calibre3\"><a href=\"\/#calibre_link-586\">Pattern matching with Like<\/a><\/li>\n<li id=\"calibre_link-1521\" class=\"calibre3\"><a href=\"\/#calibre_link-587\">Generating a random number in queries<\/a><\/li>\n<li id=\"calibre_link-1522\" class=\"calibre3\"><a href=\"\/#calibre_link-588\">Defining global filters<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1523\" class=\"calibre3\"><a href=\"\/#calibre_link-589\">Loading and tracking patterns with EF Core<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1524\" class=\"calibre3\"><a href=\"\/#calibre_link-590\">Eager loading entities using the Include extension method<\/a><\/li>\n<li id=\"calibre_link-1525\" class=\"calibre3\"><a href=\"\/#calibre_link-591\">Enabling lazy loading<\/a><\/li>\n<li id=\"calibre_link-1526\" class=\"calibre3\"><a href=\"\/#calibre_link-592\">Explicit loading entities using the Load method<\/a><\/li>\n<li id=\"calibre_link-1527\" class=\"calibre3\"><a href=\"\/#calibre_link-593\">Controlling the tracking of entities<\/a><\/li>\n<li id=\"calibre_link-1528\" class=\"calibre3\"><a href=\"\/#calibre_link-594\">Three tracking scenarios<\/a><\/li>\n<li id=\"calibre_link-1529\" class=\"calibre3\"><a href=\"\/#calibre_link-595\">Lazy loading for no tracking queries<\/a><\/li>\n<li id=\"calibre_link-1530\" class=\"calibre3\"><a href=\"\/#calibre_link-596\">Summary of tracking<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1531\" class=\"calibre3\"><a href=\"\/#calibre_link-597\">Modifying data with EF Core<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1532\" class=\"calibre3\"><a href=\"\/#calibre_link-598\">Inserting entities<\/a><\/li>\n<li id=\"calibre_link-1533\" class=\"calibre3\"><a href=\"\/#calibre_link-599\">Updating entities<\/a><\/li>\n<li id=\"calibre_link-1534\" class=\"calibre3\"><a href=\"\/#calibre_link-600\">Deleting entities<\/a><\/li>\n<li id=\"calibre_link-1535\" class=\"calibre3\"><a href=\"\/#calibre_link-601\">More efficient updates and deletes<\/a><\/li>\n<li id=\"calibre_link-1536\" class=\"calibre3\"><a href=\"\/#calibre_link-602\">Pooling database contexts<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1537\" class=\"calibre3\"><a href=\"\/#calibre_link-603\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1538\" class=\"calibre3\"><a href=\"\/#calibre_link-604\">Exercise 10.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1539\" class=\"calibre3\"><a href=\"\/#calibre_link-605\">Exercise 10.2 &ndash; Exporting data using different serialization formats<\/a><\/li>\n<li id=\"calibre_link-1540\" class=\"calibre3\"><a href=\"\/#calibre_link-606\">Exercise 10.3 &ndash; Working with transactions<\/a><\/li>\n<li id=\"calibre_link-1541\" class=\"calibre3\"><a href=\"\/#calibre_link-607\">Exercise 10.4 &ndash; Explore a Code First EF Core model<\/a><\/li>\n<li id=\"calibre_link-1542\" class=\"calibre3\"><a href=\"\/#calibre_link-608\">Exercise 10.5 &ndash; Explore app secrets<\/a><\/li>\n<li id=\"calibre_link-1543\" class=\"calibre3\"><a href=\"\/#calibre_link-609\">Exercise 10.6 &ndash; Explore topics<\/a><\/li>\n<li id=\"calibre_link-1544\" class=\"calibre3\"><a href=\"\/#calibre_link-610\">Exercise 10.7 &ndash; Explore NoSQL databases<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1545\" class=\"calibre3\"><a href=\"\/#calibre_link-611\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1546\" class=\"calibre3\"><a href=\"\/#calibre_link-612\">11 Querying and Manipulating Data Using LINQ<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1547\" class=\"calibre3\"><a href=\"\/#calibre_link-613\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1548\" class=\"calibre3\"><a href=\"\/#calibre_link-614\">Writing LINQ expressions<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1549\" class=\"calibre3\"><a href=\"\/#calibre_link-615\">Comparing imperative and declarative language features<\/a><\/li>\n<li id=\"calibre_link-1550\" class=\"calibre3\"><a href=\"\/#calibre_link-616\">LINQ components<\/a><\/li>\n<li id=\"calibre_link-1551\" class=\"calibre3\"><a href=\"\/#calibre_link-617\">Building LINQ expressions with the Enumerable class<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1552\" class=\"calibre3\"><a href=\"\/#calibre_link-618\">LINQ in practice<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1553\" class=\"calibre3\"><a href=\"\/#calibre_link-619\">Understanding deferred execution<\/a><\/li>\n<li id=\"calibre_link-1554\" class=\"calibre3\"><a href=\"\/#calibre_link-620\">Filtering entities using Where<\/a><\/li>\n<li id=\"calibre_link-1555\" class=\"calibre3\"><a href=\"\/#calibre_link-621\">Targeting a named method<\/a><\/li>\n<li id=\"calibre_link-1556\" class=\"calibre3\"><a href=\"\/#calibre_link-622\">Simplifying the code by removing the explicit delegate instantiation<\/a><\/li>\n<li id=\"calibre_link-1557\" class=\"calibre3\"><a href=\"\/#calibre_link-623\">Targeting a lambda expression<\/a><\/li>\n<li id=\"calibre_link-1558\" class=\"calibre3\"><a href=\"\/#calibre_link-624\">Lambda expressions with default parameter values<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1559\" class=\"calibre3\"><a href=\"\/#calibre_link-625\">Sorting and more<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1560\" class=\"calibre3\"><a href=\"\/#calibre_link-626\">Sorting by a single property using OrderBy<\/a><\/li>\n<li id=\"calibre_link-1561\" class=\"calibre3\"><a href=\"\/#calibre_link-627\">Sorting by a subsequent property using ThenBy<\/a><\/li>\n<li id=\"calibre_link-1562\" class=\"calibre3\"><a href=\"\/#calibre_link-628\">Sorting by the item itself<\/a><\/li>\n<li id=\"calibre_link-1563\" class=\"calibre3\"><a href=\"\/#calibre_link-629\">Declaring a query using var or a specified type<\/a><\/li>\n<li id=\"calibre_link-1564\" class=\"calibre3\"><a href=\"\/#calibre_link-630\">Filtering by type<\/a><\/li>\n<li id=\"calibre_link-1565\" class=\"calibre3\"><a href=\"\/#calibre_link-631\">Working with sets and bags<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1566\" class=\"calibre3\"><a href=\"\/#calibre_link-632\">Using LINQ with EF Core<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1567\" class=\"calibre3\"><a href=\"\/#calibre_link-633\">Creating a console app for exploring LINQ to Entities<\/a><\/li>\n<li id=\"calibre_link-1568\" class=\"calibre3\"><a href=\"\/#calibre_link-634\">Building an EF Core model<\/a><\/li>\n<li id=\"calibre_link-1569\" class=\"calibre3\"><a href=\"\/#calibre_link-635\">Filtering and sorting sequences<\/a><\/li>\n<li id=\"calibre_link-1570\" class=\"calibre3\"><a href=\"\/#calibre_link-636\">Projecting sequences into new types<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1571\" class=\"calibre3\"><a href=\"\/#calibre_link-637\">Joining, grouping, and lookups<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1572\" class=\"calibre3\"><a href=\"\/#calibre_link-638\">Joining sequences<\/a><\/li>\n<li id=\"calibre_link-1573\" class=\"calibre3\"><a href=\"\/#calibre_link-639\">Group-joining sequences<\/a><\/li>\n<li id=\"calibre_link-1574\" class=\"calibre3\"><a href=\"\/#calibre_link-640\">Grouping for lookups<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1575\" class=\"calibre3\"><a href=\"\/#calibre_link-641\">Aggregating and paging sequences<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1576\" class=\"calibre3\"><a href=\"\/#calibre_link-642\">Checking for an empty sequence<\/a><\/li>\n<li id=\"calibre_link-1577\" class=\"calibre3\"><a href=\"\/#calibre_link-643\">Be careful with Count!<\/a><\/li>\n<li id=\"calibre_link-1578\" class=\"calibre3\"><a href=\"\/#calibre_link-644\">Paging with LINQ<\/a><\/li>\n<li id=\"calibre_link-1579\" class=\"calibre3\"><a href=\"\/#calibre_link-645\">Sweetening LINQ syntax with syntactic sugar<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1580\" class=\"calibre3\"><a href=\"\/#calibre_link-646\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1581\" class=\"calibre3\"><a href=\"\/#calibre_link-647\">Exercise 11.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1582\" class=\"calibre3\"><a href=\"\/#calibre_link-648\">Exercise 11.2 &ndash; Practice querying with LINQ<\/a><\/li>\n<li id=\"calibre_link-1583\" class=\"calibre3\"><a href=\"\/#calibre_link-649\">Exercise 11.3 &ndash; Using multiple threads with parallel LINQ<\/a><\/li>\n<li id=\"calibre_link-1584\" class=\"calibre3\"><a href=\"\/#calibre_link-650\">Exercise 11.4 &ndash; Working with LINQ to XML<\/a><\/li>\n<li id=\"calibre_link-1585\" class=\"calibre3\"><a href=\"\/#calibre_link-651\">Exercise 11.5 &ndash; Creating your own LINQ extension methods<\/a><\/li>\n<li id=\"calibre_link-1586\" class=\"calibre3\"><a href=\"\/#calibre_link-652\">Exercise 11.6 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1587\" class=\"calibre3\"><a href=\"\/#calibre_link-653\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1588\" class=\"calibre3\"><a href=\"\/#calibre_link-654\">12 Introducing Web Development Using ASP.NET Core<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1589\" class=\"calibre3\"><a href=\"\/#calibre_link-655\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1590\" class=\"calibre3\"><a href=\"\/#calibre_link-656\">Understanding ASP.NET Core<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1591\" class=\"calibre3\"><a href=\"\/#calibre_link-657\">Classic ASP.NET versus modern ASP.NET Core<\/a><\/li>\n<li id=\"calibre_link-1592\" class=\"calibre3\"><a href=\"\/#calibre_link-658\">Building websites using ASP.NET Core<\/a><\/li>\n<li id=\"calibre_link-1593\" class=\"calibre3\"><a href=\"\/#calibre_link-659\">Comparison of file types used in ASP.NET Core<\/a><\/li>\n<li id=\"calibre_link-1594\" class=\"calibre3\"><a href=\"\/#calibre_link-660\">Building websites using a content management system<\/a><\/li>\n<li id=\"calibre_link-1595\" class=\"calibre3\"><a href=\"\/#calibre_link-661\">Building web applications using SPA frameworks<\/a><\/li>\n<li id=\"calibre_link-1596\" class=\"calibre3\"><a href=\"\/#calibre_link-662\">Building web and other services<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1597\" class=\"calibre3\"><a href=\"\/#calibre_link-663\">New features in ASP.NET Core<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1598\" class=\"calibre3\"><a href=\"\/#calibre_link-664\">ASP.NET Core 1.0, June 2016<\/a><\/li>\n<li id=\"calibre_link-1599\" class=\"calibre3\"><a href=\"\/#calibre_link-665\">ASP.NET Core 1.1, November 2016<\/a><\/li>\n<li id=\"calibre_link-1600\" class=\"calibre3\"><a href=\"\/#calibre_link-666\">ASP.NET Core 2.0, August 2017<\/a><\/li>\n<li id=\"calibre_link-1601\" class=\"calibre3\"><a href=\"\/#calibre_link-667\">ASP.NET Core 2.1, May 2018<\/a><\/li>\n<li id=\"calibre_link-1602\" class=\"calibre3\"><a href=\"\/#calibre_link-668\">ASP.NET Core 2.2, December 2018<\/a><\/li>\n<li id=\"calibre_link-1603\" class=\"calibre3\"><a href=\"\/#calibre_link-669\">ASP.NET Core 3.0, September 2019<\/a><\/li>\n<li id=\"calibre_link-1604\" class=\"calibre3\"><a href=\"\/#calibre_link-670\">ASP.NET Core 3.1, December 2019<\/a><\/li>\n<li id=\"calibre_link-1605\" class=\"calibre3\"><a href=\"\/#calibre_link-671\">Blazor WebAssembly 3.2, May 2020<\/a><\/li>\n<li id=\"calibre_link-1606\" class=\"calibre3\"><a href=\"\/#calibre_link-672\">ASP.NET Core 5, November 2020<\/a><\/li>\n<li id=\"calibre_link-1607\" class=\"calibre3\"><a href=\"\/#calibre_link-673\">ASP.NET Core 6, November 2021<\/a><\/li>\n<li id=\"calibre_link-1608\" class=\"calibre3\"><a href=\"\/#calibre_link-674\">ASP.NET Core 7, November 2022<\/a><\/li>\n<li id=\"calibre_link-1609\" class=\"calibre3\"><a href=\"\/#calibre_link-675\">ASP.NET Core 8, November 2023<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1610\" class=\"calibre3\"><a href=\"\/#calibre_link-676\">Structuring projects<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1611\" class=\"calibre3\"><a href=\"\/#calibre_link-677\">Structuring projects in a solution<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1612\" class=\"calibre3\"><a href=\"\/#calibre_link-678\">Building an entity model for use in the rest of the book<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1613\" class=\"calibre3\"><a href=\"\/#calibre_link-679\">Creating the Northwind database<\/a><\/li>\n<li id=\"calibre_link-1614\" class=\"calibre3\"><a href=\"\/#calibre_link-680\">Creating a class library for entity models using SQLite<\/a><\/li>\n<li id=\"calibre_link-1615\" class=\"calibre3\"><a href=\"\/#calibre_link-681\">Creating a class library for a database context using SQLite<\/a><\/li>\n<li id=\"calibre_link-1616\" class=\"calibre3\"><a href=\"\/#calibre_link-682\">Customizing the model and defining an extension method<\/a><\/li>\n<li id=\"calibre_link-1617\" class=\"calibre3\"><a href=\"\/#calibre_link-683\">Registering the scope of a dependency service<\/a><\/li>\n<li id=\"calibre_link-1618\" class=\"calibre3\"><a href=\"\/#calibre_link-684\">Creating class libraries for entity models using SQL Server<\/a><\/li>\n<li id=\"calibre_link-1619\" class=\"calibre3\"><a href=\"\/#calibre_link-685\">Improving the class-to-table mapping<\/a><\/li>\n<li id=\"calibre_link-1620\" class=\"calibre3\"><a href=\"\/#calibre_link-686\">Testing the class libraries<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1621\" class=\"calibre3\"><a href=\"\/#calibre_link-687\">Understanding web development<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1622\" class=\"calibre3\"><a href=\"\/#calibre_link-688\">Understanding Hypertext Transfer Protocol<\/a><\/li>\n<li id=\"calibre_link-1623\" class=\"calibre3\"><a href=\"\/#calibre_link-689\">Understanding the components of a URL<\/a><\/li>\n<li id=\"calibre_link-1624\" class=\"calibre3\"><a href=\"\/#calibre_link-690\">Using Google Chrome to make HTTP requests<\/a><\/li>\n<li id=\"calibre_link-1625\" class=\"calibre3\"><a href=\"\/#calibre_link-691\">Understanding client-side web development technologies<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1626\" class=\"calibre3\"><a href=\"\/#calibre_link-692\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1627\" class=\"calibre3\"><a href=\"\/#calibre_link-693\">Exercise 12.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1628\" class=\"calibre3\"><a href=\"\/#calibre_link-694\">Exercise 12.2 &ndash; Know your webbreviations<\/a><\/li>\n<li id=\"calibre_link-1629\" class=\"calibre3\"><a href=\"\/#calibre_link-695\">Exercise 12.3 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1630\" class=\"calibre3\"><a href=\"\/#calibre_link-696\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1631\" class=\"calibre3\"><a href=\"\/#calibre_link-697\">13 Building Websites Using ASP.NET Core Razor Pages<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1632\" class=\"calibre3\"><a href=\"\/#calibre_link-698\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1633\" class=\"calibre3\"><a href=\"\/#calibre_link-699\">Exploring ASP.NET Core<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1634\" class=\"calibre3\"><a href=\"\/#calibre_link-700\">Creating an empty ASP.NET Core project<\/a><\/li>\n<li id=\"calibre_link-1635\" class=\"calibre3\"><a href=\"\/#calibre_link-701\">Testing and securing the website<\/a><\/li>\n<li id=\"calibre_link-1636\" class=\"calibre3\"><a href=\"\/#calibre_link-702\">Enabling stronger security and redirecting to a secure connection<\/a><\/li>\n<li id=\"calibre_link-1637\" class=\"calibre3\"><a href=\"\/#calibre_link-703\">Controlling the hosting environment<\/a><\/li>\n<li id=\"calibre_link-1638\" class=\"calibre3\"><a href=\"\/#calibre_link-704\">Enabling a website to serve static content<\/a><\/li>\n<li id=\"calibre_link-1639\" class=\"calibre3\"><a href=\"\/#calibre_link-705\">Creating a folder for static files and a web page<\/a><\/li>\n<li id=\"calibre_link-1640\" class=\"calibre3\"><a href=\"\/#calibre_link-706\">Enabling static and default files<\/a><\/li>\n<li id=\"calibre_link-1641\" class=\"calibre3\"><a href=\"\/#calibre_link-707\">Understanding browser requests during development<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1642\" class=\"calibre3\"><a href=\"\/#calibre_link-708\">Exploring ASP.NET Core Razor Pages<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1643\" class=\"calibre3\"><a href=\"\/#calibre_link-709\">Enabling Razor Pages<\/a><\/li>\n<li id=\"calibre_link-1644\" class=\"calibre3\"><a href=\"\/#calibre_link-710\">Adding code to a Razor Page<\/a><\/li>\n<li id=\"calibre_link-1645\" class=\"calibre3\"><a href=\"\/#calibre_link-711\">Using shared layouts with Razor Pages<\/a><\/li>\n<li id=\"calibre_link-1646\" class=\"calibre3\"><a href=\"\/#calibre_link-712\">Temporarily storing data<\/a><\/li>\n<li id=\"calibre_link-1647\" class=\"calibre3\"><a href=\"\/#calibre_link-713\">Using code-behind files with Razor Pages<\/a><\/li>\n<li id=\"calibre_link-1648\" class=\"calibre3\"><a href=\"\/#calibre_link-714\">Configuring files included in an ASP.NET Core project<\/a><\/li>\n<li id=\"calibre_link-1649\" class=\"calibre3\"><a href=\"\/#calibre_link-715\">Project file build actions<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1650\" class=\"calibre3\"><a href=\"\/#calibre_link-716\">Using Entity Framework Core with ASP.NET Core<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1651\" class=\"calibre3\"><a href=\"\/#calibre_link-717\">Configuring Entity Framework Core as a service<\/a><\/li>\n<li id=\"calibre_link-1652\" class=\"calibre3\"><a href=\"\/#calibre_link-718\">Enabling a model to insert entities<\/a><\/li>\n<li id=\"calibre_link-1653\" class=\"calibre3\"><a href=\"\/#calibre_link-719\">Defining a form to insert a new supplier<\/a><\/li>\n<li id=\"calibre_link-1654\" class=\"calibre3\"><a href=\"\/#calibre_link-720\">Injecting a dependency service into a Razor Page<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1655\" class=\"calibre3\"><a href=\"\/#calibre_link-721\">Configuring services and the HTTP request pipeline<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1656\" class=\"calibre3\"><a href=\"\/#calibre_link-722\">Understanding endpoint routing<\/a><\/li>\n<li id=\"calibre_link-1657\" class=\"calibre3\"><a href=\"\/#calibre_link-723\">Configuring endpoint routing<\/a><\/li>\n<li id=\"calibre_link-1658\" class=\"calibre3\"><a href=\"\/#calibre_link-724\">Reviewing the endpoint routing configuration in our project<\/a><\/li>\n<li id=\"calibre_link-1659\" class=\"calibre3\"><a href=\"\/#calibre_link-725\">Setting up the HTTP pipeline<\/a><\/li>\n<li id=\"calibre_link-1660\" class=\"calibre3\"><a href=\"\/#calibre_link-726\">Summarizing key middleware extension methods<\/a><\/li>\n<li id=\"calibre_link-1661\" class=\"calibre3\"><a href=\"\/#calibre_link-727\">Visualizing the HTTP pipeline<\/a><\/li>\n<li id=\"calibre_link-1662\" class=\"calibre3\"><a href=\"\/#calibre_link-728\">Implementing an anonymous inline delegate as middleware<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1663\" class=\"calibre3\"><a href=\"\/#calibre_link-729\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1664\" class=\"calibre3\"><a href=\"\/#calibre_link-730\">Exercise 13.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1665\" class=\"calibre3\"><a href=\"\/#calibre_link-731\">Exercise 13.2 &ndash; Using Razor class libraries<\/a><\/li>\n<li id=\"calibre_link-1666\" class=\"calibre3\"><a href=\"\/#calibre_link-732\">Exercise 13.3 &ndash; Enabling HTTP\/3 and request decompression support<\/a><\/li>\n<li id=\"calibre_link-1667\" class=\"calibre3\"><a href=\"\/#calibre_link-733\">Exercise 13.4 &ndash; Practice building a data-driven web page<\/a><\/li>\n<li id=\"calibre_link-1668\" class=\"calibre3\"><a href=\"\/#calibre_link-734\">Exercise 13.5 &ndash; Practice building web pages for functions<\/a><\/li>\n<li id=\"calibre_link-1669\" class=\"calibre3\"><a href=\"\/#calibre_link-735\">Exercise 13.6 &ndash; Introducing Bootstrap<\/a><\/li>\n<li id=\"calibre_link-1670\" class=\"calibre3\"><a href=\"\/#calibre_link-736\">Exercise 13.7 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1671\" class=\"calibre3\"><a href=\"\/#calibre_link-737\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1672\" class=\"calibre3\"><a href=\"\/#calibre_link-738\">14 Building Websites Using the Model-View-Controller Pattern<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1673\" class=\"calibre3\"><a href=\"\/#calibre_link-739\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1674\" class=\"calibre3\"><a href=\"\/#calibre_link-740\">Setting up an ASP.NET Core MVC website<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1675\" class=\"calibre3\"><a href=\"\/#calibre_link-741\">Creating an ASP.NET Core MVC website<\/a><\/li>\n<li id=\"calibre_link-1676\" class=\"calibre3\"><a href=\"\/#calibre_link-742\">Creating the authentication database for SQL Server LocalDB<\/a><\/li>\n<li id=\"calibre_link-1677\" class=\"calibre3\"><a href=\"\/#calibre_link-743\">Changing the port numbers and starting the website<\/a><\/li>\n<li id=\"calibre_link-1678\" class=\"calibre3\"><a href=\"\/#calibre_link-744\">Exploring visitor registration<\/a><\/li>\n<li id=\"calibre_link-1679\" class=\"calibre3\"><a href=\"\/#calibre_link-745\">Reviewing an MVC website project structure<\/a><\/li>\n<li id=\"calibre_link-1680\" class=\"calibre3\"><a href=\"\/#calibre_link-746\">Reviewing the ASP.NET Core Identity database<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1681\" class=\"calibre3\"><a href=\"\/#calibre_link-747\">Exploring an ASP.NET Core MVC website<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1682\" class=\"calibre3\"><a href=\"\/#calibre_link-748\">ASP.NET Core MVC initialization<\/a><\/li>\n<li id=\"calibre_link-1683\" class=\"calibre3\"><a href=\"\/#calibre_link-749\">The default MVC route<\/a><\/li>\n<li id=\"calibre_link-1684\" class=\"calibre3\"><a href=\"\/#calibre_link-750\">Controllers and actions<\/a><\/li>\n<li id=\"calibre_link-1685\" class=\"calibre3\"><a href=\"\/#calibre_link-751\">The ControllerBase class<\/a><\/li>\n<li id=\"calibre_link-1686\" class=\"calibre3\"><a href=\"\/#calibre_link-752\">The Controller class<\/a><\/li>\n<li id=\"calibre_link-1687\" class=\"calibre3\"><a href=\"\/#calibre_link-753\">The responsibilities of a controller<\/a><\/li>\n<li id=\"calibre_link-1688\" class=\"calibre3\"><a href=\"\/#calibre_link-754\">The view search path convention<\/a><\/li>\n<li id=\"calibre_link-1689\" class=\"calibre3\"><a href=\"\/#calibre_link-755\">Logging using the dependency service<\/a><\/li>\n<li id=\"calibre_link-1690\" class=\"calibre3\"><a href=\"\/#calibre_link-756\">Using entity and view models<\/a><\/li>\n<li id=\"calibre_link-1691\" class=\"calibre3\"><a href=\"\/#calibre_link-757\">Implementing views<\/a><\/li>\n<li id=\"calibre_link-1692\" class=\"calibre3\"><a href=\"\/#calibre_link-758\">How cache busting with Tag Helpers works<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1693\" class=\"calibre3\"><a href=\"\/#calibre_link-759\">Customizing an ASP.NET Core MVC website<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1694\" class=\"calibre3\"><a href=\"\/#calibre_link-760\">Defining a custom style<\/a><\/li>\n<li id=\"calibre_link-1695\" class=\"calibre3\"><a href=\"\/#calibre_link-761\">Setting up the category images<\/a><\/li>\n<li id=\"calibre_link-1696\" class=\"calibre3\"><a href=\"\/#calibre_link-762\">Razor syntax and expressions<\/a><\/li>\n<li id=\"calibre_link-1697\" class=\"calibre3\"><a href=\"\/#calibre_link-763\">Defining a typed view<\/a><\/li>\n<li id=\"calibre_link-1698\" class=\"calibre3\"><a href=\"\/#calibre_link-764\">Passing parameters using a route value<\/a><\/li>\n<li id=\"calibre_link-1699\" class=\"calibre3\"><a href=\"\/#calibre_link-765\">Disambiguating action methods<\/a><\/li>\n<li id=\"calibre_link-1700\" class=\"calibre3\"><a href=\"\/#calibre_link-766\">Model binders in detail<\/a><\/li>\n<li id=\"calibre_link-1701\" class=\"calibre3\"><a href=\"\/#calibre_link-767\">Passing a route parameter<\/a><\/li>\n<li id=\"calibre_link-1702\" class=\"calibre3\"><a href=\"\/#calibre_link-768\">Passing a form parameter<\/a><\/li>\n<li id=\"calibre_link-1703\" class=\"calibre3\"><a href=\"\/#calibre_link-769\">Defining views with HTML Helper methods<\/a><\/li>\n<li id=\"calibre_link-1704\" class=\"calibre3\"><a href=\"\/#calibre_link-770\">Defining views with Tag Helpers<\/a><\/li>\n<li id=\"calibre_link-1705\" class=\"calibre3\"><a href=\"\/#calibre_link-771\">Cross-functional filters<\/a><\/li>\n<li id=\"calibre_link-1706\" class=\"calibre3\"><a href=\"\/#calibre_link-772\">Using a filter to define a custom route<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1707\" class=\"calibre3\"><a href=\"\/#calibre_link-773\">Improving performance and scalability using caching<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1708\" class=\"calibre3\"><a href=\"\/#calibre_link-774\">Caching HTTP responses<\/a><\/li>\n<li id=\"calibre_link-1709\" class=\"calibre3\"><a href=\"\/#calibre_link-775\">Output caching endpoints<\/a><\/li>\n<li id=\"calibre_link-1710\" class=\"calibre3\"><a href=\"\/#calibre_link-776\">Output caching MVC views<\/a><\/li>\n<li id=\"calibre_link-1711\" class=\"calibre3\"><a href=\"\/#calibre_link-777\">Varying cached data by query string<\/a><\/li>\n<li id=\"calibre_link-1712\" class=\"calibre3\"><a href=\"\/#calibre_link-778\">Disabling caching to avoid confusion<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1713\" class=\"calibre3\"><a href=\"\/#calibre_link-779\">Querying a database and using display templates<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1714\" class=\"calibre3\"><a href=\"\/#calibre_link-780\">Improving scalability using asynchronous tasks<\/a><\/li>\n<li id=\"calibre_link-1715\" class=\"calibre3\"><a href=\"\/#calibre_link-781\">Making controller action methods asynchronous<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1716\" class=\"calibre3\"><a href=\"\/#calibre_link-782\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1717\" class=\"calibre3\"><a href=\"\/#calibre_link-783\">Exercise 14.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1718\" class=\"calibre3\"><a href=\"\/#calibre_link-784\">Exercise 14.2 &ndash; Practice implementing MVC by implementing a category detail page<\/a><\/li>\n<li id=\"calibre_link-1719\" class=\"calibre3\"><a href=\"\/#calibre_link-785\">Exercise 14.3 &ndash; Practice improving scalability by understanding and implementing async action methods<\/a><\/li>\n<li id=\"calibre_link-1720\" class=\"calibre3\"><a href=\"\/#calibre_link-786\">Exercise 14.4 &ndash; Practice unit testing MVC controllers<\/a><\/li>\n<li id=\"calibre_link-1721\" class=\"calibre3\"><a href=\"\/#calibre_link-787\">Exercise 14.5 &ndash; Using a filter to control authorization<\/a><\/li>\n<li id=\"calibre_link-1722\" class=\"calibre3\"><a href=\"\/#calibre_link-788\">Exercise 14.6 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1723\" class=\"calibre3\"><a href=\"\/#calibre_link-789\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1724\" class=\"calibre3\"><a href=\"\/#calibre_link-790\">15 Building and Consuming Web Services<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1725\" class=\"calibre3\"><a href=\"\/#calibre_link-791\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1726\" class=\"calibre3\"><a href=\"\/#calibre_link-792\">Building web services using the ASP.NET Core Web API<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1727\" class=\"calibre3\"><a href=\"\/#calibre_link-793\">Understanding web service acronyms<\/a><\/li>\n<li id=\"calibre_link-1728\" class=\"calibre3\"><a href=\"\/#calibre_link-794\">Understanding HTTP requests and responses for Web APIs<\/a><\/li>\n<li id=\"calibre_link-1729\" class=\"calibre3\"><a href=\"\/#calibre_link-795\">Creating an ASP.NET Core Web API project<\/a><\/li>\n<li id=\"calibre_link-1730\" class=\"calibre3\"><a href=\"\/#calibre_link-796\">Reviewing the web service's functionality<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1731\" class=\"calibre3\"><a href=\"\/#calibre_link-797\">Creating a web service for the Northwind database<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1732\" class=\"calibre3\"><a href=\"\/#calibre_link-798\">Registering dependency services<\/a><\/li>\n<li id=\"calibre_link-1733\" class=\"calibre3\"><a href=\"\/#calibre_link-799\">Creating data repositories with caching for entities<\/a><\/li>\n<li id=\"calibre_link-1734\" class=\"calibre3\"><a href=\"\/#calibre_link-800\">Routing web services<\/a><\/li>\n<li id=\"calibre_link-1735\" class=\"calibre3\"><a href=\"\/#calibre_link-801\">Route constraints<\/a><\/li>\n<li id=\"calibre_link-1736\" class=\"calibre3\"><a href=\"\/#calibre_link-802\">Short-circuit routes in ASP.NET Core 8<\/a><\/li>\n<li id=\"calibre_link-1737\" class=\"calibre3\"><a href=\"\/#calibre_link-803\">Improved route tooling in ASP.NET Core 8<\/a><\/li>\n<li id=\"calibre_link-1738\" class=\"calibre3\"><a href=\"\/#calibre_link-804\">Understanding action method return types<\/a><\/li>\n<li id=\"calibre_link-1739\" class=\"calibre3\"><a href=\"\/#calibre_link-805\">Configuring the customer repository and Web API controller<\/a><\/li>\n<li id=\"calibre_link-1740\" class=\"calibre3\"><a href=\"\/#calibre_link-806\">Specifying problem details<\/a><\/li>\n<li id=\"calibre_link-1741\" class=\"calibre3\"><a href=\"\/#calibre_link-807\">Controlling XML serialization<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1742\" class=\"calibre3\"><a href=\"\/#calibre_link-808\">Documenting and testing web services<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1743\" class=\"calibre3\"><a href=\"\/#calibre_link-809\">Testing GET requests using a browser<\/a><\/li>\n<li id=\"calibre_link-1744\" class=\"calibre3\"><a href=\"\/#calibre_link-810\">Making GET requests using HTTP\/REST tools<\/a><\/li>\n<li id=\"calibre_link-1745\" class=\"calibre3\"><a href=\"\/#calibre_link-811\">Making other requests using HTTP\/REST tools<\/a><\/li>\n<li id=\"calibre_link-1746\" class=\"calibre3\"><a href=\"\/#calibre_link-812\">Passing environment variables<\/a><\/li>\n<li id=\"calibre_link-1747\" class=\"calibre3\"><a href=\"\/#calibre_link-813\">Understanding Swagger<\/a><\/li>\n<li id=\"calibre_link-1748\" class=\"calibre3\"><a href=\"\/#calibre_link-814\">Testing requests with Swagger UI<\/a><\/li>\n<li id=\"calibre_link-1749\" class=\"calibre3\"><a href=\"\/#calibre_link-815\">Enabling HTTP logging<\/a><\/li>\n<li id=\"calibre_link-1750\" class=\"calibre3\"><a href=\"\/#calibre_link-816\">Support for logging additional request headers in W3CLogger<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1751\" class=\"calibre3\"><a href=\"\/#calibre_link-817\">Consuming web services using HTTP clients<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1752\" class=\"calibre3\"><a href=\"\/#calibre_link-818\">Understanding HttpClient<\/a><\/li>\n<li id=\"calibre_link-1753\" class=\"calibre3\"><a href=\"\/#calibre_link-819\">Configuring HTTP clients using HttpClientFactory<\/a><\/li>\n<li id=\"calibre_link-1754\" class=\"calibre3\"><a href=\"\/#calibre_link-820\">Getting customers as JSON in the controller<\/a><\/li>\n<li id=\"calibre_link-1755\" class=\"calibre3\"><a href=\"\/#calibre_link-821\">Starting multiple projects<\/a><\/li>\n<li id=\"calibre_link-1756\" class=\"calibre3\"><a href=\"\/#calibre_link-822\">Starting the web service and MVC client projects<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1757\" class=\"calibre3\"><a href=\"\/#calibre_link-823\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1758\" class=\"calibre3\"><a href=\"\/#calibre_link-824\">Exercise 15.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1759\" class=\"calibre3\"><a href=\"\/#calibre_link-825\">Exercise 15.2 &ndash; Practice creating and deleting customers with HttpClient<\/a><\/li>\n<li id=\"calibre_link-1760\" class=\"calibre3\"><a href=\"\/#calibre_link-826\">Exercise 15.3 &ndash; Implementing advanced features for web services<\/a><\/li>\n<li id=\"calibre_link-1761\" class=\"calibre3\"><a href=\"\/#calibre_link-827\">Exercise 15.4 &ndash; Building web services using Minimal APIs<\/a><\/li>\n<li id=\"calibre_link-1762\" class=\"calibre3\"><a href=\"\/#calibre_link-828\">Exercise 15.5 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1763\" class=\"calibre3\"><a href=\"\/#calibre_link-829\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1764\" class=\"calibre3\"><a href=\"\/#calibre_link-830\">16 Building User Interfaces Using Blazor<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1765\" class=\"calibre3\"><a href=\"\/#calibre_link-831\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1766\" class=\"calibre3\"><a href=\"\/#calibre_link-832\">History of Blazor<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1767\" class=\"calibre3\"><a href=\"\/#calibre_link-833\">JavaScript and friends<\/a><\/li>\n<li id=\"calibre_link-1768\" class=\"calibre3\"><a href=\"\/#calibre_link-834\">Silverlight &ndash; C# and .NET using a plugin<\/a><\/li>\n<li id=\"calibre_link-1769\" class=\"calibre3\"><a href=\"\/#calibre_link-835\">WebAssembly &ndash; a target for Blazor<\/a><\/li>\n<li id=\"calibre_link-1770\" class=\"calibre3\"><a href=\"\/#calibre_link-836\">Blazor hosting models in .NET 7 and earlier<\/a><\/li>\n<li id=\"calibre_link-1771\" class=\"calibre3\"><a href=\"\/#calibre_link-837\">Unification of Blazor hosting models in .NET 8<\/a><\/li>\n<li id=\"calibre_link-1772\" class=\"calibre3\"><a href=\"\/#calibre_link-838\">Understanding Blazor components<\/a><\/li>\n<li id=\"calibre_link-1773\" class=\"calibre3\"><a href=\"\/#calibre_link-839\">What is the difference between Blazor and Razor?<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1774\" class=\"calibre3\"><a href=\"\/#calibre_link-840\">Reviewing the Blazor Web App project template<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1775\" class=\"calibre3\"><a href=\"\/#calibre_link-841\">Creating a Blazor Web App project<\/a><\/li>\n<li id=\"calibre_link-1776\" class=\"calibre3\"><a href=\"\/#calibre_link-842\">Reviewing Blazor routing, layouts, and navigation<\/a><\/li>\n<li id=\"calibre_link-1777\" class=\"calibre3\"><a href=\"\/#calibre_link-843\">How to define a routable page component<\/a><\/li>\n<li id=\"calibre_link-1778\" class=\"calibre3\"><a href=\"\/#calibre_link-844\">How to navigate routes and pass route parameters<\/a><\/li>\n<li id=\"calibre_link-1779\" class=\"calibre3\"><a href=\"\/#calibre_link-845\">How to use the navigation link component with routes<\/a><\/li>\n<li id=\"calibre_link-1780\" class=\"calibre3\"><a href=\"\/#calibre_link-846\">Understanding base component classes<\/a><\/li>\n<li id=\"calibre_link-1781\" class=\"calibre3\"><a href=\"\/#calibre_link-847\">Running the Blazor Web App project template<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1782\" class=\"calibre3\"><a href=\"\/#calibre_link-848\">Building components using Blazor<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1783\" class=\"calibre3\"><a href=\"\/#calibre_link-849\">Defining and testing a simple Blazor component<\/a><\/li>\n<li id=\"calibre_link-1784\" class=\"calibre3\"><a href=\"\/#calibre_link-850\">Using Bootstrap icons<\/a><\/li>\n<li id=\"calibre_link-1785\" class=\"calibre3\"><a href=\"\/#calibre_link-851\">Making the component a routable page component<\/a><\/li>\n<li id=\"calibre_link-1786\" class=\"calibre3\"><a href=\"\/#calibre_link-852\">Getting entities into a component<\/a><\/li>\n<li id=\"calibre_link-1787\" class=\"calibre3\"><a href=\"\/#calibre_link-853\">Abstracting a service for a Blazor component<\/a><\/li>\n<li id=\"calibre_link-1788\" class=\"calibre3\"><a href=\"\/#calibre_link-854\">Enabling streaming rendering<\/a><\/li>\n<li id=\"calibre_link-1789\" class=\"calibre3\"><a href=\"\/#calibre_link-855\">Defining forms using the EditForm component<\/a><\/li>\n<li id=\"calibre_link-1790\" class=\"calibre3\"><a href=\"\/#calibre_link-856\">Building a customer detail component<\/a><\/li>\n<li id=\"calibre_link-1791\" class=\"calibre3\"><a href=\"\/#calibre_link-857\">Building customer create, edit, and delete components<\/a><\/li>\n<li id=\"calibre_link-1792\" class=\"calibre3\"><a href=\"\/#calibre_link-858\">Enabling server-side interactions<\/a><\/li>\n<li id=\"calibre_link-1793\" class=\"calibre3\"><a href=\"\/#calibre_link-859\">Testing the customer components<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1794\" class=\"calibre3\"><a href=\"\/#calibre_link-860\">Enabling client-side execution using WebAssembly<\/a><\/li>\n<li id=\"calibre_link-1795\" class=\"calibre3\"><a href=\"\/#calibre_link-861\">Practicing and exploring<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1796\" class=\"calibre3\"><a href=\"\/#calibre_link-862\">Exercise 16.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1797\" class=\"calibre3\"><a href=\"\/#calibre_link-863\">Exercise 16.2 &ndash; Practice by creating a times table component<\/a><\/li>\n<li id=\"calibre_link-1798\" class=\"calibre3\"><a href=\"\/#calibre_link-864\">Exercise 16.3 &ndash; Practice by creating a country navigation item<\/a><\/li>\n<li id=\"calibre_link-1799\" class=\"calibre3\"><a href=\"\/#calibre_link-865\">Exercise 16.4 &ndash; Enhancing Blazor apps<\/a><\/li>\n<li id=\"calibre_link-1800\" class=\"calibre3\"><a href=\"\/#calibre_link-866\">Exercise 16.5 &ndash; Leveraging open source Blazor component libraries<\/a><\/li>\n<li id=\"calibre_link-1801\" class=\"calibre3\"><a href=\"\/#calibre_link-867\">Exercise 16.6 &ndash; Explore topics<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1802\" class=\"calibre3\"><a href=\"\/#calibre_link-868\">Summary<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1803\" class=\"calibre3\"><a href=\"\/#calibre_link-869\">17 Epilogue<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1804\" class=\"calibre3\"><a href=\"\/#calibre_link-870\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1805\" class=\"calibre3\"><a href=\"\/#calibre_link-871\">Next steps on your C# and .NET learning journey<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1806\" class=\"calibre3\"><a href=\"\/#calibre_link-872\">Polishing your skills with design guidelines<\/a><\/li>\n<li id=\"calibre_link-1807\" class=\"calibre3\"><a href=\"\/#calibre_link-873\">Companion books to continue your learning journey<\/a><\/li>\n<li id=\"calibre_link-1808\" class=\"calibre3\"><a href=\"\/#calibre_link-874\">Other books to take your learning further<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1809\" class=\"calibre3\"><a href=\"\/#calibre_link-875\">The ninth edition, coming November 2024<\/a><\/li>\n<li id=\"calibre_link-1810\" class=\"calibre3\"><a href=\"\/#calibre_link-876\">Good luck!<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1811\" class=\"calibre3\"><a href=\"\/#calibre_link-877\">Appendix: Answers to the Test Your Knowledge Questions<\/a>\n<ol class=\"toc1\">\n<li id=\"calibre_link-1812\" class=\"calibre3\"><a href=\"\/#calibre_link-878\">Join our book community on Discord<\/a><\/li>\n<li id=\"calibre_link-1813\" class=\"calibre3\"><a href=\"\/#calibre_link-879\">Chapter 1 &ndash; Hello, C#! Welcome, .NET!<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1814\" class=\"calibre3\"><a href=\"\/#calibre_link-880\">Exercise 1.1 &ndash; Test your knowledge<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1815\" class=\"calibre3\"><a href=\"\/#calibre_link-881\">Chapter 2 &ndash; Speaking C#<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1816\" class=\"calibre3\"><a href=\"\/#calibre_link-882\">Exercise 2.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1817\" class=\"calibre3\"><a href=\"\/#calibre_link-883\">Exercise 2.2 &ndash; Test your knowledge of number types<\/a><\/li>\n<li id=\"calibre_link-1818\" class=\"calibre3\"><a href=\"\/#calibre_link-884\">Exercise 2.3 &ndash; Practice number sizes and ranges<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1819\" class=\"calibre3\"><a href=\"\/#calibre_link-885\">Chapter 3 &ndash; Controlling Flow, Converting Types, and Handling Exceptions<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1820\" class=\"calibre3\"><a href=\"\/#calibre_link-886\">Exercise 3.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1821\" class=\"calibre3\"><a href=\"\/#calibre_link-887\">Exercise 3.2 &ndash; Explore loops and overflow<\/a><\/li>\n<li id=\"calibre_link-1822\" class=\"calibre3\"><a href=\"\/#calibre_link-888\">Exercise 3.3 &ndash; Test your knowledge of operators<\/a><\/li>\n<li id=\"calibre_link-1823\" class=\"calibre3\"><a href=\"\/#calibre_link-889\">Exercise 3.4 &ndash; Practice loops and operators<\/a><\/li>\n<li id=\"calibre_link-1824\" class=\"calibre3\"><a href=\"\/#calibre_link-890\">Exercise 3.5 &ndash; Practice exception handling<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1825\" class=\"calibre3\"><a href=\"\/#calibre_link-891\">Chapter 4 &ndash; Writing, Debugging, and Testing Functions<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1826\" class=\"calibre3\"><a href=\"\/#calibre_link-892\">Exercise 4.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1827\" class=\"calibre3\"><a href=\"\/#calibre_link-893\">Exercise 4.2 &ndash; Practice writing functions with debugging and unit testing<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1828\" class=\"calibre3\"><a href=\"\/#calibre_link-894\">Chapter 5 &ndash; Building Your Own Types with Object-Oriented Programming<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1829\" class=\"calibre3\"><a href=\"\/#calibre_link-895\">Exercise 5.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1830\" class=\"calibre3\"><a href=\"\/#calibre_link-896\">Exercise 5.2 &ndash; Practice with access modifiers<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1831\" class=\"calibre3\"><a href=\"\/#calibre_link-897\">Chapter 6 &ndash; Implementing Interfaces and Inheriting Classes<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1832\" class=\"calibre3\"><a href=\"\/#calibre_link-898\">Exercise 6.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1833\" class=\"calibre3\"><a href=\"\/#calibre_link-899\">Exercise 6.2 &ndash; Practice creating an inheritance hierarchy<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1834\" class=\"calibre3\"><a href=\"\/#calibre_link-900\">Chapter 7 &ndash; Packaging and Distributing .NET Types<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1835\" class=\"calibre3\"><a href=\"\/#calibre_link-901\">Exercise 7.1 &ndash; Test your knowledge<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1836\" class=\"calibre3\"><a href=\"\/#calibre_link-902\">Chapter 8 &ndash; Working with Common .NET Types<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1837\" class=\"calibre3\"><a href=\"\/#calibre_link-903\">Exercise 8.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1838\" class=\"calibre3\"><a href=\"\/#calibre_link-904\">Exercise 8.2 &ndash; Practice regular expressions<\/a><\/li>\n<li id=\"calibre_link-1839\" class=\"calibre3\"><a href=\"\/#calibre_link-905\">Exercise 8.3 &ndash; Practice writing extension methods<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1840\" class=\"calibre3\"><a href=\"\/#calibre_link-906\">Chapter 9 &ndash; Working with Files, Streams, and Serialization<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1841\" class=\"calibre3\"><a href=\"\/#calibre_link-907\">Exercise 9.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1842\" class=\"calibre3\"><a href=\"\/#calibre_link-908\">Exercise 9.2 &ndash; Practice serializing as XML<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1843\" class=\"calibre3\"><a href=\"\/#calibre_link-909\">Chapter 10 &ndash; Working with Data Using Entity Framework Core<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1844\" class=\"calibre3\"><a href=\"\/#calibre_link-910\">Exercise 10.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1845\" class=\"calibre3\"><a href=\"\/#calibre_link-911\">Exercise 10.2 &ndash; Exporting data using different serialization formats<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1846\" class=\"calibre3\"><a href=\"\/#calibre_link-912\">Chapter 11 &ndash; Querying and Manipulating Data Using LINQ<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1847\" class=\"calibre3\"><a href=\"\/#calibre_link-913\">Exercise 11.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1848\" class=\"calibre3\"><a href=\"\/#calibre_link-914\">Exercise 11.2 &ndash; Practice querying with LINQ<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1849\" class=\"calibre3\"><a href=\"\/#calibre_link-915\">Chapter 12 &ndash; Introducing Web Development Using ASP.NET Core<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1850\" class=\"calibre3\"><a href=\"\/#calibre_link-916\">Exercise 12.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1851\" class=\"calibre3\"><a href=\"\/#calibre_link-917\">Exercise 12.2 &ndash; Know your webbreviations<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1852\" class=\"calibre3\"><a href=\"\/#calibre_link-918\">Chapter 13 &ndash; Building Websites Using ASP. NET Core Razor Pages<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1853\" class=\"calibre3\"><a href=\"\/#calibre_link-919\">Exercise 13.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1854\" class=\"calibre3\"><a href=\"\/#calibre_link-920\">Exercise 13.4 &ndash; Practice building a data-driven web page<\/a><\/li>\n<li id=\"calibre_link-1855\" class=\"calibre3\"><a href=\"\/#calibre_link-921\">Exercise 13.5 &ndash; Practice building web pages for functions<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1856\" class=\"calibre3\"><a href=\"\/#calibre_link-922\">Chapter 14 &ndash; Building Websites Using the Model-View-Controller Pattern<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1857\" class=\"calibre3\"><a href=\"\/#calibre_link-923\">Exercise 14.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1858\" class=\"calibre3\"><a href=\"\/#calibre_link-924\">Exercise 14.2 &ndash; Practice implementing MVC by implementing a category detail page<\/a><\/li>\n<li id=\"calibre_link-1859\" class=\"calibre3\"><a href=\"\/#calibre_link-925\">Exercise 14.4 &ndash; Practice unit testing MVC controllers<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1860\" class=\"calibre3\"><a href=\"\/#calibre_link-926\">Chapter 15 &ndash; Building and Consuming Web Services<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1861\" class=\"calibre3\"><a href=\"\/#calibre_link-927\">Exercise 15.1 &ndash; Test your knowledge<\/a><\/li>\n<li id=\"calibre_link-1862\" class=\"calibre3\"><a href=\"\/#calibre_link-928\">Exercise 15.2 &ndash; Practice creating and deleting customers with HttpClient<\/a><\/li>\n<\/ol>\n<\/li>\n<li id=\"calibre_link-1863\" class=\"calibre3\"><a href=\"\/#calibre_link-929\">Chapter 16 &ndash; Building User Interfaces Using Blazor<\/a>\n<ol class=\"toc2\">\n<li id=\"calibre_link-1864\" class=\"calibre3\"><a href=\"\/#calibre_link-930\">Exercise 16.1 &ndash; Test your knowledge<\/a><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/nav>\n<nav type=\"landmarks\" hidden=\"hidden\" id=\"calibre_link-1865\">\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<a type=\"cover\" href=\"\/text\/cover.xhtml\">Cover<\/a>\n<\/li>\n<li class=\"calibre3\">\n<a type=\"toc\" href=\"\/#calibre_link-931\">Table of contents<\/a>\n<\/li>\n<\/ol>\n<\/nav>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-3\">\n<div id=\"calibre_link-1866\" class=\"calibre1\">\n<section data-number=\"1\" id=\"calibre_link-11\">\n<h1 data-number=\"1\" class=\"title\">C# 12 and .NET 8 &ndash; Modern Cross-Platform Development Fundamentals, Eighth Edition: Start building websites and services with ASP.NET Core 8, Blazor, and EF Core 8<\/h1>\n<p class=\"rights\"><strong class=\"calibre2\">Welcome to Packt Early Access<\/strong>. We\u2019re giving you an exclusive preview of this book before it goes on sale. It can take many months to write a book, but our authors have cutting-edge information to share with you today. Early Access gives you an insight into the latest developments by making chapter drafts available. The chapters may be a little rough around the edges right now, but our authors will update them over time.You can dip in and out of\u202fthis book\u202for\u202ffollow along\u202ffrom start to finish; Early Access is designed to be flexible. We hope you enjoy getting to know more about the process of writing a Packt book.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Chapter 1: Hello, C#! Welcome, .NET!<\/li>\n<li class=\"calibre3\">Chapter 2: Speaking C#<\/li>\n<li class=\"calibre3\">Chapter 3: Controlling Flow, Converting Types, and Handling Exceptions<\/li>\n<li class=\"calibre3\">Chapter 4: Writing, Debugging, and Testing Functions<\/li>\n<li class=\"calibre3\">Chapter 5: Building Your Own Types with Object-Oriented Programming<\/li>\n<li class=\"calibre3\">Chapter 6: Implementing Interfaces and Inheriting Classes<\/li>\n<li class=\"calibre3\">Chapter 7: Packaging and Distributing .NET Types<\/li>\n<li class=\"calibre3\">Chapter 8: Working with Common .NET Types<\/li>\n<li class=\"calibre3\">Chapter 9: Working with Files, Streams, and Serialization<\/li>\n<li class=\"calibre3\">Chapter 10: Working with Data Using Entity Framework Core<\/li>\n<li class=\"calibre3\">Chapter 11: Querying and Manipulating Data Using LINQ<\/li>\n<li class=\"calibre3\">Chapter 12: Introducing Web Development Using ASP.NET Core<\/li>\n<li class=\"calibre3\">Chapter 13: Building Websites Using ASP.NET Core Razor Pages<\/li>\n<li class=\"calibre3\">Chapter 14: Building Websites Using the Model-View-Controller Pattern<\/li>\n<li class=\"calibre3\">Chapter 15: Building and Consuming Web Services<\/li>\n<li class=\"calibre3\">Chapter 16: Building User Interfaces Using\u202fBlazor<\/li>\n<\/ol>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-0\">\n<div id=\"calibre_link-1867\" class=\"calibre1\">\n<section data-number=\"2\" id=\"calibre_link-12\">\n<h1 data-number=\"2\" class=\"title\">1 Hello, C#! Welcome, .NET!<\/h1>\n<section data-number=\"2.1\" id=\"calibre_link-13\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"2.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000005.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">In this first chapter, the goals are setting up your development environment; understanding the similarities and differences between modern .NET, .NET Core, .NET Framework, Mono, Xamarin, and .NET Standard; creating the simplest application possible with C# 12 and .NET 8 using various code editors; and then discovering good places to look for help.This chapter covers the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Introducing this book and its contents<\/li>\n<li class=\"calibre3\">Setting up your development environment<\/li>\n<li class=\"calibre3\">Understanding .NET<\/li>\n<li class=\"calibre3\">Building console apps using Visual Studio 2022<\/li>\n<li class=\"calibre3\">Building console apps using Visual Studio Code<\/li>\n<li class=\"calibre3\">Making good use of the GitHub repository for this book<\/li>\n<li class=\"calibre3\">Looking for help<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"2.2\" id=\"calibre_link-14\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"2.2\" class=\"calibre5\">Introducing this book and its contents<\/h2>\n<p class=\"rights\">Let's get started by introducing you to the code solutions and structure of this book.<\/p>\n<section data-number=\"2.2.1\" id=\"calibre_link-15\">\n<h3 data-number=\"2.2.1\" class=\"calibre8\">Getting code solutions for this book<\/h3>\n<p class=\"rights\">The GitHub repository for this book has solutions using full application projects for all code tasks and exercises, found at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\">https:\/\/github.com\/markjprice\/cs12dotnet8<\/a>After navigating to the GitHub repository in your web browser, press the <code class=\"calibre9\">.<\/code> (dot) key on your keyboard, or manually change <code class=\"calibre9\">.com<\/code> to <code class=\"calibre9\">.dev<\/code> in the link to convert the repository into a live code editor based on Visual Studio Code using GitHub Codespaces, as shown in <em class=\"calibre10\">Figure 1.1<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.1: GitHub Codespaces live editing the book&apos;s GitHub repository\" height=\"424\" src=\"\/images\/cs12\/000164.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.1: GitHub Codespaces live editing the book's GitHub repository<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">We provide you with a PDF file that has color images of the screenshots and diagrams used in this book. You can download this file from <a href=\"https:\/\/static.packt-cdn.com\/downloads\/???_ColorImages.pdf\">https:\/\/static.packt-cdn.com\/downloads\/???_ColorImages.pdf<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Visual Studio Code in a web browser is great to run alongside your chosen local code editor as you work through the book's coding tasks. You can compare your code to the solution code and easily copy and paste parts if needed.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You do not need to use or know anything about Git to get the solution code of this book. You can download a ZIP file containing all the code solutions by using the following direct link and then extract the ZIP file into your local filesystem: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/archive\/refs\/heads\/main.zip\">https:\/\/github.com\/markjprice\/cs12dotnet8\/archive\/refs\/heads\/main.zip<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.2.2\" id=\"calibre_link-16\">\n<h3 data-number=\"2.2.2\" class=\"calibre8\">.NET terms used in this book<\/h3>\n<p class=\"rights\">Throughout this book, I use the term <strong class=\"calibre2\">modern .NET<\/strong> to refer to .NET 8 and its predecessors like .NET 6 that derive from .NET Core. I use the term <strong class=\"calibre2\">legacy .NET<\/strong> to refer to .NET Framework, Mono, Xamarin, and .NET Standard. Modern .NET is a unification of those legacy platforms and standards.<\/p>\n<\/section>\n<section data-number=\"2.2.3\" id=\"calibre_link-17\">\n<h3 data-number=\"2.2.3\" class=\"calibre8\">The structure and style of this book<\/h3>\n<p class=\"rights\">After this first chapter, the book can be divided into three parts: language, libraries, and web development.First, the grammar and vocabulary of the C# language; second, the types available in the .NET libraries for building app features; and third, the fundamentals of cross-platform websites, services, and browser apps that you can build using C# and .NET.Most people learn complex topics best by imitation and repetition rather than reading a detailed explanation of the theory; therefore, I will not overload you with detailed explanations of every step throughout this book. The idea is to get you to write some code and see it run.You don't need to know all the nitty-gritty details immediately. That will be something that comes with time as you build your own apps and go beyond what any book can teach you.In the words of Samuel Johnson, author of the English dictionary in 1755, I have committed \"a few wild blunders, and risible absurdities, from which no work of such multiplicity is free.\" I take sole responsibility for these and hope you appreciate the challenge of my attempt to lash the wind by writing this book about rapidly evolving technologies like C# and .NET, and the apps that you can build with them.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you have a complaint about this book, then please contact me before writing a negative review on Amazon. Authors cannot respond to Amazon reviews so I cannot contact you to resolve the problem and help you or listen to your feedback and try to do better in the next edition. Please ask a question on the Discord channel for this book at <a href=\"https:\/\/packt.link\/cs12dotnet8\">https:\/\/packt.link\/cs12dotnet8<\/a>, email me at <code class=\"calibre9\">markjprice@gmail.com<\/code>, or raise an issue in the GitHub repository for the book at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/issues\">https:\/\/github.com\/markjprice\/cs12dotnet8\/issues<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.2.4\" id=\"calibre_link-18\">\n<h3 data-number=\"2.2.4\" class=\"calibre8\">Topics covered by this book<\/h3>\n<p class=\"rights\">The following topics are covered in this book:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Language fundamentals<\/strong>: Fundamental features of the C# language, from declaring variables to writing functions and object-oriented programming.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Library fundamentals<\/strong>: Fundamental features of the .NET base class library as well as some important optional packages for common tasks like database access.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Web development fundamentals<\/strong>: Fundamental features of the ASP.NET Core framework for server-side and client-side website and web service development.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"2.2.5\" id=\"calibre_link-19\">\n<h3 data-number=\"2.2.5\" class=\"calibre8\">Topics covered by Apps and Services with .NET 8<\/h3>\n<p class=\"rights\">The following topics are available in a companion book, <em class=\"calibre10\">Apps and Services with .NET 8<\/em>:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Data<\/strong>: SQL Server, Azure Cosmos DB.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Specialized libraries<\/strong>: Dates, times, time zones, and internationalization; common third-party libraries for image handling, logging, mapping, and generating PDFs; multitasking and concurrency; and many more.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Services<\/strong>: Caching, queuing, background services, gRPC, GraphQL, Azure Functions, SignalR, and Minimal APIs.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">User Interfaces<\/strong>: ASP.NET Core, Blazor, and .NET MAUI.<\/li>\n<\/ul>\n<p class=\"rights\">This book, <em class=\"calibre10\">C# 12 and .NET 8 &ndash; Modern Cross-Platform Development Fundamentals<\/em>, is best read linearly, chapter by chapter, because it builds up fundamental skills and knowledge. The companion book, <em class=\"calibre10\">Apps and Services with .NET 8<\/em>, can be read more like a cookbook, so if you are especially interested in building gRPC services, then you could read that chapter without the preceding chapters about Minimal API services. To see a list of all books I have published with Packt, you can use the following link:<a href=\"https:\/\/subscription.packtpub.com\/search?query=mark+j.+price\">https:\/\/subscription.packtpub.com\/search?query=mark+j.+price<\/a>A similar list is available on Amazon:<a href=\"https:\/\/www.amazon.com\/Mark-J-Price\/e\/B071DW3QGN\/\">https:\/\/www.amazon.com\/Mark-J-Price\/e\/B071DW3QGN\/<\/a>You can search other book-selling sites for my books too.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"2.3\" id=\"calibre_link-20\">\n<h2 data-number=\"2.3\" class=\"calibre5\">Setting up your development environment<\/h2>\n<p class=\"rights\">Before you start programming, you'll need a code editor for C#. Microsoft has a family of code editors and <strong class=\"calibre2\">Integrated Development Environments<\/strong> (<strong class=\"calibre2\">IDEs<\/strong>), which include:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Visual Studio 2022 for Windows<\/li>\n<li class=\"calibre3\">Visual Studio Code for Windows, Mac, or Linux<\/li>\n<li class=\"calibre3\">Visual Studio Code for the Web or GitHub Codespaces<\/li>\n<\/ul>\n<p class=\"rights\">Third parties have created their own C# code editors, for example, JetBrains Rider, which is available for Windows, Mac, or Linux but does have a license cost. JetBrains Rider is popular with more experienced .NET developers.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Although JetBrains is a fantastic company with great products, both Rider and the ReSharper extension for Visual Studio are software, and all software has bugs and quirky behavior. For example, they might show errors like \"Cannot resolve symbol\" in your Razor Pages, Razor views, and Blazor components. Yet you can build and run those files because there is no actual problem. If you have installed the Unity Support plugin then it will complain about boxing operations (which are a genuine problem for Unity game developers), but in projects that are not Unity so the warning does not apply.<\/p>\n<\/blockquote>\n<section data-number=\"2.3.1\" id=\"calibre_link-21\">\n<h3 data-number=\"2.3.1\" class=\"calibre8\">Choosing the appropriate tool and application type for learning<\/h3>\n<p class=\"rights\">What is the best tool and application type for learning C# and .NET?When learning, the best tool is one that helps you write code and configuration but does not hide what is really happening. IDEs provide graphical user interfaces that are friendly to use, but what are they doing for you underneath? A more basic code editor that is closer to the action while providing help to write your code can be better while you are learning.Having said that, you can make the argument that the best tool is the one you are already familiar with or that you or your team will use as your daily development tool. For that reason, I want you to be free to choose any C# code editor or IDE to complete the coding tasks in this book, including Visual Studio Code, Visual Studio 2022, or even JetBrains Rider.In this book, I give detailed step-by-step instructions in <em class=\"calibre10\">Chapter 1<\/em> for how to create multiple projects in both Visual Studio 2022 for Windows and Visual Studio Code. There are also links to online instructions for other code editors, as shown at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/code-editors\/README.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/code-editors\/README.md<\/a>.In subsequent chapters, I will only give the names of projects along with general instructions so you can use whichever tool you prefer. The best application type for learning the C# language constructs and many of the .NET libraries is one that does not distract with unnecessary application code. For example, there is no need to create an entire Windows desktop application or a website just to learn how to write a <code class=\"calibre9\">switch<\/code> statement.For that reason, I believe the best method for learning the C# and .NET topics in <em class=\"calibre10\">Chapters 1<\/em> to <em class=\"calibre10\">11<\/em> is to build console apps. Then, in <em class=\"calibre10\">Chapters 12<\/em> to <em class=\"calibre10\">16<\/em>, you will build websites, services, and web browser apps.<\/p>\n<section data-number=\"2.3.1.1\" id=\"calibre_link-1868\">\n<h4 data-number=\"2.3.1.1\" class=\"calibre15\">Pros and cons of the Polyglot Notebooks extension<\/h4>\n<p class=\"rights\">The <strong class=\"calibre2\">Polyglot Notebooks<\/strong> extension for Visual Studio Code provides an easy and safe place to write simple code snippets for experimenting and learning. For example, data scientists use them to analyze and visualize data. Students use them to learn how to write small pieces of code for language constructs and to explore APIs. Polyglot Notebooks enables you to create a single notebook file that mixes \"cells\" of Markdown (richly formatted text) and code using C# and other related languages, such as PowerShell, F#, and SQL (for databases). The extension does this by hosting an instance of the <strong class=\"calibre2\">.NET Interactive<\/strong> engine.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The old legacy name for the <strong class=\"calibre2\">Polyglot Notebooks<\/strong> extension was the <strong class=\"calibre2\">.NET Interactive<\/strong> <strong class=\"calibre2\">Notebooks<\/strong> extension but it was renamed because it is not limited to only .NET languages like C# and F#. The extension retains its original identifier, <code class=\"calibre9\">ms-dotnettools.dotnet-interactive-vscode<\/code>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Polyglot Notebooks have some limitations:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">They cannot be used to create websites, services, and apps.<\/li>\n<li class=\"calibre3\">You cannot use <code class=\"calibre9\">Console<\/code> class methods like <code class=\"calibre9\">ReadLine<\/code> or <code class=\"calibre9\">ReadKey<\/code> to get input from the user. (But there are alternative methods that you will learn if you complete the optional online-only exercise at the end of this chapter.)<\/li>\n<li class=\"calibre3\">They cannot have arguments passed to them.<\/li>\n<li class=\"calibre3\">They do not allow you to define your own namespaces.<\/li>\n<li class=\"calibre3\">They do not have any debugging tools (yet).<\/li>\n<\/ul>\n<p class=\"rights\">At the end of this chapter, you will have the opportunity to complete an optional exercise to practice using Polyglot Notebooks.<\/p>\n<\/section>\n<section data-number=\"2.3.1.2\" id=\"calibre_link-1869\">\n<h4 data-number=\"2.3.1.2\" class=\"calibre15\">Visual Studio Code for cross-platform development<\/h4>\n<p class=\"rights\">The most modern and lightweight code editor to choose from, and the only one from Microsoft that is cross-platform, is Visual Studio Code. It can run on all common operating systems, including Windows, macOS, and many varieties of Linux, including <strong class=\"calibre2\">Red Hat Enterprise Linux<\/strong> (<strong class=\"calibre2\">RHEL<\/strong>) and Ubuntu.Visual Studio Code is a good choice for modern cross-platform development because it has an extensive and growing set of extensions to support many languages beyond C#. The most important extension for C# and .NET developers is the <strong class=\"calibre2\">C# Dev Kit<\/strong> that was released in preview in June 2023 because it turns Visual Studio Code from a general-purpose code editor into a tool optimized for C# and .NET developers.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can read about the <strong class=\"calibre2\">C# Dev Kit<\/strong> extension in the official announcement at the following link: <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/announcing-csharp-dev-kit-for-visual-studio-code\/\">https:\/\/devblogs.microsoft.com\/visualstudio\/announcing-csharp-dev-kit-for-visual-studio-code\/<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Being cross-platform and lightweight, Visual Studio Code and its extensions can be installed on all platforms that your apps will be deployed to for quick bug fixes and so on. Choosing Visual Studio Code means a developer can use a cross-platform code editor to develop cross-platform apps. Visual Studio Code is supported on ARM processors so that you can develop on Apple Silicon computers and Raspberry Pi computers.Visual Studio Code has strong support for web development, although it currently has weak support for mobile and desktop development.Visual Studio Code is by far the most popular code editor or IDE, with over 73% of professional developers selecting it in the Stack Overflow 2023 survey that you can read at the following link: <a href=\"https:\/\/survey.stackoverflow.co\/2023\/\">https:\/\/survey.stackoverflow.co\/2023\/<\/a>.<\/p>\n<\/section>\n<section data-number=\"2.3.1.3\" id=\"calibre_link-1870\">\n<h4 data-number=\"2.3.1.3\" class=\"calibre15\">GitHub Codespaces for development in the cloud<\/h4>\n<p class=\"rights\">GitHub Codespaces is a fully configured development environment based on Visual Studio Code that can be spun up in an environment hosted in the cloud and accessed through any web browser. It supports Git repos, extensions, and a built-in command-line interface so you can edit, run, and test from any device.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about GitHub Codespaces at the following link: <a href=\"https:\/\/github.com\/features\/codespaces\">https:\/\/github.com\/features\/codespaces<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.3.1.4\" id=\"calibre_link-1871\">\n<h4 data-number=\"2.3.1.4\" class=\"calibre15\">Visual Studio 2022 for general development<\/h4>\n<p class=\"rights\">Visual Studio 2022 for Windows can create most types of applications, including console apps, websites, web services, desktop, and mobile apps. Although you can use Visual Studio 2022 for Windows to write a cross-platform mobile app, you still need macOS and Xcode to compile it.It only runs on Windows 10 version 1909 or later, Home, Professional, Education, or Enterprise; or on Windows 11 version 21H2 or later, Home, Pro, Pro Education, Pro for Workstations, Enterprise, or Education. Windows Server 2016 and later are also supported. 32-bit operating systems and Windows S mode are <em class=\"calibre10\">not<\/em> supported.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Visual Studio 2022 for Mac does not officially support .NET 8 and it will reach end-of-life in August 2024. If you have been using Visual Studio 2022 for Mac then you should switch to Visual Studio Code for Mac, JetBrains Rider for Mac, or use Visual Studio 2022 for Windows in a virtual machine on your local computer or in the cloud using a technology like Microsoft Dev Box. The retirement announcement can be read here: <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/visual-studio-for-mac-retirement-announcement\/\">https:\/\/devblogs.microsoft.com\/visualstudio\/visual-studio-for-mac-retirement-announcement\/<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.3.1.5\" id=\"calibre_link-1872\">\n<h4 data-number=\"2.3.1.5\" class=\"calibre15\">What I used<\/h4>\n<p class=\"rights\">To write and test the code for this book, I used the following hardware and software:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Visual Studio 2022 for Windows on:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Windows 11 on an HP Spectre (Intel) laptop<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Visual Studio Code on:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">macOS on an Apple Silicon Mac mini (M1) desktop<\/li>\n<li class=\"calibre3\">Windows 11 on an HP Spectre (Intel) laptop<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">JetBrains Rider on:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">macOS on an Apple Silicon Mac mini (M1) desktop<\/li>\n<li class=\"calibre3\">Windows 11 on an HP Spectre (Intel) laptop<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p class=\"rights\">I hope that you have access to a variety of hardware and software too, because seeing the differences in platforms deepens your understanding of development challenges, although any one of the above combinations is enough to learn the fundamentals of C# and .NET and how to build practical apps and websites.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can learn how to write code with C# and .NET using a Raspberry Pi 400 with Ubuntu Desktop 64-bit by reading an extra article that I wrote at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/docs\/raspberry-pi-ubuntu64\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/docs\/raspberry-pi-ubuntu64<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"2.3.2\" id=\"calibre_link-22\">\n<h3 data-number=\"2.3.2\" class=\"calibre8\">Deploying cross-platform<\/h3>\n<p class=\"rights\">Your choice of code editor and operating system for development does not limit where your code gets deployed..NET 8 supports the following platforms for deployment:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Windows<\/strong>: Windows 10 version 1607 or later. Windows 11 version 22000 or later. Windows Server 2012 R2 SP1 or later. Nano Server version 1809 or later.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Mac<\/strong>: macOS Catalina version 10.15 or later and in the Rosetta 2 x64 emulator.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Linux<\/strong>: Alpine Linux 3.17 or later. Debian 11 or later. Fedora 37 or later. openSUSE 15 or later. Oracle Linux 8 or later. RHEL 8 or later. SUSE Enterprise Linux 12 SP2 or later. Ubuntu 20.04 or later.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Android<\/strong>: API 21 or later.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">iOS<\/strong> and <strong class=\"calibre2\">tvOS<\/strong>: 11.0 or later.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">MacCatalyst<\/strong>: 10.15 or later. 11.0 or later on Arm64.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> .NET support for Windows 7 and 8.1 ended in January 2023: <a href=\"https:\/\/github.com\/dotnet\/core\/issues\/7556\">https:\/\/github.com\/dotnet\/core\/issues\/7556<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Windows Arm64 support in .NET 5 and later means you can develop on, and deploy to, Windows Arm devices like Microsoft's Windows Dev Kit 2023 (formerly known as Project Volterra) and Surface Pro X.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can review the latest supported operating systems and versions at the following link: <a href=\"https:\/\/github.com\/dotnet\/core\/blob\/main\/release-notes\/8.0\/supported-os.md\">https:\/\/github.com\/dotnet\/core\/blob\/main\/release-notes\/8.0\/supported-os.md<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.3.3\" id=\"calibre_link-23\">\n<h3 data-number=\"2.3.3\" class=\"calibre8\">Downloading and installing Visual Studio 2022<\/h3>\n<p class=\"rights\">Many professional .NET developers use Visual Studio 2022 for Windows in their day-to-day development work. Even if you choose to use Visual Studio Code to complete the coding tasks in this book, you might want to familiarize yourself with Visual Studio 2022 for Windows too. It is not until you have written a decent amount of code with a tool that you can really judge if it fits your needs.If you do not have a Windows computer, then you can skip this section and continue to the next section where you will download and install Visual Studio Code on macOS or Linux.Since October 2014, Microsoft has made a professional-quality edition of Visual Studio available to students, open-source contributors, and individuals for free. It is called Community Edition. Any of the editions are suitable for this book. If you have not already installed it, let's do so now:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Download Microsoft Visual Studio 2022 version 17.8 or later for Windows from the following link: <a href=\"https:\/\/visualstudio.microsoft.com\/downloads\/\">https:\/\/visualstudio.microsoft.com\/downloads\/<\/a>.<\/li>\n<li class=\"calibre3\">Run the installer to start the installation.<\/li>\n<li class=\"calibre3\">On the <strong class=\"calibre2\">Workloads<\/strong> tab, select the following:\n<ul class=\"calibre16\">\n<li class=\"calibre3\"><strong class=\"calibre2\">ASP.NET and web development<\/strong>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">.NET desktop development<\/strong> (because this includes console apps).<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Desktop development with C++<\/strong> with all default components (because this enables publishing console apps and web services that start faster and have smaller memory footprints).<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Install<\/strong> and wait for the installer to acquire the selected software and install it.<\/li>\n<li class=\"calibre3\">When the installation is complete, click <strong class=\"calibre2\">Launch<\/strong>.<\/li>\n<li class=\"calibre3\">The first time that you run Visual Studio, you will be prompted to sign in. If you have a Microsoft account, you can use that account. If you don't, then register for a new one at the following link: <a href=\"https:\/\/signup.live.com\/\">https:\/\/signup.live.com\/<\/a>.<\/li>\n<li class=\"calibre3\">The first time that you run Visual Studio, you will be prompted to configure your environment. For <strong class=\"calibre2\">Development Settings<\/strong>, choose <strong class=\"calibre2\">Visual C#<\/strong>. For the color theme, I chose <strong class=\"calibre2\">Blue<\/strong>, but you can choose whatever tickles your fancy.<\/li>\n<li class=\"calibre3\">If you want to customize your keyboard shortcuts, navigate to <strong class=\"calibre2\">Tools<\/strong> | <strong class=\"calibre2\">Options\u2026<\/strong>, and then select the <strong class=\"calibre2\">Keyboard<\/strong> section.<\/li>\n<\/ol>\n<section data-number=\"2.3.3.1\" id=\"calibre_link-1873\">\n<h4 data-number=\"2.3.3.1\" class=\"calibre15\">Keyboard shortcuts for Visual Studio 2022 for Windows<\/h4>\n<p class=\"rights\">In this book, I will avoid showing keyboard shortcuts since they are often customized. Where they are consistent across code editors and commonly used, I will try to show them. If you want to identify and customize your keyboard shortcuts, then you can, as shown at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/visualstudio\/ide\/identifying-and-customizing-keyboard-shortcuts-in-visual-studio\">https:\/\/learn.microsoft.com\/en-us\/visualstudio\/ide\/identifying-and-customizing-keyboard-shortcuts-in-visual-studio<\/a>.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"2.3.4\" id=\"calibre_link-24\">\n<h3 data-number=\"2.3.4\" class=\"calibre8\">Downloading and installing Visual Studio Code<\/h3>\n<p class=\"rights\">Visual Studio Code has rapidly improved over the past couple of years and has pleasantly surprised Microsoft with its popularity. If you are brave and like to live on the bleeding edge, then there is the <strong class=\"calibre2\">Insiders<\/strong> edition, which is a daily build of the next version.Even if you plan to only use Visual Studio 2022 for Windows for development, I recommend that you download and install Visual Studio Code and try the coding tasks in this chapter using it, and then decide if you want to stick with just using Visual Studio 2022 for the rest of the book.Let's now download and install Visual Studio Code, the .NET SDK, and the C# Dev Kit extension:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Download and install either the Stable build or the Insiders edition of Visual Studio Code from the following link: <a href=\"https:\/\/code.visualstudio.com\/\">https:\/\/code.visualstudio.com\/<\/a>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: If you need more help installing Visual Studio Code, you can read the official setup guide at the following link: <a href=\"https:\/\/code.visualstudio.com\/docs\/setup\/setup-overview\">https:\/\/code.visualstudio.com\/docs\/setup\/setup-overview<\/a>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Download and install the .NET SDKs for version 8.0 and at least one other version like 6.0 or 7.0 from the following link: <a href=\"https:\/\/www.microsoft.com\/net\/download\">https:\/\/www.microsoft.com\/net\/download<\/a>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In real life, you are extremely unlikely to only have one .NET SDK version installed on your computer. To learn how to control which .NET SDK version is used to build a project, we need multiple versions installed. .NET 6, .NET 7, and .NET 8 are supported versions at the time of publishing in November 2023. You can safely install multiple SDKs side by side. The most recent SDK will be used to build your projects.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">To install the <strong class=\"calibre2\">C# Dev Kit<\/strong> extension with a user interface, you must first launch the Visual Studio Code application.<\/li>\n<li class=\"calibre3\">In Visual Studio Code, click the <strong class=\"calibre2\">Extensions<\/strong> icon or navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Extensions<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\"><strong class=\"calibre2\">C# Dev Kit<\/strong> is one of the most popular extensions available, so you should see it at the top of the list, and you can enter <code class=\"calibre9\">C#<\/code> in the search box.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">C# Dev Kit<\/strong> has a dependency on the <strong class=\"calibre2\">C#<\/strong> extension version 2.0 or later, so you do not have to install the <strong class=\"calibre2\">C#<\/strong> extension separately. Note that <strong class=\"calibre2\">C#<\/strong> extension version 2.0 or later no longer uses OmniSharp since it has a new <strong class=\"calibre2\">Language Service Protocol (LSP)<\/strong> host. <strong class=\"calibre2\">C# Dev Kit<\/strong> also has dependencies on the <strong class=\"calibre2\">.NET Install Tool for Extension Authors<\/strong> and <strong class=\"calibre2\">IntelliCode for C# Dev Kit<\/strong> extensions so they will be installed too.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Install<\/strong> and wait for supporting packages to download and install.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Be sure to read the license agreement for the <strong class=\"calibre2\">C# Dev Kit<\/strong>. It has a more restrictive license than the <strong class=\"calibre2\">C#<\/strong> extension: <a href=\"https:\/\/aka.ms\/vs\/csdevkit\/license\">https:\/\/aka.ms\/vs\/csdevkit\/license<\/a>.<\/p>\n<\/blockquote>\n<section data-number=\"2.3.4.1\" id=\"calibre_link-1874\">\n<h4 data-number=\"2.3.4.1\" class=\"calibre15\">Installing other extensions<\/h4>\n<p class=\"rights\">In later chapters of this book, you will use more Visual Studio Code extensions. If you want to install them now, all the extensions that we will use are shown in <em class=\"calibre10\">Table 1.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre19\"><\/col>\n<col class=\"calibre19\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Extension name and identifier<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><strong class=\"calibre2\">C# Dev Kit<\/strong><\/p>\n<p class=\"rights\"><code class=\"calibre9\">ms-dotnettools.csdevkit<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Official C# extension from Microsoft. Manage your code with a solution explorer and test your code with integrated unit test discovery and execution.<\/p>\n<p class=\"rights\">Includes the <strong class=\"calibre2\">C#<\/strong> and <strong class=\"calibre2\">IntelliCode for C# Dev Kit<\/strong> extensions.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><strong class=\"calibre2\">C#<\/strong><\/p>\n<p class=\"rights\"><code class=\"calibre9\">ms-dotnettools.csharp<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">C# editing support, including syntax highlighting, IntelliSense, Go To Definition, Find All References, debugging support for .NET, and support for <code class=\"calibre9\">csproj<\/code> projects on Windows, macOS, and Linux.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><strong class=\"calibre2\">IntelliCode for C# Dev Kit<\/strong><\/p>\n<p class=\"rights\"><code class=\"calibre9\">ms-dotnettools.vscodeintellicode-csharp<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">Provides AI-assisted development features for Python, TypeScript\/JavaScript, C#, and Java developers.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><strong class=\"calibre2\">MSBuild project tools<\/strong><\/p>\n<p class=\"rights\"><code class=\"calibre9\">tintoy.msbuild-project-tools<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">Provides IntelliSense for MSBuild project files, including autocomplete for <code class=\"calibre9\">&lt;PackageReference&gt;<\/code> elements.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><strong class=\"calibre2\">Polyglot Notebooks<\/strong><\/p>\n<p class=\"rights\"><code class=\"calibre9\">ms-dotnettools.dotnet-interactive-vscode<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">This extension adds support for using .NET and other languages in a notebook. It has a dependency on the <strong class=\"calibre2\">Jupyter<\/strong> extension ( <code class=\"calibre9\">ms-toolsai.jupyter<\/code> ), which itself has dependencies.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><strong class=\"calibre2\">ilspy-vscode<\/strong><\/p>\n<p class=\"rights\"><code class=\"calibre9\">icsharpcode.ilspy-vscode<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">Decompile MSIL assemblies &ndash; support for modern .NET, .NET Framework, .NET Core, and .NET Standard.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><strong class=\"calibre2\">REST Client<\/strong><\/p>\n<p class=\"rights\"><code class=\"calibre9\">humao.rest-client<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">Send an HTTP request and view the response directly in Visual Studio Code.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 1.1: Visual Studio Code extensions used in this book<br \/>\n<\/section>\n<section data-number=\"2.3.4.2\" id=\"calibre_link-1875\">\n<h4 data-number=\"2.3.4.2\" class=\"calibre15\">Managing Visual Studio Code extensions at the command prompt<\/h4>\n<p class=\"rights\">You can install a Visual Studio Code extension at the command prompt or terminal, as shown in <em class=\"calibre10\">Table 1.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Command<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">code --list-extensions<\/code><\/td>\n<td class=\"calibre21\">List installed extensions.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">code --install-extension &lt;extension-id&gt;<\/code><\/td>\n<td class=\"calibre21\">Install the specified extension.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">code --uninstall-extension &lt;extension-id&gt;<\/code><\/td>\n<td class=\"calibre21\">Uninstall the specified extension.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 1.2: Commands to list, install, and uninstall extensions<\/p>\n<p class=\"rights\">For example, to install the <strong class=\"calibre2\">C# Dev Kit<\/strong> extension, enter the following at the command prompt:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">code --install-extension ms-dotnettools.csdevkit<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">I have created PowerShell scripts to install and uninstall the Visual Studio Code extensions in the preceding table. You can find them at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/scripts\/extension-scripts\/\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/scripts\/extension-scripts\/<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.3.4.3\" id=\"calibre_link-1876\">\n<h4 data-number=\"2.3.4.3\" class=\"calibre15\">Understanding Visual Studio Code versions<\/h4>\n<p class=\"rights\">Microsoft releases a new feature version of Visual Studio Code (almost) every month and bug-fix versions more frequently. For example:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Version 1.79.0, May 2023 feature release<\/li>\n<li class=\"calibre3\">Version 1.79.1, May 2023 bug fix release<\/li>\n<\/ul>\n<p class=\"rights\">The version used in this book is 1.82.1, August 2023 feature release, but the version of Visual Studio Code is less important than the version of the <strong class=\"calibre2\">C# Dev Kit<\/strong> or <strong class=\"calibre2\">C#<\/strong> extension that you install. I recommend <strong class=\"calibre2\">C#<\/strong> extension v2.2.10 or later and C# Dev Kit v0.4.10 or later.While the <strong class=\"calibre2\">C#<\/strong> extension is not required, it provides IntelliSense as you type, code navigation, and debugging features, so it's something that's very handy to install and keep updated to support the latest C# language features.<\/p>\n<\/section>\n<section data-number=\"2.3.4.4\" id=\"calibre_link-1877\">\n<h4 data-number=\"2.3.4.4\" class=\"calibre15\">Keyboard shortcuts for Visual Studio Code<\/h4>\n<p class=\"rights\">If you want to customize your keyboard shortcuts for Visual Studio Code, then you can, as shown at the following link: <a href=\"https:\/\/code.visualstudio.com\/docs\/getstarted\/keybindings\">https:\/\/code.visualstudio.com\/docs\/getstarted\/keybindings<\/a>.I recommend that you download a PDF of Visual Studio Code keyboard shortcuts for your operating system from the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Windows: <a href=\"https:\/\/code.visualstudio.com\/shortcuts\/keyboard-shortcuts-windows.pdf\">https:\/\/code.visualstudio.com\/shortcuts\/keyboard-shortcuts-windows.pdf<\/a><\/li>\n<li class=\"calibre3\">macOS: <a href=\"https:\/\/code.visualstudio.com\/shortcuts\/keyboard-shortcuts-macos.pdf\">https:\/\/code.visualstudio.com\/shortcuts\/keyboard-shortcuts-macos.pdf<\/a><\/li>\n<li class=\"calibre3\">Linux: <a href=\"https:\/\/code.visualstudio.com\/shortcuts\/keyboard-shortcuts-linux.pdf\">https:\/\/code.visualstudio.com\/shortcuts\/keyboard-shortcuts-linux.pdf<\/a><\/li>\n<\/ul>\n<\/section>\n<\/section>\n<\/section>\n<section data-number=\"2.4\" id=\"calibre_link-25\">\n<h2 data-number=\"2.4\" class=\"calibre5\">Understanding .NET<\/h2>\n<p class=\"rights\">.NET, .NET Core, .NET Framework, and Xamarin are related and overlapping platforms for developers used to build applications and services.<\/p>\n<blockquote class=\"calibre14\"><p>\n<em class=\"calibre10\">\u201cThose who cannot remember the past are condemned to repeat it.\u201d -- George Santayana<\/em>\n<\/p><\/blockquote>\n<p class=\"rights\">If you are not familiar with the history of .NET, then I introduce you to each of these .NET concepts at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch01-dotnet-history.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch01-dotnet-history.md<\/a><\/p>\n<section data-number=\"2.4.1\" id=\"calibre_link-26\">\n<h3 data-number=\"2.4.1\" class=\"calibre8\">Understanding .NET support<\/h3>\n<p class=\"rights\">.NET versions are either <strong class=\"calibre2\">Long Term Support<\/strong> (<strong class=\"calibre2\">LTS<\/strong>), <strong class=\"calibre2\">Standard Term Support (STS)<\/strong> (formerly known as <strong class=\"calibre2\">Current<\/strong>), or <strong class=\"calibre2\">Preview<\/strong>, as described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">LTS<\/strong> releases are a good choice for applications that you do not intend to update frequently, although you must update the .NET runtime for your production code monthly. LTS releases are supported by Microsoft for 3 years after <strong class=\"calibre2\">General Availability (GA)<\/strong>, or 1 year after the next LTS release ships, whichever is longer.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">STS<\/strong> releases include features that may change based on feedback. These are a good choice for applications that you are actively developing because they provide access to the latest improvements. STS releases are supported by Microsoft for 18 months after GA, or 6 months after the next STS or LTS release ships, whichever is longer.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Preview<\/strong> releases are for public testing. These are a good choice for adventurous programmers who want to live on the bleeding edge, or programming book authors who need to have early access to new language features, libraries, and app and service platforms. Preview releases are not usually supported by Microsoft, but some preview or <strong class=\"calibre2\">Release Candidate (RC)<\/strong> releases may be declared <strong class=\"calibre2\">Go Live<\/strong>, meaning they are supported by Microsoft in production.<\/li>\n<\/ul>\n<p class=\"rights\">STS and LTS releases receive critical patches throughout their lifetime for security and reliability.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You must stay up to date with the latest patches to get support. For example, if a system is running on .NET runtime version 8.0.0 and then version 8.0.1 is released, you must install version 8.0.1 to get support. These updates are released on the second Tuesday of each month, aka <strong class=\"calibre2\">Patch Tuesday<\/strong>.<\/p>\n<\/blockquote>\n<p class=\"rights\">To better understand your choices of STS and LTS releases, it is helpful to see it visually, with 3-year-long black bars for LTS releases, and 1\u00bd-year-long gray bars for STS releases, as shown in <em class=\"calibre10\">Figure 1.2<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.2: Support durations for recent and planned STS and LTS releases\" height=\"382\" src=\"\/images\/cs12\/000148.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.2: Support durations for recent and planned STS and LTS releases<\/figcaption><\/figure>\n<p class=\"rights\">During the lifetime of .NET 8, two older versions will reach end-of-life and two new versions will be released. I have tried to be cognizant that you might choose to use .NET 9 or .NET 10 with this book, although, obviously, the book cannot cover new features of those future versions!<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">End of support<\/strong> or <strong class=\"calibre2\">end-of-life (EOL)<\/strong> means the date after which bug fixes, security updates, or technical assistance are no longer available from Microsoft.<\/p>\n<\/blockquote>\n<p class=\"rights\">If you need long-term support from Microsoft, then choose .NET 8 today and stick with it even after .NET 9 releases in 2024. This is because .NET 9 will be an STS release, and it will therefore lose support in May 2026, before .NET 8 does in November 2026. As soon as .NET 10 is released, start upgrading your .NET 8 projects to it. You will have a year to do so before .NET 8 reaches its end-of-life.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Remember that with all releases, you must upgrade to bug-fix releases like .NET runtime 8.0.1 and .NET SDK 8.0.101, which are expected to release in December 2023, because updates are released every month.<\/p>\n<\/blockquote>\n<p class=\"rights\">At the time of publishing in November 2023, all versions of modern .NET have reached their end of life except those shown in the following list that are ordered by their end-of-life dates:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">.NET 7 will reach end-of-life on May 14, 2024.<\/li>\n<li class=\"calibre3\">.NET 6 will reach end-of-life on November 12, 2024.<\/li>\n<li class=\"calibre3\">.NET 8 will reach end-of-life on November 10, 2026.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can check which .NET versions are currently supported and when they will reach end-of-life at the following link: <a href=\"https:\/\/github.com\/dotnet\/core\/blob\/main\/releases.md\">https:\/\/github.com\/dotnet\/core\/blob\/main\/releases.md<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.4.2\" id=\"calibre_link-27\">\n<h3 data-number=\"2.4.2\" class=\"calibre8\">Understanding .NET support phases<\/h3>\n<p class=\"rights\">The lifetime of a version of .NET passes through several phases, during which they have varying levels of support, as described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Preview<\/strong>: Not supported. .NET 8 Preview 1 to Preview 7 were in this support phase from February 2023 to August 2023.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Go Live<\/strong>: Supported until GA, then becomes immediately unsupported so you must upgrade to the final release version as soon as it is available. .NET 8 Release Candidate 1 and Release Candidate 2 were in this support phase in September and October 2023.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Active<\/strong>: .NET 8 will be in this support phase from November 2023 to May 2026.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Maintenance<\/strong>: Supported only with security fixes for the last six months of its lifetime. .NET 8 will be in this support phase from May 2026 to November 2026.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">End-of-life<\/strong>: Not supported. .NET 8 will reach its end-of-life in November 2026.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"2.4.3\" id=\"calibre_link-28\">\n<h3 data-number=\"2.4.3\" class=\"calibre8\">Understanding .NET Runtime and .NET SDK versions<\/h3>\n<p class=\"rights\">If you have not built a standalone app, then the .NET Runtime is the minimum needed to install so that an operating system can run a .NET application. The .NET SDK includes the .NET Runtime as well as the compilers and other tools needed to build .NET code and apps..NET Runtime versioning follows semantic versioning, that is, a major increment indicates breaking changes, minor increments indicate new features, and patch increments indicate bug fixes..NET SDK versioning does not follow semantic versioning. The major and minor version numbers are tied to the runtime version it is matched with. The patch number follows a convention that indicates the major and minor versions of the SDK.You can see an example of this in <em class=\"calibre10\">Table 1.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Change<\/td>\n<td class=\"calibre21\">Runtime<\/td>\n<td class=\"calibre21\">SDK<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Initial release<\/td>\n<td class=\"calibre21\">8.0.0<\/td>\n<td class=\"calibre21\">8.0.100<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">SDK bug fix<\/td>\n<td class=\"calibre21\">8.0.0<\/td>\n<td class=\"calibre21\">8.0.101<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Runtime and SDK bug fix<\/td>\n<td class=\"calibre21\">8.0.1<\/td>\n<td class=\"calibre21\">8.0.102<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">SDK new feature<\/td>\n<td class=\"calibre21\">8.0.1<\/td>\n<td class=\"calibre21\">8.0.200<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 1.3: Examples of changes and versions for a .NET runtime and SDK<br \/>\n<\/section>\n<section data-number=\"2.4.4\" id=\"calibre_link-29\">\n<h3 data-number=\"2.4.4\" class=\"calibre8\">Listing and removing versions of .NET<\/h3>\n<p class=\"rights\">.NET Runtime updates are compatible with a major version such as 8.x, and updated releases of the .NET SDK maintain the ability to build applications that target previous versions of the runtime, which enables the safe removal of older versions.You can see which SDKs and runtimes are currently installed using the following commands:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet --list-sdks\ndotnet --list-runtimes\ndotnet --info<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: To make it easier to enter commands at the command prompt or terminal, the following link lists all commands throughout the book as a single statement that can be easily copied and pasted: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/command-lines.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/command-lines.md<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">On Windows, use the <strong class=\"calibre2\">Apps &amp; features<\/strong> section to remove .NET SDKs.On Linux, there is no single mechanism, but you can learn more at the following link:<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/install\/remove-runtime-sdk-versions?pivots=os-linux\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/install\/remove-runtime-sdk-versions?pivots=os-linux<\/a><\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You could use a third-party tool like Dots, the friendly .NET SDK manager, found at the following link: <a href=\"https:\/\/johnnys.news\/2023\/01\/Dots-a-dotnet-SDK-manager\">https:\/\/johnnys.news\/2023\/01\/Dots-a-dotnet-SDK-manager<\/a>. At the time of writing, you must build the app from source on its GitHub repository, so I only recommend that for advanced developers.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.4.5\" id=\"calibre_link-30\">\n<h3 data-number=\"2.4.5\" class=\"calibre8\">Understanding intermediate language<\/h3>\n<p class=\"rights\">The C# compiler (named <strong class=\"calibre2\">Roslyn<\/strong>) used by the <code class=\"calibre9\">dotnet<\/code> CLI tool converts your C# source code into <strong class=\"calibre2\">intermediate language<\/strong> (<strong class=\"calibre2\">IL<\/strong>) code and stores the IL in an <strong class=\"calibre2\">assembly<\/strong> (a DLL or EXE file). IL code statements are like assembly language instructions, which are executed by .NET's virtual machine, known as CoreCLR.At runtime, CoreCLR loads the IL code from the assembly, the <strong class=\"calibre2\">just-in-time<\/strong> (<strong class=\"calibre2\">JIT<\/strong>) compiler compiles it into native CPU instructions, and then it is executed by the CPU on your machine.The benefit of this two-step compilation process is that Microsoft can create <strong class=\"calibre2\">Common Language Runtimes<\/strong> (<strong class=\"calibre2\">CLRs<\/strong>) for Linux and macOS, as well as for Windows. The same IL code runs everywhere because of the second compilation step, which generates code for the native operating system and CPU instruction set.Regardless of which language the source code is written in, for example, C#, Visual Basic, or F#, all .NET applications use IL code for their instructions stored in an assembly. Microsoft and others provide disassembler tools that can open an assembly and reveal this IL code, such as the ILSpy .NET Decompiler extension. You will learn more about this in <em class=\"calibre10\">Chapter 7<\/em>, <em class=\"calibre10\">Packaging and Distributing .NET Types<\/em>.<\/p>\n<\/section>\n<section data-number=\"2.4.6\" id=\"calibre_link-31\">\n<h3 data-number=\"2.4.6\" class=\"calibre8\">Comparing .NET technologies<\/h3>\n<p class=\"rights\">We can summarize and compare .NET technologies today, as shown in <em class=\"calibre10\">Table 1.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Technology<\/td>\n<td class=\"calibre21\">Description<\/td>\n<td class=\"calibre21\">Host operating systems<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Modern .NET<\/td>\n<td class=\"calibre21\">A modern feature set, with full C# 8 to C# 12 language support. It can be used to port existing apps or create new desktop, mobile, and web apps and services. It can target older .NET platforms.<\/td>\n<td class=\"calibre21\">Windows, macOS, Linux, Android, iOS, tvOS, Tizen<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">.NET Framework<\/td>\n<td class=\"calibre21\">A legacy feature set with limited C# 8 support and no C# 9 or later support. It should be used to maintain existing applications only.<\/td>\n<td class=\"calibre21\">Windows only<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Xamarin<\/td>\n<td class=\"calibre21\">Mobile and desktop apps only.<\/td>\n<td class=\"calibre21\">Android, iOS, macOS<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 1.4: Comparison of .NET technologies<br \/>\n<\/section>\n<section data-number=\"2.4.7\" id=\"calibre_link-32\">\n<h3 data-number=\"2.4.7\" class=\"calibre8\">Managing multiple projects using code editors<\/h3>\n<p class=\"rights\">Visual Studio 2022 for Windows, JetBrains Rider, and even Visual Studio Code (with the C# Dev Kit extension installed) all have a concept called a <strong class=\"calibre2\">solution<\/strong> that allows you to open and manage multiple projects simultaneously. We will use a solution to manage the two projects that you will create in this chapter.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"2.5\" id=\"calibre_link-33\">\n<h2 data-number=\"2.5\" class=\"calibre5\">Building console apps using Visual Studio 2022<\/h2>\n<p class=\"rights\">The goal of this section is to showcase how to build a console app using Visual Studio 2022 for Windows.If you do not have a Windows computer or want to use Visual Studio Code, then you can skip this section since the code will be the same; just the tooling experience is different. But I recommend that you review this section because it does explain some of the code and how top-level programs work, and that information applies to all code editors.This section is also available in the GitHub repository (so it can be updated after publishing if needed) at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/code-editors\/vs4win.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/code-editors\/vs4win.md<\/a>If you want to see similar instructions for using JetBrains Rider, they are available in the GitHub repository at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/code-editors\/rider.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/code-editors\/rider.md<\/a><\/p>\n<section data-number=\"2.5.1\" id=\"calibre_link-34\">\n<h3 data-number=\"2.5.1\" class=\"calibre8\">Writing code using Visual Studio 2022<\/h3>\n<p class=\"rights\">Let's get started writing code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start Visual Studio 2022. You must have installed version 17.8 or later to see the new <strong class=\"calibre2\">Welcome<\/strong> tab that replaces the old modal dialog box.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <strong class=\"calibre2\">Welcome<\/strong> tab, click <strong class=\"calibre2\">New Project<\/strong>, as shown in <em class=\"calibre10\">Figure 1.3<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.3: Welcome tab with buttons like New Project\" height=\"347\" src=\"\/images\/cs12\/000131.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.3: Welcome tab with buttons like New Project<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <strong class=\"calibre2\">Create a new project<\/strong> dialog, select the C# language to filter the project templates, and then enter <code class=\"calibre9\">console<\/code> in the <strong class=\"calibre2\">Search for templates<\/strong> box, and select <strong class=\"calibre2\">Console App<\/strong>, making sure that you have chosen the cross-platform project template, not the one for .NET Framework, which is Windows-only, and the <strong class=\"calibre2\">C#<\/strong> project template rather than another language, such as Visual Basic or TypeScript, so that it is selected as shown in <em class=\"calibre10\">Figure 1.4<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.4: Selecting the C# Console App project template for modern cross-platform .NET\" height=\"700\" src=\"\/images\/cs12\/000114.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.4: Selecting the C# Console App project template for modern cross-platform .NET<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Next<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <strong class=\"calibre2\">Configure your new project<\/strong> dialog, enter <code class=\"calibre9\">HelloCS<\/code> for the project name, enter <code class=\"calibre9\">C:\\cs12dotnet8<\/code> for the location, and enter <code class=\"calibre9\">Chapter01<\/code> for the solution name.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">More screenshots of Visual Studio 2022 when creating new projects can be found in the GitHub repository at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch01-project-options.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch01-project-options.md<\/a>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Next<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <strong class=\"calibre2\">Additional information<\/strong> dialog, in the <strong class=\"calibre2\">Framework<\/strong> drop-down list, note that your .NET SDK choices indicate if that version is <strong class=\"calibre2\">Standard Term Support<\/strong>, <strong class=\"calibre2\">Long Term Support<\/strong>, <strong class=\"calibre2\">Preview<\/strong>, or <strong class=\"calibre2\">Out of support<\/strong>, and then select <strong class=\"calibre2\">.NET 8.0 (Long Term Support)<\/strong>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can install as many .NET SDK versions as you like. If you are missing a .NET SDK version, then you can install it from the following link: <a href=\"https:\/\/dotnet.microsoft.com\/en-us\/download\/dotnet\">https:\/\/dotnet.microsoft.com\/en-us\/download\/dotnet<\/a>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Leave the check box labeled <strong class=\"calibre2\">Do not use top-level statements<\/strong> cleared. (Later in this chapter, you will create a console app that selects this option so you can see the difference.)<\/li>\n<li class=\"calibre3\">Leave the check box labeled <strong class=\"calibre2\">Enable native AOT publish<\/strong> cleared. You will learn what this option does in <em class=\"calibre10\">Chapter 7, Packaging and Distributing .NET Types<\/em>.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Create<\/strong>.<\/li>\n<li class=\"calibre3\">If you cannot see the <strong class=\"calibre2\">Solution Explorer<\/strong>, then navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Solution Explorer<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">If code is not shown, then in <strong class=\"calibre2\">Solution Explorer<\/strong>, double-click the file named <code class=\"calibre9\">Program.cs<\/code> to open it, and note that <strong class=\"calibre2\">Solution Explorer<\/strong> shows the <strong class=\"calibre2\">HelloCS<\/strong> project, as shown in <em class=\"calibre10\">Figure 1.5<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.5: Editing Program.cs in Visual Studio 2022\" height=\"457\" src=\"\/images\/cs12\/000097.png\" width=\"1241\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.5: Editing Program.cs in Visual Studio 2022<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, note the code consists of only a comment and a single statement, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ See https:\/\/aka.ms\/new-console-template for more information\nConsole.WriteLine(\"Hello, World!\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">This template uses the top-level program feature introduced in C# 9, which I will explain later in this chapter. As the comment in the code says, you can read more about this template at the following link: <a href=\"https:\/\/aka.ms\/new-console-template\">https:\/\/aka.ms\/new-console-template<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, modify line 2 so that the text that is being written to the console says <code class=\"calibre9\">Hello, C#!<\/code><\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">All code examples and commands that the reader must review or type are shown in plain text so you will never have to read code or commands from a screenshot like in <em class=\"calibre10\">Figure 1.5<\/em>, which might be too small or too faint in print.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.5.2\" id=\"calibre_link-35\">\n<h3 data-number=\"2.5.2\" class=\"calibre8\">Compiling and running code using Visual Studio<\/h3>\n<p class=\"rights\">The next task is to compile and run the code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">In Visual Studio, navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Without Debugging<\/strong>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: When you start a project in Visual Studio 2022, you can choose to attach a debugger or not. If you do not need to debug, then it is better not to attach one because attaching a debugger requires more resources and slows everything down. Attaching a debugger also limits you to only starting one project. If you want to run more than one project, each with a debugger attached, then you must start multiple instances of Visual Studio. In the toolbar, click the green outline triangle button (to the right of <strong class=\"calibre2\">HelloCS<\/strong> in <em class=\"calibre10\">Figure 1.5<\/em>) to start without debugging instead of the green solid triangle button (to the left of <strong class=\"calibre2\">HelloCS<\/strong> in <em class=\"calibre10\">Figure 1.5<\/em>), unless you need to debug.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">The output in the console window will show the result of running your application, as shown in <em class=\"calibre10\">Figure 1.6<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.6: Running the console app on Windows\" height=\"554\" src=\"\/images\/cs12\/000081.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.6: Running the console app on Windows<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Press any key to close the console app window and return to Visual Studio.<\/li>\n<li class=\"calibre3\">Optionally, close the <strong class=\"calibre2\">Properties<\/strong> pane to make more vertical space for <strong class=\"calibre2\">Solution Explorer<\/strong>.<\/li>\n<li class=\"calibre3\">Double-click the <strong class=\"calibre2\">HelloCS<\/strong> project and note the <code class=\"calibre9\">HelloCS.csproj<\/code> project file shows that this project has its target framework set to <code class=\"calibre9\">net8.0<\/code>, as shown in <em class=\"calibre10\">Figure 1.7<\/em>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Solution Explorer<\/strong> toolbar, toggle on the <strong class=\"calibre2\">Show All Files<\/strong> button <img loading=\"lazy\" decoding=\"async\" height=\"32\" src=\"\/images\/cs12\/000064.png\" width=\"32\" class=\"calibre12\" \/>, and note that the compiler-generated <code class=\"calibre9\">bin<\/code> and <code class=\"calibre9\">obj<\/code> folders are visible, as shown in <em class=\"calibre10\">Figure 1.7<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.7: Showing the compiler-generated folders and files\" height=\"406\" src=\"\/images\/cs12\/000048.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.7: Showing the compiler-generated folders and files<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"2.5.3\" id=\"calibre_link-36\">\n<h3 data-number=\"2.5.3\" class=\"calibre8\">Understanding the compiler-generated folders and files<\/h3>\n<p class=\"rights\">Two compiler-generated folders were created, named <code class=\"calibre9\">obj<\/code> and <code class=\"calibre9\">bin<\/code>, as described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The <code class=\"calibre9\">obj<\/code> folder contains one compiled <em class=\"calibre10\">object<\/em> file for each source code file. These objects haven't been linked together into a final executable yet.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">bin<\/code> folder contains the <em class=\"calibre10\">binary<\/em> executable for the application or class library. We will look at this in more detail in <em class=\"calibre10\">Chapter 7<\/em>, <em class=\"calibre10\">Packaging and Distributing .NET Types<\/em>.<\/li>\n<\/ul>\n<p class=\"rights\">You do not need to look inside these folders or understand their files yet (but feel free to browse around if you are curious). Just be aware that the compiler needs to create temporary folders and files to do its work. You could delete these folders and their files, and they will be automatically recreated the next time you \"build\" or run the project. Developers often delete these temporary folders and files to \"clean\" a project. Visual Studio even has a command on the <strong class=\"calibre2\">Build<\/strong> menu named <strong class=\"calibre2\">Clean Solution<\/strong> that deletes some of these temporary files for you. The equivalent command with Visual Studio Code is <code class=\"calibre9\">dotnet clean<\/code>.<\/p>\n<\/section>\n<section data-number=\"2.5.4\" id=\"calibre_link-37\">\n<h3 data-number=\"2.5.4\" class=\"calibre8\">Understanding top-level programs<\/h3>\n<p class=\"rights\">If you have seen older .NET projects before, then you might have expected more code, even just to output a simple message. This project has minimal statements because some of the required code is written for you by the compiler when you target .NET 6 or later. If you had created the project with .NET SDK 5 or earlier, or if you had selected the check box labeled <strong class=\"calibre2\">Do not use top-level statements<\/strong>, then the <code class=\"calibre9\">Program.cs<\/code> file would have more statements, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System;\nnamespace HelloCS\n{\n  class Program\n  {\n    static void Main(string[] args)\n    {\n      Console.WriteLine(\"Hello, World!\");\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">During compilation with .NET SDK 6 or later, all the boilerplate code to define the <code class=\"calibre9\">Program<\/code> class and its <code class=\"calibre9\">Main<\/code> method is generated and wrapped around the statements you write.This uses a feature introduced in .NET 5 called <strong class=\"calibre2\">top-level programs<\/strong>, but it was not until .NET 6 that Microsoft updated the project template for console apps to use top-level statements by default. Then in .NET 7 or later, Microsoft added options to use the older style if you prefer:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">If you are using Visual Studio 2022, select the check box labeled <strong class=\"calibre2\">Do not use top-level statements<\/strong>.<\/li>\n<li class=\"calibre3\">If you are using the <code class=\"calibre9\">dotnet<\/code> CLI at the command prompt, add a switch:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new console --use-program-main<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> One functional difference is that the auto-generated code does not define a namespace, so the <code class=\"calibre9\">Program<\/code> class is implicitly defined in an empty namespace with no name instead of a namespace that matches the name of the project.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.5.5\" id=\"calibre_link-38\">\n<h3 data-number=\"2.5.5\" class=\"calibre8\">Requirements for top-level programs<\/h3>\n<p class=\"rights\">Key points to remember about top-level programs include the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">There can be only one file like this in a project.<\/li>\n<li class=\"calibre3\">Any <code class=\"calibre9\">using<\/code> statements must be at the top of the file.<\/li>\n<li class=\"calibre3\">If you declare any classes or other types, they must be at the bottom of the file.<\/li>\n<li class=\"calibre3\">Although you should name the method <code class=\"calibre9\">Main<\/code> if you explicitly define it, the method is named <code class=\"calibre9\">&lt;Main&gt;$<\/code> when created by the compiler.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"2.5.6\" id=\"calibre_link-39\">\n<h3 data-number=\"2.5.6\" class=\"calibre8\">Implicitly imported namespaces<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">using System;<\/code> statement at the top of the file imports the <code class=\"calibre9\">System<\/code> namespace. This enables the <code class=\"calibre9\">Console.WriteLine<\/code> statement to work. Why do we not have to import it in our project? The trick is that we do still need to import the <code class=\"calibre9\">System<\/code> namespace, but it is now done for us using a combination of features introduced in C# 10 and .NET 6. Let's see how:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, expand the <code class=\"calibre9\">obj<\/code> folder, expand the <code class=\"calibre9\">Debug<\/code> folder, expand the <code class=\"calibre9\">net8.0<\/code> folder, and open the file named <code class=\"calibre9\">HelloCS.GlobalUsings.g.cs<\/code>.<\/li>\n<li class=\"calibre3\">Note that this file is automatically created by the compiler for projects that target .NET 6 or later, and that it uses a feature introduced in C# 10 called <strong class=\"calibre2\">global namespace imports<\/strong>, which imports some commonly used namespaces like <code class=\"calibre9\">System<\/code> for use in all code files, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ &lt;autogenerated \/&gt;\nglobal using global::System;\nglobal using global::System.Collections.Generic;\nglobal using global::System.IO;\nglobal using global::System.Linq;\nglobal using global::System.Net.Http;\nglobal using global::System.Threading;\nglobal using global::System.Threading.Tasks;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, click the <strong class=\"calibre2\">Show All Files<\/strong> button to hide the <code class=\"calibre9\">bin<\/code> and <code class=\"calibre9\">obj<\/code> folders.<\/li>\n<\/ol>\n<p class=\"rights\">I will explain more about the implicit imports feature in the next chapter. For now, just note that a significant change that happened between .NET 5 and .NET 6 is that many of the project templates, like the one for console apps, use new SDK and language features to hide what is really happening.<\/p>\n<\/section>\n<section data-number=\"2.5.7\" id=\"calibre_link-40\">\n<h3 data-number=\"2.5.7\" class=\"calibre8\">Revealing the hidden code by throwing an exception<\/h3>\n<p class=\"rights\">Now let's discover how the hidden code has been written:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, after the statement that outputs the message, add a statement to throw a new exception, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">throw new Exception();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Visual Studio, navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Without Debugging<\/strong>. (Do not start the project with debugging or the exception will be caught by the debugger!)<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">The output in the console window will show the result of running your application, including that a hidden <code class=\"calibre9\">Program<\/code> class was defined by the compiler with a method named <code class=\"calibre9\">&lt;Main&gt;$<\/code> that has a parameter named <code class=\"calibre9\">args<\/code> for passing in arguments, as shown in <em class=\"calibre10\">Figure 1.8<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.8: Throwing an exception to reveal the hidden Program.&lt;Main&gt;$ method\" height=\"408\" src=\"\/images\/cs12\/000031.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.8: Throwing an exception to reveal the hidden Program.&lt;Main&gt;$ method<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Press any key to close the console app window and return to Visual Studio.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"2.5.8\" id=\"calibre_link-41\">\n<h3 data-number=\"2.5.8\" class=\"calibre8\">Revealing the namespace for the Program class<\/h3>\n<p class=\"rights\">Now, let's discover what namespace the <code class=\"calibre9\">Program<\/code> class has been defined within:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, before the statement that throws an exception, add statements to get the name of the namespace of the <code class=\"calibre9\">Program<\/code> class, and then write it to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string name = typeof(Program).Namespace ?? \"None!\";\nConsole.WriteLine($\"Namespace: {name}\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">??<\/code> is the null-coalescing operator. The first statement means, \"If the namespace of <code class=\"calibre9\">Program<\/code> is <code class=\"calibre9\">null<\/code>, then return <code class=\"calibre9\">None!<\/code>; otherwise, return the name.\" You will see more explanations of these keywords and operators throughout the book. For now, just enter the code and run it to see what it does.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Visual Studio, navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Without Debugging<\/strong>.<\/li>\n<li class=\"calibre3\">The output in the console window will show the result of running your application, including that the hidden <code class=\"calibre9\">Program<\/code> class was defined without a namespace, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Namespace: None!<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Press any key to close the console app window and return to Visual Studio.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"2.5.9\" id=\"calibre_link-42\">\n<h3 data-number=\"2.5.9\" class=\"calibre8\">Adding a second project using Visual Studio 2022<\/h3>\n<p class=\"rights\">Let's add a second project to our solution to explore how to work with multiple projects:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">In Visual Studio, navigate to <strong class=\"calibre2\">File<\/strong> | <strong class=\"calibre2\">Add<\/strong> | <strong class=\"calibre2\">New Project\u2026<\/strong>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> The above step adds a new project to the existing solution. Do NOT navigate to <strong class=\"calibre2\">File<\/strong> | <strong class=\"calibre2\">New<\/strong> | <strong class=\"calibre2\">Project\u2026<\/strong>, which instead is meant to be used to create a new project <em class=\"calibre10\">and solution<\/em> (although the dialog box has a dropdown to choose to add to an existing solution too).<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Add a new project<\/strong> dialog, in <strong class=\"calibre2\">Recent project templates<\/strong>, select <strong class=\"calibre2\">Console App [C#]<\/strong> and then click <strong class=\"calibre2\">Next<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Configure your new project<\/strong> dialog, for <strong class=\"calibre2\">Project name<\/strong>, enter <code class=\"calibre9\">AboutMyEnvironment<\/code>, leave the location as <code class=\"calibre9\">C:\\cs12dotnet8\\Chapter01<\/code>, and then click <strong class=\"calibre2\">Next<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <strong class=\"calibre2\">Additional information<\/strong> dialog, select <strong class=\"calibre2\">.NET 8.0 (Long Term Support)<\/strong> and select the <strong class=\"calibre2\">Do not use top-level statements<\/strong> check box.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Make sure you have selected the <strong class=\"calibre2\">Do not use top-level statements<\/strong> check box, so we get to see the older style of <code class=\"calibre9\">Program.cs<\/code>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Create<\/strong>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">AboutMyEnvironment<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, note the statements to define a namespace that matches the project name, an internal class named <code class=\"calibre9\">Program<\/code>, and a static method named <code class=\"calibre9\">Main<\/code> with a parameter named <code class=\"calibre9\">args<\/code> that returns nothing (<code class=\"calibre9\">void<\/code>), as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace AboutMyEnvironment\n{\n  internal class Program\n  {\n    static void Main(string[] args)\n    {\n      Console.WriteLine(\"Hello, World!\");\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, in the <code class=\"calibre9\">Main<\/code> method, replace the existing <code class=\"calibre9\">Console.WriteLine<\/code> statement with statements to output the current directory, the version of the operating system, and the namespace of the <code class=\"calibre9\">Program<\/code> class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Console.WriteLine(Environment.CurrentDirectory);\nConsole.WriteLine(Environment.OSVersion.VersionString);\nConsole.WriteLine(\"Namespace: {0}\", typeof(Program).Namespace);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, right-click the <strong class=\"calibre2\">Chapter01<\/strong> solution, and then select <strong class=\"calibre2\">Configure Startup Projects\u2026<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Solution 'Chapter01' Property Pages<\/strong> dialog box, set <strong class=\"calibre2\">Startup Project<\/strong> to <strong class=\"calibre2\">Current selection<\/strong>, and then click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, click the <code class=\"calibre9\">AboutMyEnvironment<\/code> project (or any file or folder within it), and note that Visual Studio indicates that <code class=\"calibre9\">AboutMyEnvironment<\/code> is now the startup project by making the project name bold.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: I recommend this way of setting the startup project because it then makes it very easy to switch startup projects by simply clicking a project (or any file in a project) to make it the startup project. Although you can right-click a project and set it as a startup project, if you then want to run a different project, you must manually change it again. Simply clicking anywhere in the project is easier. In most chapters, you will only need to run one project at a time. In <em class=\"calibre10\">Chapter 15<\/em>, <em class=\"calibre10\">Building and Consuming Web Services<\/em>, I will show you how to configure multiple startup projects.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Without Debugging<\/strong> to run the <code class=\"calibre9\">AboutMyEnvironment<\/code> project, and note the result, as shown in the following output and in <em class=\"calibre10\">Figure 1.9<\/em>:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">C:\\cs12dotnet8\\Chapter01\\AboutMyEnvironment\\bin\\Debug\\net8.0\nMicrosoft Windows NT 10.0.22621.0\nNamespace: AboutMyEnvironment<\/code><\/pre>\n<\/div>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.9: Running a console app in a Visual Studio solution with two projects\" height=\"635\" src=\"\/images\/cs12\/000013.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.9: Running a console app in a Visual Studio solution with two projects<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Windows 11 is just branding. Its official name is Windows NT, and its major version number is still 10! But its patch version is 22000 or higher.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Press any key to close the console app window and return to Visual Studio.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">When using Visual Studio 2022 for Windows to run a console app, it executes the app from the <code class=\"calibre9\">&lt;projectname&gt;\\bin\\Debug\\net8.0<\/code> folder. It will be important to remember this when we work with the filesystem in later chapters. When using Visual Studio Code, or more accurately, the <code class=\"calibre9\">dotnet<\/code> CLI, it has different behavior, as you are about to see.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"2.6\" id=\"calibre_link-43\">\n<h2 data-number=\"2.6\" class=\"calibre5\">Building console apps using Visual Studio Code<\/h2>\n<p class=\"rights\">The goal of this section is to showcase how to build a console app using Visual Studio Code and the <code class=\"calibre9\">dotnet<\/code> <strong class=\"calibre2\">CLI<\/strong>.If you never want to try Visual Studio Code or the <code class=\"calibre9\">dotnet<\/code> command-line tool, then please feel free to skip this section, and then continue with the <em class=\"calibre10\">Making good use of the GitHub repository for this book<\/em> section.Both the instructions and screenshots in this section are for Windows, but the same actions will work with Visual Studio Code on the macOS and Linux variants.The main differences will be native command-line actions such as deleting a file: both the command and the path are likely to be different on Windows or macOS and Linux. Luckily, the <code class=\"calibre9\">dotnet<\/code> CLI tool itself and its commands are identical on all platforms.<\/p>\n<section data-number=\"2.6.1\" id=\"calibre_link-44\">\n<h3 data-number=\"2.6.1\" class=\"calibre8\">Writing code using Visual Studio Code<\/h3>\n<p class=\"rights\">Let's get started writing code!<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start your favorite tool for working with the filesystem, for example, <strong class=\"calibre2\">File Explorer<\/strong> on Windows or <strong class=\"calibre2\">Finder<\/strong> on Mac.<\/li>\n<li class=\"calibre3\">Navigate to your <code class=\"calibre9\">C:<\/code> drive on Windows, your user folder on macOS or Linux (mine are named <code class=\"calibre9\">markjprice<\/code> and <code class=\"calibre9\">home\/markjprice<\/code>), or any directory or drive in which you want to save your projects.<\/li>\n<li class=\"calibre3\">Create a new folder named <code class=\"calibre9\">cs12dotnet8<\/code>. (If you completed the section for Visual Studio 2022, then this folder will already exist.)<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <code class=\"calibre9\">cs12dotnet8<\/code> folder, create a new folder named <code class=\"calibre9\">Chapter01-vscode<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you did not complete the section for Visual Studio 2022, then you could name this folder <code class=\"calibre9\">Chapter01<\/code>, but I will assume you will want to complete both sections and therefore need to use a non-conflicting name.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Chapter01-vscode<\/code> folder, open the command prompt or terminal. For example, on Windows, right-click in the folder and then select <strong class=\"calibre2\">Open in Terminal<\/strong>.<\/li>\n<li class=\"calibre3\">At the command prompt or terminal, use the <code class=\"calibre9\">dotnet<\/code> CLI to create a new solution named <code class=\"calibre9\">Chapter01<\/code>, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new sln --name Chapter01<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can use either <code class=\"calibre9\">-n<\/code> or <code class=\"calibre9\">--name<\/code> as the switch to specify a name. The default would match the name of the folder, for example, <code class=\"calibre9\">Chapter01-vscode<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">The template \"Solution File\" was created successfully.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the command prompt or terminal, use the <code class=\"calibre9\">dotnet<\/code> CLI to create a new subfolder and project for a console app named <code class=\"calibre9\">HelloCS<\/code>, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new console --output HelloCS<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can use either <code class=\"calibre9\">-o<\/code> or <code class=\"calibre9\">--output<\/code> as the switch to specify the folder and project name. The <code class=\"calibre9\">dotnet new console<\/code> command targets your latest .NET SDK version by default. To target a different version, use the <code class=\"calibre9\">-f<\/code> or <code class=\"calibre9\">--framework<\/code> switch to specify a target framework. For example, to target .NET 6, as shown in the following command: <code class=\"calibre9\">dotnet new console -f net6.0<\/code><\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the command prompt or terminal, use the <code class=\"calibre9\">dotnet<\/code> CLI to add the project to the solution, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet sln add HelloCS<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Project `HelloCS\\HelloCS.csproj` added to the solution.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the command prompt or terminal, start Visual Studio Code and open the current folder indicated with a <code class=\"calibre9\">.<\/code> (dot), as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">code .<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you are prompted, <strong class=\"calibre2\">Do you trust the authors of the files in this folder?<\/strong>, then select the <strong class=\"calibre2\">Trust the authors of all files in the parent folder 'cs12dotnet8'<\/strong> check box and then click <strong class=\"calibre2\">Yes, I trust the authors<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In Visual Studio Code, in <strong class=\"calibre2\">EXPLORER<\/strong>, in the <strong class=\"calibre2\">CHAPTER01-VSCODE<\/strong> folder view, expand the <code class=\"calibre9\">HelloCS<\/code> folder, and you will see that the <code class=\"calibre9\">dotnet<\/code> command-line tool created two files, <code class=\"calibre9\">HelloCS.csproj<\/code> and <code class=\"calibre9\">Program.cs<\/code>, and <code class=\"calibre9\">bin<\/code> and <code class=\"calibre9\">obj<\/code> folders, as shown in <em class=\"calibre10\">Figure 1.10<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.10: EXPLORER shows that two files and a folder have been created\" height=\"414\" src=\"\/images\/cs12\/000175.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.10: EXPLORER shows that two files and a folder have been created<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Output<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <strong class=\"calibre2\">OUTPUT<\/strong> pane, select <strong class=\"calibre2\">C# Dev Kit<\/strong> and note the tool has recognized and processed the solution, as shown in <em class=\"calibre10\">Figure 1.11<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.11: C# Dev Kit processing a solution file\" height=\"425\" src=\"\/images\/cs12\/000157.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.11: C# Dev Kit processing a solution file<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">At the bottom of <strong class=\"calibre2\">EXPLORER<\/strong>, note the <strong class=\"calibre2\">SOLUTION EXPLORER<\/strong>.<\/li>\n<li class=\"calibre3\">Drag <strong class=\"calibre2\">SOLUTION EXPLORER<\/strong> to the top of the <strong class=\"calibre2\">EXPLORER<\/strong> pane and expand it.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">SOLUTION EXPLORER<\/strong>, expand the <strong class=\"calibre2\">HelloCS<\/strong> project, and then click the file named <code class=\"calibre9\">Program.cs<\/code> to open it in the editor window.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, modify line 2 so that the text that is being written to the console says <code class=\"calibre9\">Hello, C#!<\/code><\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Navigate to <strong class=\"calibre2\">File<\/strong> | <strong class=\"calibre2\">Auto Save<\/strong>. This toggle will save the annoyance of remembering to save before rebuilding your application each time.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.6.2\" id=\"calibre_link-45\">\n<h3 data-number=\"2.6.2\" class=\"calibre8\">Compiling and running code using the dotnet CLI<\/h3>\n<p class=\"rights\">The next task is to compile and run the code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">SOLUTION EXPLORER<\/strong>, right-click on any file in the <code class=\"calibre9\">HelloCS<\/code> project and choose <strong class=\"calibre2\">Open In Integrated Terminal<\/strong>.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">TERMINAL<\/strong>, enter the following command: <code class=\"calibre9\">dotnet run<\/code>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">The output in the <strong class=\"calibre2\">TERMINAL<\/strong> window will show the result of running your application, as shown in <em class=\"calibre10\">Figure 1.12<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.12: The output of running your first console app in Visual Studio Code\" height=\"374\" src=\"\/images\/cs12\/000141.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.12: The output of running your first console app in Visual Studio Code<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, after the statement that outputs the message, add statements to get the name of the namespace of the <code class=\"calibre9\">Program<\/code> class, write it to the console, and then throw a new exception, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string name = typeof(Program).Namespace ?? \"None!\";\nConsole.WriteLine($\"Namespace: {name}\");\nthrow new Exception();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">In <strong class=\"calibre2\">TERMINAL<\/strong>, enter the following command: <code class=\"calibre9\">dotnet run<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In <strong class=\"calibre2\">TERMINAL<\/strong>, you can press the up and down arrows to loop through previous commands and then press the left and right arrows to edit the command before pressing <span>Enter<\/span> to run them.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">The output in the <strong class=\"calibre2\">TERMINAL<\/strong> window will show the result of running your application, including that a hidden <code class=\"calibre9\">Program<\/code> class was defined by the compiler with a method named <code class=\"calibre9\">&lt;Main&gt;$<\/code> that has a parameter named <code class=\"calibre9\">args<\/code> for passing in arguments, and that it does not have a namespace, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Hello, C#!\nNamespace: None!\nUnhandled exception. System.Exception: Exception of type 'System.Exception' was thrown.\n   at Program.&lt;Main&gt;$(String[] args) in C:\\cs12dotnet8\\Chapter01-vscode\\HelloCS\\Program.cs:line 7<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"2.6.3\" id=\"calibre_link-46\">\n<h3 data-number=\"2.6.3\" class=\"calibre8\">Adding a second project using Visual Studio Code<\/h3>\n<p class=\"rights\">Let's add a second project to explore how to work with multiple projects:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">TERMINAL<\/strong>, change to the <code class=\"calibre9\">Chapter01-vscode<\/code> directory, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">cd ..<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">TERMINAL<\/strong>, enter the command to create a new console app project named <code class=\"calibre9\">AboutMyEnvironment<\/code> using the older non-top-level program style, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new console -o AboutMyEnvironment --use-program-main<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Be careful when entering commands in <strong class=\"calibre2\">TERMINAL<\/strong>. Be sure that you are in the correct folder before entering potentially destructive commands!<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">TERMINAL<\/strong>, use the <code class=\"calibre9\">dotnet<\/code> CLI to add the new project folder to the solution, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet sln add AboutMyEnvironment<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Project `AboutMyEnvironment\\AboutMyEnvironment.csproj` added to the solution.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">SOLUTION<\/strong> <strong class=\"calibre2\">EXPLORER<\/strong>, in the <code class=\"calibre9\">AboutMyEnvironment<\/code> project, open <code class=\"calibre9\">Program.cs<\/code>, and then in the <code class=\"calibre9\">Main<\/code> method, change the existing statement to output the current directory, the operating system version string, and the namespace of the <code class=\"calibre9\">Program<\/code> class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Console.WriteLine(Environment.CurrentDirectory);\nConsole.WriteLine(Environment.OSVersion.VersionString);\nConsole.WriteLine(\"Namespace: {0}\", typeof(Program).Namespace);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">SOLUTION EXPLORER<\/strong>, right-click on any file in the <code class=\"calibre9\">AboutMyEnvironment<\/code> project and choose <strong class=\"calibre2\">Open In Integrated Terminal<\/strong>.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">TERMINAL<\/strong>, enter the command to run the project, as shown in the following command: <code class=\"calibre9\">dotnet run<\/code>.<\/li>\n<li class=\"calibre3\">Note the output in the <strong class=\"calibre2\">TERMINAL<\/strong> window, as shown in the following output and in <em class=\"calibre10\">Figure 1.13<\/em>:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">C:\\cs12dotnet8\\Chapter01-vscode\\AboutMyEnvironment\nMicrosoft Windows NT 10.0.22621.0\nNamespace: AboutMyEnvironment<\/code><\/pre>\n<\/div>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.13: Running a console app in Visual Studio Code with two projects\" height=\"569\" src=\"\/images\/cs12\/000124.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.13: Running a console app in Visual Studio Code with two projects<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Once you open multiple terminal windows, you can toggle between them by clicking their names in the panel on the right-hand side of <strong class=\"calibre2\">TERMINAL<\/strong>. By default, the name will be one of the common shells like <strong class=\"calibre2\">pwsh<\/strong>, <strong class=\"calibre2\">powershell<\/strong>, <strong class=\"calibre2\">zsh<\/strong>, or <strong class=\"calibre2\">bash<\/strong>. Right-click and choose to rename to set something else.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">When using Visual Studio Code, or more accurately, the <code class=\"calibre9\">dotnet<\/code> CLI, to run a console app, it executes the app from the <code class=\"calibre9\">&lt;projectname&gt;<\/code> folder. When using Visual Studio 2022 for Windows, it executes the app from the <code class=\"calibre9\">&lt;projectname&gt;\\bin\\Debug\\net8.0<\/code> folder. It will be important to remember this when we work with the filesystem in later chapters.<\/p>\n<\/blockquote>\n<\/blockquote>\n<p class=\"rights\">If you were to run the program on macOS Ventura, the environment operating system would be different, as shown in the following output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Unix 13.5.2<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Although the source code, like the <code class=\"calibre9\">.csproj<\/code> and <code class=\"calibre9\">.cs<\/code> files, is identical, the <code class=\"calibre9\">bin<\/code> and <code class=\"calibre9\">obj<\/code> folders that are automatically generated by the compiler could have mismatches that give you errors. If you want to open the same project in both Visual Studio 2022 and Visual Studio Code, delete the temporary <code class=\"calibre9\">bin<\/code> and <code class=\"calibre9\">obj<\/code> folders before opening the project in the other code editor. This potential problem is why I asked you to create a different folder for the Visual Studio Code projects in this chapter.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.6.4\" id=\"calibre_link-47\">\n<h3 data-number=\"2.6.4\" class=\"calibre8\">Summary of steps for Visual Studio Code<\/h3>\n<p class=\"rights\">Follow these steps to create a solution and projects using Visual Studio Code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Create a folder for the solution, for example, <code class=\"calibre9\">Chapter01<\/code>.<\/li>\n<li class=\"calibre3\">Create a solution file in the folder: <code class=\"calibre9\">dotnet new sln<\/code>.<\/li>\n<li class=\"calibre3\">Create a folder and project using a template: <code class=\"calibre9\">dotnet new console -o HelloCS<\/code>.<\/li>\n<li class=\"calibre3\">Add the folder and its project to the solution: <code class=\"calibre9\">dotnet sln add HelloCS<\/code>.<\/li>\n<li class=\"calibre3\">Repeat steps 3 and 4 to create and add any other projects.<\/li>\n<li class=\"calibre3\">Open the folder containing the solution using Visual Studio Code: <code class=\"calibre9\">code .<\/code><\/li>\n<\/ol>\n<\/section>\n<section data-number=\"2.6.5\" id=\"calibre_link-48\">\n<h3 data-number=\"2.6.5\" class=\"calibre8\">Summary of other project types used in this book<\/h3>\n<p class=\"rights\">A <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project is just one type of project template. In this book, you will also create projects using the following project templates, as shown in <em class=\"calibre10\">Table 1.5<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Visual Studio 2022<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">dotnet new<\/code><\/td>\n<td class=\"calibre21\">JetBrains Rider - Type<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Console App<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">console<\/code><\/td>\n<td class=\"calibre21\">Console Application<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Class Library<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">classlib<\/code><\/td>\n<td class=\"calibre21\">Class Library<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">xUnit Test Project<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">xunit<\/code><\/td>\n<td class=\"calibre21\">Unit Test Project - xUnit<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ASP.NET Core Empty<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">web<\/code><\/td>\n<td class=\"calibre21\">ASP.NET Core Web Application - Empty<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Razor Class Library<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">razorclasslib<\/code><\/td>\n<td class=\"calibre21\">ASP.NET Core Web Application - Razor Class Library<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ASP.NET Core Web App (Model-View-Controller)<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">mvc<\/code><\/td>\n<td class=\"calibre21\">ASP.NET Core Web Application - Web App (Model-View-Controller)<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ASP.NET Core Web API<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">webapi<\/code><\/td>\n<td class=\"calibre21\">ASP.NET Core Web Application - Web API<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ASP.NET Core Web API (native AOT)<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">api<\/code><\/td>\n<td class=\"calibre21\">ASP.NET Core Web Application - Web API (native AOT)<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Blazor Web App<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">blazor<\/code><\/td>\n<td class=\"calibre21\">ASP.NET Core Web Application - Blazor Web App<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 1.5: Project template names for various code editors<\/p>\n<p class=\"rights\">The steps for adding any type of new project to a solution are the same. Only the type name of the project template differs, and sometimes some command-line switches to control options. I will always specify what those switches and options should be if they differ from the defaults.A summary of project template defaults, options, and switches can be found here: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch01-project-options.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch01-project-options.md<\/a>.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"2.7\" id=\"calibre_link-49\">\n<h2 data-number=\"2.7\" class=\"calibre5\">Making good use of the GitHub repository for this book<\/h2>\n<p class=\"rights\"><strong class=\"calibre2\">Git<\/strong> is a commonly used source code management system. <strong class=\"calibre2\">GitHub<\/strong> is a company, website, and desktop application that makes it easier to manage Git. Microsoft purchased GitHub in 2018, so it will continue to get closer integration with Microsoft tools.I created a GitHub repository for this book, and I use it for the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">To store the solution code for the book that can be maintained after the print publication date.<\/li>\n<li class=\"calibre3\">To provide extra materials that extend the book, like errata fixes, small improvements, lists of useful links, and optional sections about topics that cannot fit in the printed book.<\/li>\n<li class=\"calibre3\">To provide a place for readers to get in touch with me if they have issues with the book.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: I strongly recommend that all readers review the errata, improvements, post-publication changes, and common errors pages before attempting any coding task in this book. You can find them at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/errata\/errata.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/errata\/errata.md<\/a>.<\/p>\n<\/blockquote>\n<section data-number=\"2.7.1\" id=\"calibre_link-50\">\n<h3 data-number=\"2.7.1\" class=\"calibre8\">Understanding the solution code on GitHub<\/h3>\n<p class=\"rights\">The solution code in the GitHub repository for this book includes folders for each chapter that can be opened with any of the following code editors:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Visual Studio 2022 or JetBrains Rider: Open the <code class=\"calibre9\">.sln<\/code> solution file.<\/li>\n<li class=\"calibre3\">Visual Studio Code: Open the folder that contains the solution file.<\/li>\n<\/ul>\n<p class=\"rights\">Chapters 1 to 11 each have their own solution file named <code class=\"calibre9\">ChapterXX.sln<\/code> where <code class=\"calibre9\">XX<\/code> is the chapter number. Chapters 12 to 16 share a single solution file named <code class=\"calibre9\">PracticalApps.sln<\/code>.All the code solutions can be found at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code<\/a><\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If you need to, return to this chapter to remind yourself how to create and manage multiple projects in the code editor of your choice. The GitHub repository has step-by-step instructions for three code editors (Visual Studio 2022, Visual Studio Code, and JetBrains Rider), along with additional screenshots: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/docs\/code-editors\/\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/docs\/code-editors\/<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.7.2\" id=\"calibre_link-51\">\n<h3 data-number=\"2.7.2\" class=\"calibre8\">Raising issues with the book<\/h3>\n<p class=\"rights\">If you get stuck following any of the instructions in this book, or if you spot a mistake in the text or the code in the solutions, please raise an issue in the GitHub repository:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your favorite browser to navigate to the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/issues\">https:\/\/github.com\/markjprice\/cs12dotnet8\/issues<\/a>.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">New Issue<\/strong>.<\/li>\n<li class=\"calibre3\">Enter as much detail as possible that will help me to diagnose the issue. For example:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">The specific section title, page number, and step number.<\/li>\n<li class=\"calibre3\">Your code editor, for example, Visual Studio 2022, Visual Studio Code, or something else, including the version number.<\/li>\n<li class=\"calibre3\">As much of your code and configuration that you feel is relevant and necessary.<\/li>\n<li class=\"calibre3\">Description of expected behavior and the behavior experienced.<\/li>\n<li class=\"calibre3\">Screenshots (you can drag and drop image files into the <strong class=\"calibre2\">Issue<\/strong> box).<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p class=\"rights\">The following is less relevant but might be useful:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Your operating system, for example, Windows 11 64-bit, or macOS Ventura version 13.5.2.<\/li>\n<li class=\"calibre3\">Your hardware, for example, Intel, Apple Silicon, or ARM CPU.<\/li>\n<\/ul>\n<p class=\"rights\">I cannot always respond immediately to issues. But I want all my readers to be successful with my book, so if I can help you (and others) without too much trouble, then I will gladly do so.<\/p>\n<\/section>\n<section data-number=\"2.7.3\" id=\"calibre_link-52\">\n<h3 data-number=\"2.7.3\" class=\"calibre8\">Giving me feedback<\/h3>\n<p class=\"rights\">If you'd like to give me more general feedback about the book, then either email me at <code class=\"calibre9\">markjprice@gmail.com<\/code> or ask me a question on Discord in the book channel. You can provide the feedback anonymously, or if you would like a response from me, then you can supply an email address. I will only use this email address to answer your feedback.Please join me and your fellow readers on Discord using this invite: <a href=\"https:\/\/packt.link\/cs12dotnet8\">https:\/\/packt.link\/cs12dotnet8<\/a>I recommend that you add the preceding link to your favorite bookmarks.I love to hear from my readers about what they like about my book, as well as suggestions for improvements and how they are working with C# and .NET, so don't be shy. Please get in touch!Thank you in advance for your thoughtful and constructive feedback.<\/p>\n<\/section>\n<section data-number=\"2.7.4\" id=\"calibre_link-53\">\n<h3 data-number=\"2.7.4\" class=\"calibre8\">Avoiding common mistakes<\/h3>\n<p class=\"rights\">After working through the step-by-step tasks in this book, readers often then strike out on their own and attempt to write similar code, but sometimes they hit problems and either raise an issue in the GitHub repository or post a question to the Discord channel for the book. From these, I have noted some common mistakes, so I maintain a page in the repository to highlight and explain these potential traps and how to fix them:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/errata\/common-mistakes.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/errata\/common-mistakes.md<\/a><\/p>\n<\/section>\n<section data-number=\"2.7.5\" id=\"calibre_link-54\">\n<h3 data-number=\"2.7.5\" class=\"calibre8\">Downloading solution code from the GitHub repository<\/h3>\n<p class=\"rights\">If you just want to download all the solution files without using Git, click the green <strong class=\"calibre2\">Code<\/strong> button and then select <strong class=\"calibre2\">Download ZIP<\/strong>, as shown in <em class=\"calibre10\">Figure 1.14<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.14: Downloading the repository as a ZIP file\" height=\"743\" src=\"\/images\/cs12\/000106.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.14: Downloading the repository as a ZIP file<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: It is best to clone or download the code solutions to a short folder path, like <code class=\"calibre9\">C:\\cs12dotnet8\\<\/code> or <code class=\"calibre9\">C:\\book\\<\/code>, to avoid build-generated files exceeding the maximum path length. You should also avoid special characters like <code class=\"calibre9\">#<\/code>. For example, do not use a folder name like <code class=\"calibre9\">C:\\C# projects\\<\/code>. That folder name might work for a simple console app project but once you start adding features that automatically generate code, you are likely to have strange issues. Keep your folder names short and simple.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.7.6\" id=\"calibre_link-55\">\n<h3 data-number=\"2.7.6\" class=\"calibre8\">Using Git with Visual Studio Code and the command prompt<\/h3>\n<p class=\"rights\">Visual Studio Code has integrations with Git, but it will use your operating system's Git installation, so you must install Git 2.0 or later first before you get these features.You can install Git from the following link: <a href=\"https:\/\/git-scm.com\/download\">https:\/\/git-scm.com\/download<\/a>.If you like to use a GUI, you can download GitHub Desktop from the following link: <a href=\"https:\/\/desktop.github.com\">https:\/\/desktop.github.com<\/a>.<\/p>\n<\/section>\n<section data-number=\"2.7.7\" id=\"calibre_link-56\">\n<h3 data-number=\"2.7.7\" class=\"calibre8\">Cloning the book solution code repository<\/h3>\n<p class=\"rights\">Let's clone the book solution code repository. In the steps that follow, you will use the Visual Studio Code terminal, but you could enter the commands at any command prompt or terminal window:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Create a folder named <code class=\"calibre9\">Repos-vscode<\/code> in your user or <code class=\"calibre9\">Documents<\/code> folder, or wherever you want to store your Git repositories.<\/li>\n<li class=\"calibre3\">Open the <code class=\"calibre9\">Repos-vscode<\/code> folder at the command prompt or terminal, and then enter the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">git clone https:\/\/github.com\/markjprice\/cs12dotnet8.git<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note that cloning all the solutions for all the chapters will take a minute or so, so please be patient.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"2.8\" id=\"calibre_link-57\">\n<h2 data-number=\"2.8\" class=\"calibre5\">Looking for help<\/h2>\n<p class=\"rights\">This section is all about how to find quality information about programming on the web.<\/p>\n<section data-number=\"2.8.1\" id=\"calibre_link-58\">\n<h3 data-number=\"2.8.1\" class=\"calibre8\">Reading the documentation on Microsoft Learn<\/h3>\n<p class=\"rights\">The definitive resource for getting help with Microsoft developer tools and platforms is in the technical documentation on Microsoft Learn, and you can find it at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/docs\">https:\/\/learn.microsoft.com\/en-us\/docs<\/a>.<\/p>\n<\/section>\n<section data-number=\"2.8.2\" id=\"calibre_link-59\">\n<h3 data-number=\"2.8.2\" class=\"calibre8\">Documentation links in this book<\/h3>\n<p class=\"rights\">The official Microsoft documentation for .NET needs to cover all versions. The default version shown in the documentation is always the most recent general availability (GA) version.For example, between November 2023 and November 2024, the default version of .NET shown in documentation pages will be 8.0. Between November 2024 and November 2025, the default version of .NET will be 9.0. The following link will automatically direct to the current version depending on the current date:<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.diagnostics.codeanalysis.stringsyntaxattribute\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.diagnostics.codeanalysis.stringsyntaxattribute<\/a>To view the documentation page specifically for .NET 7, append <code class=\"calibre9\">?view=net-7.0<\/code> to the end of a link. For example, use the following link:<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.diagnostics.codeanalysis.stringsyntaxattribute?view=net-7.0\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.diagnostics.codeanalysis.stringsyntaxattribute?view=net-7.0<\/a>All documentation links in this book do not specify a version, so after November 2024, they will show the documentation pages for .NET 9.0. If you want to force the documentation to show the version for .NET 8.0, then append <code class=\"calibre9\">?view=net-8.0<\/code> to the end of a link.You can check what versions a .NET feature supports by appending <code class=\"calibre9\">#applies-to<\/code> to the end of a link, for example:<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.diagnostics.codeanalysis.stringsyntaxattribute#applies-to\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.diagnostics.codeanalysis.stringsyntaxattribute#applies-to<\/a>We can therefore see that the <code class=\"calibre9\">StringSyntax<\/code> attribute is only available in .NET 7 or later.<\/p>\n<\/section>\n<section data-number=\"2.8.3\" id=\"calibre_link-60\">\n<h3 data-number=\"2.8.3\" class=\"calibre8\">Getting help for the dotnet tool<\/h3>\n<p class=\"rights\">At the command prompt, you can ask the <code class=\"calibre9\">dotnet<\/code> tool for help with its commands. The syntax is:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet help &lt;command&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This will cause your web browser to open a page in the documentation about the specified command. Common <code class=\"calibre9\">dotnet<\/code> commands include <code class=\"calibre9\">new<\/code>, <code class=\"calibre9\">build<\/code>, <code class=\"calibre9\">run<\/code>, and many more.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> The <code class=\"calibre9\">dotnet help new<\/code> command worked with .NET Core 3.1 to .NET 6, but it returns an error with .NET 7 or later: <code class=\"calibre9\">Specified command 'new' is not a valid SDK command. Specify a valid SDK command. For more information, run dotnet help.<\/code> Hopefully, they will fix that bug soon!<\/p>\n<\/blockquote>\n<p class=\"rights\">Another type of help is command-line documentation. It follows this syntax:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet &lt;command&gt; -?|-h|--help<\/code><\/pre>\n<\/div>\n<p class=\"rights\">For example, <code class=\"calibre9\">dotnet new -?<\/code> or <code class=\"calibre9\">dotnet new -h<\/code> or <code class=\"calibre9\">dotnet new --help<\/code> outputs documentation about the <code class=\"calibre9\">new<\/code> command at the command prompt.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">As you should now expect, <code class=\"calibre9\">dotnet help help<\/code> opens a web browser for the <code class=\"calibre9\">help<\/code> command, and <code class=\"calibre9\">dotnet help -h<\/code> outputs documentation for the <code class=\"calibre9\">help<\/code> command at the command prompt!<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's try some examples:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">To open the official documentation in a web browser window for the <code class=\"calibre9\">dotnet build<\/code> command, enter the following at the command prompt or in the Visual Studio Code terminal, and note the page opened in your web browser, as shown in <em class=\"calibre10\">Figure 1.15<\/em>:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet help build<\/code><\/pre>\n<\/div>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.15: Web page documentation for the dotnet build command\" height=\"462\" src=\"\/images\/cs12\/000090.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.15: Web page documentation for the dotnet build command<\/figcaption><\/figure>\n<ol class=\"toc\">\n<li class=\"calibre3\">To get help output at the command prompt, use the <code class=\"calibre9\">-?<\/code> or <code class=\"calibre9\">-h<\/code> or <code class=\"calibre9\">--help<\/code> flag, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet build -?<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">You will see the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Description:\n  .NET Builder\nUsage:\n  dotnet build [&lt;PROJECT | SOLUTION&gt;...] [options]\nArguments:\n  &lt;PROJECT | SOLUTION&gt;  The project or solution file to operate on. If a file is not specified, the command will search the current directory for one.\nOptions:\n  --ucr, --use-current-runtime         Use current runtime as the target runtime.\n  -f, --framework &lt;FRAMEWORK&gt;          The target framework to build for. The target framework must also be specified in the project file.\n...\n  -?, -h, --help                       Show command line help.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Repeat both types of help request for the following commands: <code class=\"calibre9\">add<\/code>, <code class=\"calibre9\">help<\/code>, <code class=\"calibre9\">list<\/code>, <code class=\"calibre9\">new<\/code>, and <code class=\"calibre9\">run<\/code>, remembering that <code class=\"calibre9\">new<\/code> might not show its web page due to a bug introduced in .NET 7.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"2.8.4\" id=\"calibre_link-61\">\n<h3 data-number=\"2.8.4\" class=\"calibre8\">Getting definitions of types and their members<\/h3>\n<p class=\"rights\">One of the most useful features of a code editor is <strong class=\"calibre2\">Go To Definition<\/strong> (<span>F12<\/span>). It is available in Visual Studio Code, Visual Studio 2022, and JetBrains Rider. It will show what the public definition of the type or member looks like by reading the metadata in the compiled assembly.Some tools, such as ILSpy .NET Decompiler, will even reverse-engineer from the metadata and IL code back into C# or another language for you.A similar and related feature is named <strong class=\"calibre2\">Go To Implementation<\/strong> (<span>Ctrl<\/span> + <span>F12<\/span>). Instead of reading the metadata or decompiling, this will show the actual source code if that is embedded using the optional source link feature.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> <strong class=\"calibre2\">Go To Definition<\/strong> should go to the decompiled metadata for a member or type. But if you have previously viewed source link, then it goes to source link. <strong class=\"calibre2\">Go To Implementation<\/strong> should go to the source link implementation for a member or type. But if you have disabled source link, then it goes to the decompiled metadata.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's see how to use the <strong class=\"calibre2\">Go To Definition<\/strong> feature:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In your preferred code editor, open the solution\/folder named <code class=\"calibre9\">Chapter01<\/code>.<\/li>\n<\/ol>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">If you are using Visual Studio 2022:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Tools<\/strong> | <strong class=\"calibre2\">Options<\/strong>.<\/li>\n<li class=\"calibre3\">In the search box, enter <code class=\"calibre9\">navigation to source<\/code>.<\/li>\n<li class=\"calibre3\">Select <strong class=\"calibre2\">Text Editor<\/strong> | <strong class=\"calibre2\">C#<\/strong> | <strong class=\"calibre2\">Advanced<\/strong>.<\/li>\n<li class=\"calibre3\">Clear the <strong class=\"calibre2\">Enable navigation to Source Link and Embedded sources<\/strong> check box, and then click <strong class=\"calibre2\">OK<\/strong>, as shown in <em class=\"calibre10\">Figure 1.16<\/em>:<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.16: Disabling Source Link for the Go To Definition feature\" height=\"484\" src=\"\/images\/cs12\/000073.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.16: Disabling Source Link for the Go To Definition feature<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Definitions can be either reverse-engineered from metadata or loaded from the original source code if that is enabled. Personally, I find the code from metadata more useful, as you are about to see. At the end of this section, try switching the Source Link option back on to see the difference.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">HelloCS<\/code> project, at the bottom of <code class=\"calibre9\">Program.cs<\/code>, enter the following statement to declare an integer variable named <code class=\"calibre9\">z<\/code>:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int z;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Click on <code class=\"calibre9\">int<\/code>, right-click on <code class=\"calibre9\">int<\/code>, and then choose <strong class=\"calibre2\">Go To Definition<\/strong> in Visual Studio 2022 or Visual Studio Code. In JetBrains Rider, choose <strong class=\"calibre2\">Go to<\/strong> | <strong class=\"calibre2\">Go to Declaration or Usages<\/strong>.<\/li>\n<li class=\"calibre3\">In the code window that appears, you can see how the <code class=\"calibre9\">int<\/code> data type is defined, as shown in <em class=\"calibre10\">Figure 1.17<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.17: The int data type metadata\" height=\"423\" src=\"\/images\/cs12\/000057.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.17: The int data type metadata<\/figcaption><\/figure>\n<p class=\"rights\">You can see that <code class=\"calibre9\">int<\/code>:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Is defined using the <code class=\"calibre9\">struct<\/code> keyword.<\/li>\n<li class=\"calibre3\">Is in the <code class=\"calibre9\">System.Runtime<\/code> assembly.<\/li>\n<li class=\"calibre3\">Is in the <code class=\"calibre9\">System<\/code> namespace.<\/li>\n<li class=\"calibre3\">Is named <code class=\"calibre9\">Int32<\/code>.<\/li>\n<li class=\"calibre3\">Is therefore an alias for the <code class=\"calibre9\">System.Int32<\/code> type.<\/li>\n<li class=\"calibre3\">Implements interfaces such as <code class=\"calibre9\">IComparable<\/code>.<\/li>\n<li class=\"calibre3\">Has constant values for its maximum and minimum values.<\/li>\n<li class=\"calibre3\">Has methods such as <code class=\"calibre9\">Parse<\/code>. (Not visible in <em class=\"calibre10\">Figure 1.17<\/em>.)<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Right now, the <strong class=\"calibre2\">Go To Definition<\/strong> feature is not that useful to you because you do not yet know what all of this information means. By the end of the first part of this book, which consists of <em class=\"calibre10\">Chapters 2<\/em> to <em class=\"calibre10\">6<\/em> and teaches you about the C# language, you will know enough for this feature to become very handy.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the code editor window, scroll down to find the <code class=\"calibre9\">Parse<\/code> method with a single <code class=\"calibre9\">string<\/code> parameter, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public static Int32 Parse(string s)<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Expand the code and review the comments that document this method, as shown in <em class=\"calibre10\">Figure 1.18<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.18: The comments for the Parse method with a single string parameter\" height=\"604\" src=\"\/images\/cs12\/000042.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.18: The comments for the Parse method with a single string parameter<\/figcaption><\/figure>\n<p class=\"rights\">In the comments, you will see that Microsoft has documented the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A summary that describes the method.<\/li>\n<li class=\"calibre3\">Parameters like the <code class=\"calibre9\">string<\/code> value that can be passed to the method.<\/li>\n<li class=\"calibre3\">The return value of the method, including its data type.<\/li>\n<li class=\"calibre3\">Three exceptions that might occur if you call this method, including <code class=\"calibre9\">ArgumentNullException<\/code>, <code class=\"calibre9\">FormatException<\/code>, and <code class=\"calibre9\">OverflowException<\/code>. Now, we know that we could choose to wrap a call to this method in a <code class=\"calibre9\">try<\/code> statement and which exceptions to catch.<\/li>\n<\/ul>\n<p class=\"rights\">Hopefully, you are getting impatient to learn what all this means!Be patient for a little longer. You are almost at the end of this chapter, and in the next chapter, you will dive into the details of the C# language. But first, let's see where else you can look for help.<\/p>\n<\/section>\n<section data-number=\"2.8.5\" id=\"calibre_link-62\">\n<h3 data-number=\"2.8.5\" class=\"calibre8\">Configuring inline aka inlay hints<\/h3>\n<p class=\"rights\">Throughout the code in this book, when calling a method, I often explicitly specify named parameters to help the reader learn what is going on. For example, I have specified the names of the parameters <code class=\"calibre9\">format<\/code> and <code class=\"calibre9\">arg0<\/code> in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Console.WriteLine(format: \"Value is {0}.\", arg0: 19.8);<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><strong class=\"calibre2\">Inline hints<\/strong> aka <strong class=\"calibre2\">inlay hints<\/strong> show the names of parameters without you having to type them, as shown in <em class=\"calibre10\">Figure 1.19<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.19: Configuring inline hints aka inlay hints\" height=\"345\" src=\"\/images\/cs12\/000169.png\" width=\"1206\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.19: Configuring inline hints aka inlay hints<\/figcaption><\/figure>\n<p class=\"rights\">Most code editors have this feature that you can enable permanently or only when a key combination like <span>Alt<\/span> + <span>F1<\/span> or <span>Ctrl<\/span> is held down:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">In Visual Studio 2022, navigate to <strong class=\"calibre2\">Tools<\/strong> | <strong class=\"calibre2\">Options<\/strong>, navigate to <strong class=\"calibre2\">Text Editor<\/strong> | <strong class=\"calibre2\">C#<\/strong> | <strong class=\"calibre2\">Advanced<\/strong>, scroll down to the <strong class=\"calibre2\">Inline Hints<\/strong> section, and select the <strong class=\"calibre2\">Display inline parameter hint names<\/strong> check box, and then click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<li class=\"calibre3\">In Visual Studio Code, navigate to <strong class=\"calibre2\">File<\/strong> | <strong class=\"calibre2\">Preferences<\/strong> | <strong class=\"calibre2\">Settings<\/strong>, search for <code class=\"calibre9\">inlay<\/code>, select the <strong class=\"calibre2\">C#<\/strong> filter, and then select the <strong class=\"calibre2\">Display inline parameter name hints<\/strong> check box.<\/li>\n<li class=\"calibre3\">In JetBrains Rider, in <strong class=\"calibre2\">Settings<\/strong>, navigate to <strong class=\"calibre2\">Editor<\/strong> | <strong class=\"calibre2\">Inlay Hints<\/strong> | <strong class=\"calibre2\">C#<\/strong> | <strong class=\"calibre2\">Parameter Name Hints<\/strong>.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"2.8.6\" id=\"calibre_link-63\">\n<h3 data-number=\"2.8.6\" class=\"calibre8\">Looking for answers on Stack Overflow<\/h3>\n<p class=\"rights\">Stack Overflow is the most popular third-party website for getting answers to difficult programming questions. Let's see an example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start your favorite web browser.<\/li>\n<li class=\"calibre3\">Navigate to <code class=\"calibre9\">stackoverflow.com<\/code>; in the search box, enter <code class=\"calibre9\">securestring<\/code> and note the search results, which are shown in <em class=\"calibre10\">Figure 1.20<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.20: Stack Overflow search results for securestring\" height=\"650\" src=\"\/images\/cs12\/000135.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.20: Stack Overflow search results for securestring<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"2.8.7\" id=\"calibre_link-64\">\n<h3 data-number=\"2.8.7\" class=\"calibre8\">Searching for answers using Google<\/h3>\n<p class=\"rights\">You can search Google with advanced search options to increase the likelihood of finding what you need:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to Google at the following link: <a href=\"https:\/\/www.google.com\/\">https:\/\/www.google.com\/<\/a>.<\/li>\n<li class=\"calibre3\">Search for information about <code class=\"calibre9\">garbage collection<\/code> using a simple Google query and note that you will probably see a lot of ads for garbage collection services in your local area before you see the Wikipedia definition of garbage collection in computer science.<\/li>\n<li class=\"calibre3\">Improve the search by restricting it to a useful site such as Stack Overflow, and by removing languages that we might not care about, such as C++, Rust, and Python, or by adding C# and .NET explicitly, as shown in the following search query:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">garbage collection site:stackoverflow.com +C# -Java<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"2.8.8\" id=\"calibre_link-65\">\n<h3 data-number=\"2.8.8\" class=\"calibre8\">Searching the .NET source code<\/h3>\n<p class=\"rights\">Sometimes you can learn a lot from seeing how the Microsoft teams have implemented .NET. The source for the entire code base for .NET is available in public GitHub repositories. For example, you might know that there is a built-in attribute to validate an email address. Let's search the repositories for the word \"email\" and see if we can find out how it works:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred web browser to navigate to: <a href=\"https:\/\/github.com\/search\">https:\/\/github.com\/search<\/a>.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">advanced search<\/strong>.<\/li>\n<li class=\"calibre3\">In the search box, type <code class=\"calibre9\">email<\/code>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">In these respositories<\/strong> box, type <code class=\"calibre9\">dotnet\/runtime<\/code>. (Other repositories you might want to search include <code class=\"calibre9\">dotnet\/core<\/code>, <code class=\"calibre9\">dotnet\/aspnetcore<\/code>, <code class=\"calibre9\">dotnet\/wpf<\/code>, <code class=\"calibre9\">dotnet\/winforms<\/code>).<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Written in this language<\/strong> box, select <strong class=\"calibre2\">C#<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the top right of the page, note how the advanced query has been written for you, click <strong class=\"calibre2\">Search<\/strong>, and then click the <strong class=\"calibre2\">Code<\/strong> filter and note the results include the <code class=\"calibre9\">EmailAddressAttribute<\/code>, as shown in <em class=\"calibre10\">Figure 1.21<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.21: Advanced search for email in the dotnet\/runtime repository\" height=\"544\" src=\"\/images\/cs12\/000118.png\" width=\"1210\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.21: Advanced search for email in the dotnet\/runtime repository<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Click the source file and note it implements email validation by checking that the <code class=\"calibre9\">string<\/code> value contains an <code class=\"calibre9\">@<\/code> symbol but not as the first or last character, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ only return true if there is only 1 '@' character\n\/\/ and it is neither the first nor the last character\nint index = valueAsString.IndexOf('@');\nreturn\n    index &gt; 0 &amp;&amp;\n    index != valueAsString.Length - 1 &amp;&amp;\n    index == valueAsString.LastIndexOf('@');<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close the browser.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">For your convenience, you can do a quick search for other terms by replacing the search term <code class=\"calibre9\">email<\/code> in the following link: <a href=\"https:\/\/github.com\/search?q=%22email%22+repo%3Adotnet%2Fruntime+language%3AC%23&amp;type=code&amp;ref=advsearch\">https:\/\/github.com\/search?q=%22email%22+repo%3Adotnet%2Fruntime+language%3AC%23&amp;type=code&amp;ref=advsearch<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.8.9\" id=\"calibre_link-66\">\n<h3 data-number=\"2.8.9\" class=\"calibre8\">Subscribing to the official .NET blog<\/h3>\n<p class=\"rights\">To keep up to date with .NET, an excellent blog to subscribe to is the official .NET blog, written by the .NET engineering teams, and you can find it at the following link: <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/\">https:\/\/devblogs.microsoft.com\/dotnet\/<\/a>.<\/p>\n<\/section>\n<section data-number=\"2.8.10\" id=\"calibre_link-67\">\n<h3 data-number=\"2.8.10\" class=\"calibre8\">Watching Scott Hanselman's videos<\/h3>\n<p class=\"rights\">Scott Hanselman from Microsoft has an excellent YouTube channel about computer stuff they didn't teach you: <a href=\"http:\/\/computerstufftheydidntteachyou.com\/\">http:\/\/computerstufftheydidntteachyou.com\/<\/a>.I recommend it to everyone working with computers.<\/p>\n<\/section>\n<section data-number=\"2.8.11\" id=\"calibre_link-68\">\n<h3 data-number=\"2.8.11\" class=\"calibre8\">AI tools like ChatGPT and GitHub Copilot<\/h3>\n<p class=\"rights\">One of the biggest changes in coding and development in the past year is the emergence of generative <strong class=\"calibre2\">artificial intelligence<\/strong> (<strong class=\"calibre2\">AI<\/strong>) tools that can help with coding tasks like completing a code statement, implementing an entire function, writing unit tests, and suggesting debugging fixes for existing code.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can read what developers say about AI tools in the 2023 Stack Overflow Developer Survey. \"44% of them use AI tools in their development process now, and 26% plan to soon.\": <a href=\"https:\/\/stackoverflow.blog\/2023\/06\/14\/hype-or-not-developers-have-something-to-say-about-ai\/\">https:\/\/stackoverflow.blog\/2023\/06\/14\/hype-or-not-developers-have-something-to-say-about-ai\/<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">ChatGPT currently has two models: 3.5 (free) and 4.0 ($20 per month). Let's say you need to write a C# function to validate an email address. You might go to ChatGPT and enter the following prompt:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">write a c# function to validate an email address<\/code><\/pre>\n<\/div>\n<p class=\"rights\">It responds with a complete class with methods, as shown in <em class=\"calibre10\">Figure 1.22<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.22: ChatGPT writes a function to validate an email address\" height=\"707\" src=\"\/images\/cs12\/000056.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.22: ChatGPT writes a function to validate an email address<\/figcaption><\/figure>\n<p class=\"rights\">It then provides an explanation of the code and examples of how to call the function, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">bool isValid = EmailValidator.IsValidEmail(\"test@example.com\");\nConsole.WriteLine(isValid ? \"Valid\" : \"Invalid\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">But is a general-purpose generative AI like ChatGPT the best partner for a C# programmer?Microsoft has a service specifically for programmers, named GitHub Copilot, that can help autocomplete code directly in your code editor. It is being enhanced with more intelligence using GPT-4. It has plugins for code editors including Visual Studio 2022, Visual Studio Code, and JetBrains IntelliJ-based IDEs.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Personally, I really like the Copilot branding. It makes it clear that you are the pilot. You are ultimately responsible for \"flying the plane.\" But for the easy or boring bits, you can hand it over to your co-pilot for a bit, while being actively ready to take back control if needed.<\/p>\n<\/blockquote>\n<p class=\"rights\"><strong class=\"calibre2\">GitHub Copilot<\/strong> is free for students, teachers, and some open source project maintainers. For everyone else, it has a 30-day free trial and then it costs $10 per month or $100 per year for individuals. Once you have an account, you can then sign up for waiting lists to get the more advanced experimental GitHub Copilot X features. You should check online for which Copilot features are available for various code editors. As you can imagine, this is a fast-changing world and a lot of what I might write in the book today will be out-of-date by the time you read it: <a href=\"https:\/\/github.com\/features\/copilot\">https:\/\/github.com\/features\/copilot<\/a>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">JetBrains has its own equivalent, named AI Assistant, that you can read about at the following link: <a href=\"https:\/\/blog.jetbrains.com\/idea\/2023\/06\/ai-assistant-in-jetbrains-ides\/\">https:\/\/blog.jetbrains.com\/idea\/2023\/06\/ai-assistant-in-jetbrains-ides\/<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">So, what can GitHub Copilot do for you today?Imagine that you have just added a new class file named <code class=\"calibre9\">Product.cs<\/code>. You click inside the <code class=\"calibre9\">Product<\/code> class, press <span>Enter<\/span> to insert a blank line, and then pause for a second as you think about what you need to type\u2026and GitHub Copilot generates some sample code in gray, as shown in <em class=\"calibre10\">Figure 1.23<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.23: GitHub Copilot suggesting how to define a Product class\" height=\"543\" src=\"\/images\/cs12\/000024.png\" width=\"1209\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.23: GitHub Copilot suggesting how to define a Product class<\/figcaption><\/figure>\n<p class=\"rights\">At this point, you can glance over the code and, if it is close to what you want, just press <span>Tab<\/span> to insert it all, or press <span>Alt<\/span> + <span>.<\/span> (dot) to toggle between other suggestions.Sometimes it is too far off what you need, and you'll be better off ignoring its suggestion completely and just writing it yourself. But usually, there's something there that's usable or reminds you of the syntax you need to use. And sometimes, it feels like magic, writing dozens of lines of exactly what you need.Microsoft feeds its AI tools with code from public GitHub repositories, including all the repositories I have created since 2016 for all the editions of this book. This means that it can suggest code completions for the readers of this book that are surprisingly accurate predictions including my frequent use of pop culture references in my code. It's like I, Mark J. Price, am the \"ghost in the machine\" guiding your coding.It's easy to imagine a custom ChatGPT that has ingested all the official Microsoft .NET documentation, every public blog article written about .NET, and perhaps even hundreds of books about .NET, and having a conversation about it to find a bug or suggest how to solve a programming problem.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can sign up for GitHub Copilot at the following link: <a href=\"https:\/\/github.com\/github-copilot\/signup\/\">https:\/\/github.com\/github-copilot\/signup\/<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.8.12\" id=\"calibre_link-69\">\n<h3 data-number=\"2.8.12\" class=\"calibre8\">Disabling tools when they get in the way<\/h3>\n<p class=\"rights\">Although these tools can be helpful, they can also get in your way, especially when learning, because they sometimes do work for you without telling you. If you do not do that work for yourself at least a few times, you won't learn fully.To configure IntelliSense for C# in Visual Studio 2022:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Tools<\/strong> | <strong class=\"calibre2\">Options<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Options<\/strong> dialog box tree view, navigate to <strong class=\"calibre2\">Text Editor<\/strong> | <strong class=\"calibre2\">C#<\/strong> | <strong class=\"calibre2\">IntelliSense<\/strong>.<\/li>\n<li class=\"calibre3\">Click the <strong class=\"calibre2\">?<\/strong> button in the caption bar to view the documentation.<\/li>\n<\/ol>\n<p class=\"rights\">To configure GitHub Copilot X in Visual Studio 2022:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Tools<\/strong> | <strong class=\"calibre2\">Options<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Options<\/strong> dialog box tree view, navigate to <strong class=\"calibre2\">GitHub<\/strong> | <strong class=\"calibre2\">Copilot<\/strong>.<\/li>\n<li class=\"calibre3\">Set <strong class=\"calibre2\">Enable Globally<\/strong> to <strong class=\"calibre2\">True<\/strong> or <strong class=\"calibre2\">False<\/strong>, and then click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<\/ol>\n<p class=\"rights\">To disable GitHub Copilot X in Visual Studio Code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the status bar, on the right, to the left of the notification icon, click the GitHub Copilot icon.<\/li>\n<li class=\"calibre3\">In the popup, click <strong class=\"calibre2\">Disable Globally<\/strong>.<\/li>\n<li class=\"calibre3\">To enable, click the GitHub Copilot icon again and then click <strong class=\"calibre2\">Enable Globally<\/strong>.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">For help with JetBrains Rider IntelliSense, please see the following link: <a href=\"https:\/\/www.jetbrains.com\/help\/rider\/Auto-Completing_Code.xhtml\">https:\/\/www.jetbrains.com\/help\/rider\/Auto-Completing_Code.xhtml<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"2.9\" id=\"calibre_link-70\">\n<h2 data-number=\"2.9\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Let's now test your knowledge and understanding by trying to answer some questions, getting some hands-on practice, and going into the topics covered throughout this chapter in greater detail.<\/p>\n<section data-number=\"2.9.1\" id=\"calibre_link-71\">\n<h3 data-number=\"2.9.1\" class=\"calibre8\">Exercise 1.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Try to answer the following questions, remembering that although most answers can be found in this chapter, you should do some online research or code writing to answer others:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Is Visual Studio 2022 better than Visual Studio Code?<\/li>\n<li class=\"calibre3\">Is .NET 5 and later better than .NET Framework?<\/li>\n<li class=\"calibre3\">What is .NET Standard and why is it still important?<\/li>\n<li class=\"calibre3\">Why can a programmer use different languages, for example, C# and F#, to write applications that run on .NET?<\/li>\n<li class=\"calibre3\">What is a top-level program and how do you access any command-line arguments?<\/li>\n<li class=\"calibre3\">What is the name of the entry point method of a .NET console app and how should it be explicitly declared if you are not using the top-level program feature?<\/li>\n<li class=\"calibre3\">What namespace is the <code class=\"calibre9\">Program<\/code> class defined in with a top-level program?<\/li>\n<li class=\"calibre3\">Where would you look for help for a C# keyword?<\/li>\n<li class=\"calibre3\">Where would you look first for solutions to common programming problems?<\/li>\n<li class=\"calibre3\">What should you do after getting an AI to write code for you?<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><em class=\"calibre10\">Appendix<\/em>, <em class=\"calibre10\">Answers to the Test Your Knowledge Questions<\/em>, is available to download from a link in the README in the GitHub repository: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\">https:\/\/github.com\/markjprice\/cs12dotnet8<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"2.9.2\" id=\"calibre_link-72\">\n<h3 data-number=\"2.9.2\" class=\"calibre8\">Exercise 1.2 &ndash; Practice C# anywhere with a browser<\/h3>\n<p class=\"rights\">You don't need to download and install Visual Studio Code or even Visual Studio 2022 to write C#. You can start coding online at any of the following links:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Visual Studio Code for Web: <a href=\"https:\/\/vscode.dev\/\">https:\/\/vscode.dev\/<\/a><\/li>\n<li class=\"calibre3\">SharpLab: <a href=\"https:\/\/sharplab.io\/\">https:\/\/sharplab.io\/<\/a><\/li>\n<li class=\"calibre3\">C# Online Compiler | .NET Fiddle: <a href=\"https:\/\/dotnetfiddle.net\/\">https:\/\/dotnetfiddle.net\/<\/a><\/li>\n<li class=\"calibre3\">W3Schools C# Online Compiler: <a href=\"https:\/\/www.w3schools.com\/cs\/cs_compiler.php\">https:\/\/www.w3schools.com\/cs\/cs_compiler.php<\/a><\/li>\n<\/ul>\n<\/section>\n<section data-number=\"2.9.3\" id=\"calibre_link-73\">\n<h3 data-number=\"2.9.3\" class=\"calibre8\">Exercise 1.3 &ndash; Explore topics<\/h3>\n<p class=\"rights\">A book is a curated experience. I have tried to find the right balance of topics to include in the printed book. Other content that I have written can be found in the GitHub repository for this book.I believe that this book covers all the fundamental knowledge and skills a C# and .NET developer should have or be aware of. Some longer examples are best included as links to Microsoft documentation or third-party article authors.Use the links on the following page to learn more details about the topics covered in this chapter:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-1---hello-c-welcome-net\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-1---hello-c-welcome-net<\/a><\/p>\n<\/section>\n<section data-number=\"2.9.4\" id=\"calibre_link-74\">\n<h3 data-number=\"2.9.4\" class=\"calibre8\">Exercise 1.4 &ndash; Explore Polyglot Notebooks<\/h3>\n<p class=\"rights\">Complete the following online-only section to explore how you can use Polyglot Notebooks with its .NET Interactive engine:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch01-polyglot-notebooks.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch01-polyglot-notebooks.md<\/a><\/p>\n<\/section>\n<section data-number=\"2.9.5\" id=\"calibre_link-75\">\n<h3 data-number=\"2.9.5\" class=\"calibre8\">Exercise 1.5 &ndash; Explore themes of modern .NET<\/h3>\n<p class=\"rights\">Microsoft has created a website using Blazor that shows the major themes of modern .NET: <a href=\"https:\/\/themesof.net\/\">https:\/\/themesof.net\/<\/a><\/p>\n<\/section>\n<section data-number=\"2.9.6\" id=\"calibre_link-76\">\n<h3 data-number=\"2.9.6\" class=\"calibre8\">Exercise 1.6 &ndash; Free Code Camp and C# Certification<\/h3>\n<p class=\"rights\">For many years, Microsoft had an exam for C# 5, <em class=\"calibre10\">Exam 70-483: Programming in C#<\/em>. I taught hundreds of developers the skills needed to get qualified and pass it. Sadly, that exam was retired a few years ago.In August 2023, Microsoft announced a new foundational certification for C# alongside a free 35-hour online course. You can read more about how to qualify for the certification at the following link:<a href=\"https:\/\/www.freecodecamp.org\/learn\/foundational-c-sharp-with-microsoft\/\">https:\/\/www.freecodecamp.org\/learn\/foundational-c-sharp-with-microsoft\/<\/a><\/p>\n<\/section>\n<section data-number=\"2.9.7\" id=\"calibre_link-77\">\n<h3 data-number=\"2.9.7\" class=\"calibre8\">Exercise 1.7 &ndash; Alpha versions of .NET<\/h3>\n<p class=\"rights\">You can (but probably shouldn't) download future versions of .NET including alpha versions from the following link:<a href=\"https:\/\/github.com\/dotnet\/installer#table\">https:\/\/github.com\/dotnet\/installer#table<\/a>For example, in August 2023, you could download .NET SDK 9 alpha, which included an early release candidate of the .NET 8 runtime, although so few people do that Edge gives a warning and tries to stop you, as shown in <em class=\"calibre10\">Figure 1.24<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 1.24: Download page for alpha versions of .NET\" height=\"341\" src=\"\/images\/cs12\/000085.png\" width=\"1208\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 1.24: Download page for alpha versions of .NET<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Alpha versions are designed to be used only internally by Microsoft employees. Beta versions (official previews) are designed to be used externally and are publicized in Microsoft blog posts. Personally, I would not download an alpha of .NET 9 until December 2023 when it might have some new features compared to .NET 8. Once official previews of .NET 9 become available in February 2024, I recommend using those instead.<\/p>\n<\/blockquote>\n<p class=\"rights\">For more about using .NET 9 or 10 with this book, please see the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/dotnet9.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/dotnet9.md<\/a>.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"2.10\" id=\"calibre_link-78\">\n<h2 data-number=\"2.10\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, we:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Set up your development environment.<\/li>\n<li class=\"calibre3\">Discussed the similarities and differences between modern .NET, .NET Core, .NET Framework, Xamarin, and .NET Standard in an online article.<\/li>\n<li class=\"calibre3\">Used Visual Studio 2022 and Visual Studio Code with the .NET SDK CLI to create a couple of simple console apps grouped in a solution.<\/li>\n<li class=\"calibre3\">Learned how to download the solution code for this book from its GitHub repository.<\/li>\n<li class=\"calibre3\">And, most importantly, we learned how to find help. This could be in the traditional way, by using help command switches, documentation, and articles, or the modern way, by having a conversation with a coding expert AI, or using an AI-based tool to perform \"grunt work.\"<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will learn how to \"speak\" C#.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-937\">\n<div id=\"calibre_link-1878\" class=\"calibre1\">\n<section data-number=\"3\" id=\"calibre_link-79\">\n<h1 data-number=\"3\" class=\"title\">2 Speaking C#<\/h1>\n<section data-number=\"3.1\" id=\"calibre_link-80\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"3.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000041.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is all about the basics of the C# programming language. Over the course of this chapter, you'll learn how to write statements using the grammar of C#, as well as being introduced to some of the common vocabulary that you will use every day. In addition to this, by the end of the chapter, you'll feel confident in knowing how to temporarily store and work with information in your computer's memory.This chapter covers the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Introducing the C# language<\/li>\n<li class=\"calibre3\">Discovering your C# compiler version<\/li>\n<li class=\"calibre3\">Understanding C# grammar and vocabulary<\/li>\n<li class=\"calibre3\">Working with variables<\/li>\n<li class=\"calibre3\">Exploring more about console apps<\/li>\n<li class=\"calibre3\">Understanding async and await<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"3.2\" id=\"calibre_link-81\">\n<h2 data-number=\"3.2\" class=\"calibre5\">Introducing the C# language<\/h2>\n<p class=\"rights\">This part of the book is about the C# language&mdash;the grammar and vocabulary that you will use every day to write the source code for your applications.Programming languages have many similarities to human languages, except that in programming languages, you can make up your own words, just like Dr. Seuss!In a book written by Dr. Seuss in 1950, <em class=\"calibre10\">If I Ran the Zoo<\/em>, he states this:<\/p>\n<blockquote class=\"calibre14\"><p>\n<em class=\"calibre10\">\"And then, just to show them, I'll sail to Ka-Troo And Bring Back an It-Kutch, a Preep, and a Proo, A Nerkle, a Nerd, and a Seersucker, too!\"<\/em>\n<\/p><\/blockquote>\n<section data-number=\"3.2.1\" id=\"calibre_link-82\">\n<h3 data-number=\"3.2.1\" class=\"calibre8\">C# language versions and features<\/h3>\n<p class=\"rights\">This part of the book covers the C# programming language and is written primarily for beginners, so it covers the fundamental topics that all developers need to know, including declaring variables, storing data, and how to define your own custom data types.This book covers features of the C# language from version 1 up to the latest version, 12.If you already have some familiarity with older versions of C# and are excited to find out about the new features in the most recent versions of C#, I have made it easier for you to jump around by listing language versions and their important new features below, along with the chapter number and topic title where you can learn about them.<\/p>\n<section data-number=\"3.2.1.1\" id=\"calibre_link-1879\">\n<h4 data-number=\"3.2.1.1\" class=\"calibre15\">Project COOL<\/h4>\n<p class=\"rights\">Before the first release of C#, it had the codename <strong class=\"calibre2\">C-like Object-Oriented Language<\/strong> (<strong class=\"calibre2\">COOL<\/strong>).<\/p>\n<\/section>\n<section data-number=\"3.2.1.2\" id=\"calibre_link-1880\">\n<h4 data-number=\"3.2.1.2\" class=\"calibre15\">C# 1<\/h4>\n<p class=\"rights\">C# 1 was released in February 2002 and included all the important features of a statically typed object-oriented modern language, as you will see throughout <em class=\"calibre10\">Chapters 2<\/em> to <em class=\"calibre10\">6<\/em>.<\/p>\n<\/section>\n<section data-number=\"3.2.1.3\" id=\"calibre_link-1881\">\n<h4 data-number=\"3.2.1.3\" class=\"calibre15\">C# 1.2<\/h4>\n<p class=\"rights\">C# 1.2, with a few minor improvements, like automatic disposal at the end of <code class=\"calibre9\">foreach<\/code> statements, was released with Visual Studio .NET 2003.<\/p>\n<\/section>\n<section data-number=\"3.2.1.4\" id=\"calibre_link-1882\">\n<h4 data-number=\"3.2.1.4\" class=\"calibre15\">C# 2<\/h4>\n<p class=\"rights\">C# 2 was released in 2005 and focused on enabling strong data typing using generics, to improve code performance and reduce type errors, including the topics listed in <em class=\"calibre10\">Table 2.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Nullable value types<\/td>\n<td class=\"calibre21\">6<\/td>\n<td class=\"calibre21\">Making a value type nullable<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Generics<\/td>\n<td class=\"calibre21\">6<\/td>\n<td class=\"calibre21\">Making types more reusable with generics<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.1: Features of C# 2 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.5\" id=\"calibre_link-1883\">\n<h4 data-number=\"3.2.1.5\" class=\"calibre15\">C# 3<\/h4>\n<p class=\"rights\">C# 3 was released in 2007 and focused on enabling declarative coding with <strong class=\"calibre2\">Language INtegrated Queries<\/strong> (<strong class=\"calibre2\">LINQ<\/strong>) and related features like anonymous types and lambda expressions, including the topics listed in <em class=\"calibre10\">Table 2.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Implicitly typed local variables<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Inferring the type of a local variable<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">LINQ<\/td>\n<td class=\"calibre21\">11<\/td>\n<td class=\"calibre21\">All topics in <em class=\"calibre10\">Chapter 11<\/em> , <em class=\"calibre10\">Querying and Manipulating Data Using LINQ<\/em><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.2: Features of C# 3 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.6\" id=\"calibre_link-1884\">\n<h4 data-number=\"3.2.1.6\" class=\"calibre15\">C# 4<\/h4>\n<p class=\"rights\">C# 4 was released in 2010 and focused on improving interoperability with dynamic languages like F# and Python, including the topics listed in <em class=\"calibre10\">Table 2.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Dynamic types<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Storing dynamic types<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Named\/optional arguments<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Optional parameters and named arguments<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.3: Features of C# 3 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.7\" id=\"calibre_link-1885\">\n<h4 data-number=\"3.2.1.7\" class=\"calibre15\">C# 5<\/h4>\n<p class=\"rights\">C# 5 was released in 2012 and focused on simplifying asynchronous operation support by automatically implementing complex state machines while writing what looks like synchronous statements, including the topics listed in <em class=\"calibre10\">Table 2.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Simplified asynchronous tasks<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Understanding <code class=\"calibre9\">async<\/code> and <code class=\"calibre9\">await<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.4: Features of C# 5 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.8\" id=\"calibre_link-1886\">\n<h4 data-number=\"3.2.1.8\" class=\"calibre15\">C# 6<\/h4>\n<p class=\"rights\">C# 6 was released in 2015 and focused on minor refinements to the language, including the topics listed in <em class=\"calibre10\">Table 2.5<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">static<\/code> imports<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Simplifying the usage of the console<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Interpolated strings<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Displaying output to the user<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Expression-bodied members<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Defining read-only properties<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.5: Features of C# 6 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.9\" id=\"calibre_link-1887\">\n<h4 data-number=\"3.2.1.9\" class=\"calibre15\">C# 7<\/h4>\n<p class=\"rights\">C# 7 was released in March 2017 and focused on adding functional language features like tuples and pattern matching, as well as minor refinements to the language, including the topics listed in <em class=\"calibre10\">Table 2.6<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Binary literals and digit separators<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Storing whole numbers<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Pattern matching<\/td>\n<td class=\"calibre21\">3<\/td>\n<td class=\"calibre21\">Pattern matching with the <code class=\"calibre9\">if<\/code> statement<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">out<\/code> variables<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Controlling how parameters are passed<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Tuples<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Combining multiple values with tuples<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Local functions<\/td>\n<td class=\"calibre21\">6<\/td>\n<td class=\"calibre21\">Defining local functions<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.6: Features of C# 7 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.10\" id=\"calibre_link-1888\">\n<h4 data-number=\"3.2.1.10\" class=\"calibre15\">C# 7.1<\/h4>\n<p class=\"rights\">C# 7.1 was released in August 2017 and focused on minor refinements to the language, including the topics listed in <em class=\"calibre10\">Table 2.7<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">async<\/code> <code class=\"calibre9\">Main<\/code><\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Improving responsiveness for console apps<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Default literal expressions<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Setting fields with default literals<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Inferred tuple element names<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Inferring tuple names<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.7: Features of C# 7.1 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.11\" id=\"calibre_link-1889\">\n<h4 data-number=\"3.2.1.11\" class=\"calibre15\">C# 7.2<\/h4>\n<p class=\"rights\">C# 7.2 was released in November 2017 and focused on minor refinements to the language, including the topics listed in <em class=\"calibre10\">Table 2.8<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Leading underscores in numeric literals<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Storing whole numbers<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Non-trailing named arguments<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Optional parameters and named arguments<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">private protected<\/code> access modifier<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Understanding access modifiers<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">You can test <code class=\"calibre9\">==<\/code> and <code class=\"calibre9\">!=<\/code> with tuple types<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Comparing tuples<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.8: Features of C# 7.2 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.12\" id=\"calibre_link-1890\">\n<h4 data-number=\"3.2.1.12\" class=\"calibre15\">C# 7.3<\/h4>\n<p class=\"rights\">C# 7.3 was released in May 2018 and focused on performance-oriented safe code, which improved <code class=\"calibre9\">ref<\/code> variables, pointers, and <code class=\"calibre9\">stackalloc<\/code>. These features are advanced and rarely needed by most developers, so they are not covered in this book.<\/p>\n<\/section>\n<section data-number=\"3.2.1.13\" id=\"calibre_link-1891\">\n<h4 data-number=\"3.2.1.13\" class=\"calibre15\">C# 8<\/h4>\n<p class=\"rights\">C# 8 was released in September 2019 and focused on a major change to the language related to null handling, including the topics listed in <em class=\"calibre10\">Table 2.9<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Switch expressions<\/td>\n<td class=\"calibre21\">3<\/td>\n<td class=\"calibre21\">Simplifying <code class=\"calibre9\">switch<\/code> statements with switch expressions<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Nullable reference types<\/td>\n<td class=\"calibre21\">6<\/td>\n<td class=\"calibre21\">Making a reference type nullable<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Default interface methods<\/td>\n<td class=\"calibre21\">6<\/td>\n<td class=\"calibre21\">Understanding the default interface methods<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.9: Features of C# 8 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.14\" id=\"calibre_link-1892\">\n<h4 data-number=\"3.2.1.14\" class=\"calibre15\">C# 9<\/h4>\n<p class=\"rights\">C# 9 was released in November 2020 and focused on record types, refinements to pattern matching, and minimal-code projects, including the topics listed in <em class=\"calibre10\">Table 2.10<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Minimal-code console apps<\/td>\n<td class=\"calibre21\">1<\/td>\n<td class=\"calibre21\">Understanding top-level programs<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Target-typed new expressions<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Using target-typed new expressions to instantiate objects<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Enhanced pattern matching<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Pattern matching with objects<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Records<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Working with records<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.10: Features of C# 9 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.15\" id=\"calibre_link-1893\">\n<h4 data-number=\"3.2.1.15\" class=\"calibre15\">C# 10<\/h4>\n<p class=\"rights\">C# 10 was released in November 2021 and focused on features that minimize the amount of code needed in common scenarios, including the topics listed in <em class=\"calibre10\">Table 2.11<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Global namespace imports<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Importing namespaces<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Constant string literals<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Formatting using interpolated strings<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">File-scoped namespaces<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Simplifying namespace declarations<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Record structs<\/td>\n<td class=\"calibre21\">6<\/td>\n<td class=\"calibre21\">Working with record struct types<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ArgumentNullException.ThrowIfNull<\/code><\/td>\n<td class=\"calibre21\">6<\/td>\n<td class=\"calibre21\">Checking for null in method parameters<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.11: Features of C# 10 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.16\" id=\"calibre_link-1894\">\n<h4 data-number=\"3.2.1.16\" class=\"calibre15\">C# 11<\/h4>\n<p class=\"rights\">C# 11 was released in November 2022 and focused on features that simplify your code, including the topics listed in <em class=\"calibre10\">Table 2.12<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Raw string literals<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Understanding raw string literals<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Line breaks in interpolated string expressions<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Formatting using interpolated strings<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Required properties<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Requiring properties to be set during instantiation<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.12: Features of C# 11 covered in this book<br \/>\n<\/section>\n<section data-number=\"3.2.1.17\" id=\"calibre_link-1895\">\n<h4 data-number=\"3.2.1.17\" class=\"calibre15\">C# 12<\/h4>\n<p class=\"rights\">C# 12 was released in November 2023 and focused on features that simplify your code and improving performance, including the topics listed in <em class=\"calibre10\">Table 2.13<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Inline arrays<\/td>\n<td class=\"calibre21\">3<\/td>\n<td class=\"calibre21\">Understanding inline arrays<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Default lambda parameters<\/td>\n<td class=\"calibre21\">4<\/td>\n<td class=\"calibre21\">Lambda expressions with default parameter values<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">New exception guard clauses<\/td>\n<td class=\"calibre21\">4<\/td>\n<td class=\"calibre21\">Throwing exceptions using guard clauses<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Aliasing any type<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Renaming a type with a <code class=\"calibre9\">using<\/code> alias<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Primary constructors<\/td>\n<td class=\"calibre21\">5<\/td>\n<td class=\"calibre21\">Defining a primary constructor<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Interceptors<\/td>\n<td class=\"calibre21\">7<\/td>\n<td class=\"calibre21\">Method interceptors<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.13: Features of C# 12 mentioned in this book<br \/>\n<\/section>\n<\/section>\n<section data-number=\"3.2.2\" id=\"calibre_link-83\">\n<h3 data-number=\"3.2.2\" class=\"calibre8\">Understanding C# standards<\/h3>\n<p class=\"rights\">Over the years, Microsoft has submitted a few versions of C# to standards bodies, as shown in <em class=\"calibre10\">Table 2.14<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">C# version<\/td>\n<td class=\"calibre21\">ECMA standard<\/td>\n<td class=\"calibre21\">ISO\/IEC standard<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">1.0<\/td>\n<td class=\"calibre21\">ECMA-334:2003<\/td>\n<td class=\"calibre21\">ISO\/IEC 23270:2003<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">2.0<\/td>\n<td class=\"calibre21\">ECMA-334:2006<\/td>\n<td class=\"calibre21\">ISO\/IEC 23270:2006<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">5.0<\/td>\n<td class=\"calibre21\">ECMA-334:2017<\/td>\n<td class=\"calibre21\">ISO\/IEC 23270:2018<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">6.0<\/td>\n<td class=\"calibre21\">ECMA-334:2022<\/td>\n<td class=\"calibre21\">ISO\/IEC 23270:2022<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.14: ECMA standards for C#<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The ECMA standard for C# 7.3 is still a draft. So don't even think about when C# versions 8 to 12 might be ECMA standards! Microsoft made C# open source in 2014. You can read the latest C# standard document at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/specifications\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/specifications<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">More practically useful than the ECMA standards are the public GitHub repositories for making the work on C# and related technologies as open as possible, as shown in <em class=\"calibre10\">Table 2.15<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Description<\/td>\n<td class=\"calibre21\">Link<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">C# language design<\/td>\n<td class=\"calibre21\"><a href=\"https:\/\/github.com\/dotnet\/csharplang\">https:\/\/github.com\/dotnet\/csharplang<\/a><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Compiler implementation<\/td>\n<td class=\"calibre21\"><a href=\"https:\/\/github.com\/dotnet\/roslyn\">https:\/\/github.com\/dotnet\/roslyn<\/a><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Standard to describe the language<\/td>\n<td class=\"calibre21\"><a href=\"https:\/\/github.com\/dotnet\/csharpstandard\">https:\/\/github.com\/dotnet\/csharpstandard<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.15: Public GitHub repositories for C#<br \/>\n<\/section>\n<\/section>\n<section data-number=\"3.3\" id=\"calibre_link-84\">\n<h2 data-number=\"3.3\" class=\"calibre5\">Discovering your C# compiler version<\/h2>\n<p class=\"rights\">The .NET language compiler for C# and Visual Basic, also known as <strong class=\"calibre2\">Roslyn<\/strong>, along with a separate compiler for F#, is distributed as part of the .NET SDK. To use a specific version of C#, you must have at least that version of the .NET SDK installed, as shown in <em class=\"calibre10\">Table 2.16<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">.NET SDK<\/td>\n<td class=\"calibre21\">Roslyn compiler<\/td>\n<td class=\"calibre21\">Default C# language<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">1.0.4<\/td>\n<td class=\"calibre21\">2.0-2.2<\/td>\n<td class=\"calibre21\">7.0<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">1.1.4<\/td>\n<td class=\"calibre21\">2.3-2.4<\/td>\n<td class=\"calibre21\">7.1<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">2.1.2<\/td>\n<td class=\"calibre21\">2.6-2.7<\/td>\n<td class=\"calibre21\">7.2<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">2.1.200<\/td>\n<td class=\"calibre21\">2.8-2.10<\/td>\n<td class=\"calibre21\">7.3<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">3.0<\/td>\n<td class=\"calibre21\">3.0-3.4<\/td>\n<td class=\"calibre21\">8.0<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">5.0<\/td>\n<td class=\"calibre21\">3.8<\/td>\n<td class=\"calibre21\">9.0<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">6.0<\/td>\n<td class=\"calibre21\">4.0<\/td>\n<td class=\"calibre21\">10.0<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">7.0<\/td>\n<td class=\"calibre21\">4.4<\/td>\n<td class=\"calibre21\">11.0<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">8.0<\/td>\n<td class=\"calibre21\">4.8<\/td>\n<td class=\"calibre21\">12.0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.16: .NET SDK versions and their C# compiler versions<\/p>\n<p class=\"rights\">When you create class libraries, you can choose to target .NET Standard as well as versions of modern .NET. They have default C# language versions, as shown in <em class=\"calibre10\">Table 2.17<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">.NET Standard<\/td>\n<td class=\"calibre21\">C#<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">2.0<\/td>\n<td class=\"calibre21\">7.3<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">2.1<\/td>\n<td class=\"calibre21\">8.0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.17: .NET Standard versions and their default C# compiler versions<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Although you must have a minimum version of the .NET SDK installed to have access to a specific compiler version, the projects that you create can target older versions of .NET and still use a modern compiler version. For example, if you have the .NET 7 SDK or later installed, then you can use C# 11 language features in a console app that targets .NET Core 3.0.<\/p>\n<\/blockquote>\n<section data-number=\"3.3.1\" id=\"calibre_link-85\">\n<h3 data-number=\"3.3.1\" class=\"calibre8\">How to output the SDK version<\/h3>\n<p class=\"rights\">Let's see what .NET SDK and C# language compiler versions you have available:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">On Windows, start <strong class=\"calibre2\">Windows Terminal<\/strong> or <strong class=\"calibre2\">Command Prompt<\/strong>. On macOS, start <strong class=\"calibre2\">Terminal<\/strong>.<\/li>\n<li class=\"calibre3\">To determine which version of the .NET SDK you have available, enter the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet --version<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note that the version at the time of publishing is 8.0.100, indicating that it is the initial version of the SDK without any bug fixes or new features yet, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">8.0.100<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"3.3.2\" id=\"calibre_link-86\">\n<h3 data-number=\"3.3.2\" class=\"calibre8\">Enabling a specific language version compiler<\/h3>\n<p class=\"rights\">Developer tools like Visual Studio and the <code class=\"calibre9\">dotnet<\/code> command-line interface assume that you want to use the latest major version of a C# language compiler by default. Before C# 8 was released, C# 7 was the latest major version and was used by default. To use the improvements in a C# point release like 7.1, 7.2, or 7.3, you had to add a <code class=\"calibre9\">&lt;LangVersion&gt;<\/code> configuration element to the project file, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;LangVersion&gt;7.3&lt;\/LangVersion&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">After the release of C# 12 with .NET 8, if Microsoft releases a C# 12.1 compiler and you want to use its new language features, then you will have to add a configuration element to your project file, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;LangVersion&gt;12.1&lt;\/LangVersion&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Potential values for the <code class=\"calibre9\">&lt;LangVersion&gt;<\/code> are shown in <em class=\"calibre10\">Table 2.18<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">&lt;LangVersion&gt;<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">7<\/code> , <code class=\"calibre9\">7.1<\/code> , <code class=\"calibre9\">7.2<\/code> , <code class=\"calibre9\">7.3<\/code> , <code class=\"calibre9\">8<\/code> , <code class=\"calibre9\">9<\/code> , <code class=\"calibre9\">10<\/code> , <code class=\"calibre9\">11<\/code> , <code class=\"calibre9\">12<\/code><\/td>\n<td class=\"calibre21\">Entering a specific version number will use that compiler if it has been installed.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">latestmajor<\/code><\/td>\n<td class=\"calibre21\">Uses the highest major number, for example, 7.0 in August 2019, 8 in October 2019, 9 in November 2020, 10 in November 2021, 11 in November 2022, and 12 in November 2023.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">latest<\/code><\/td>\n<td class=\"calibre21\">Uses the highest major and highest minor number, for example, 7.2 in 2017, 7.3 in 2018, 8 in 2019, and perhaps 12.1 in H1 2024.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">preview<\/code><\/td>\n<td class=\"calibre21\">Uses the highest available preview version, for example, 12.0 in July 2023 with .NET 8 Preview 6 installed.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.18: LangVersion settings for a project file<br \/>\n<\/section>\n<section data-number=\"3.3.3\" id=\"calibre_link-87\">\n<h3 data-number=\"3.3.3\" class=\"calibre8\">Using future C# compiler versions<\/h3>\n<p class=\"rights\">In February 2024, Microsoft is likely to release the first preview of .NET 9 with a C# 13 compiler. You will be able to install its SDK from the following link:<a href=\"https:\/\/dotnet.microsoft.com\/en-us\/download\/dotnet\/9.0\">https:\/\/dotnet.microsoft.com\/en-us\/download\/dotnet\/9.0<\/a>The link will give a <code class=\"calibre9\">404 Missing resource<\/code> error until February 2024, so do not bother using it until then!After you've installed a .NET 9 SDK preview, you will be able to use it to create new projects and explore the new language features in C# 13. After creating a new project, you can edit the <code class=\"calibre9\">.csproj<\/code> file and add the <code class=\"calibre9\">&lt;LangVersion&gt;<\/code> element set to <code class=\"calibre9\">preview<\/code> to use the preview C# 13 compiler, as shown highlighted in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n    &lt;TargetFramework&gt;net9.0&lt;\/TargetFramework&gt;\n    &lt;LangVersion&gt;preview&lt;\/LangVersion&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"3.3.4\" id=\"calibre_link-88\">\n<h3 data-number=\"3.3.4\" class=\"calibre8\">Switching the C# compiler for .NET 8 to a future version<\/h3>\n<p class=\"rights\">.NET 8 is an LTS release, so Microsoft must support developers who continue to use .NET 8 for three years. But that does not mean that you are stuck with the C# 12 compiler for three years!In November 2024, Microsoft is likely to release .NET 9, including a C# 13 compiler with new features. Although future versions of .NET 8 are likely to include preview versions of the C# 13 compiler, to be properly supported by Microsoft, you should only set <code class=\"calibre9\">&lt;LangVersion&gt;<\/code> to <code class=\"calibre9\">preview<\/code> for exploration, not production projects, because it is not supported by Microsoft, and it is more likely to have bugs. Microsoft makes previews available because they want to hear feedback. You can be a part of C#'s development and improvement.Once .NET 9 SDK is made generally available in November 2024, you will be able to get the best of both worlds. You can use the .NET 9 SDK and its C# 13 compiler while your projects continue to target .NET 8. To do so, set the target framework to <code class=\"calibre9\">net8.0<\/code> and add a <code class=\"calibre9\">&lt;LangVersion&gt;<\/code> element set to <code class=\"calibre9\">13<\/code>, as shown highlighted in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n    &lt;LangVersion&gt;13&lt;\/LangVersion&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The preceding project targets <code class=\"calibre9\">net8.0<\/code> so it is supported until November 2026 when run on a monthly patched version of the .NET 8 runtime. If the preceding project is built using .NET 9 SDK, then it can have the <code class=\"calibre9\">&lt;LangVersion&gt;<\/code> set to <code class=\"calibre9\">13<\/code> meaning C# 13.If you target <code class=\"calibre9\">net9.0<\/code>, which new projects will by default if you have installed the .NET 9 SDK, then the default language will be C# 13 so it would not need to be explicitly set.In February 2025, Microsoft is likely to release the first preview of .NET 10, and, in November 2025, it will likely release .NET 10 for general availability in production. You will be able to install its SDK from the following link and explore C# 14 in the same way as described above for C# 13 with .NET 9:<a href=\"https:\/\/dotnet.microsoft.com\/en-us\/download\/dotnet\/10.0\">https:\/\/dotnet.microsoft.com\/en-us\/download\/dotnet\/10.0<\/a>Again, the preceding link is for future use! It will give a <code class=\"calibre9\">404 Missing resource<\/code> error until February 2025, so do not bother using it until then.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Some C# language features depend on changes in the underlying .NET libraries. Even if you use the latest SDK with the latest compiler, you might not be able to use all the new language features while targeting an older version of .NET. For example, C# 11 introduced the <code class=\"calibre9\">required<\/code> keyword, but it cannot be used in a project that targets .NET 6 because that language feature requires new attributes that are only available in .NET 7. Luckily, the compiler will warn you if you try to use a C# feature that is not supported. Just be prepared for that eventuality.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.3.5\" id=\"calibre_link-89\">\n<h3 data-number=\"3.3.5\" class=\"calibre8\">Showing the compiler version<\/h3>\n<p class=\"rights\">We will start by writing code that shows the compiler version:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you've completed <em class=\"calibre10\">Chapter 1<\/em>, <em class=\"calibre10\">Hello, C#! Welcome, .NET!<\/em>, then you will already have a <code class=\"calibre9\">cs12dotnet8<\/code> folder. If not, then you'll need to create it.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Use your preferred code editor to create a new project, as defined in the following list:<\/p>\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Console App [C#]<\/strong> \/ <code class=\"calibre9\">console<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">Vocabulary<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter02<\/code><\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Do not use top-level statements<\/strong>: Cleared<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Enable native AOT publish<\/strong>: Cleared<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If you have forgotten how, or did not complete the previous chapter, then step-by-step instructions for creating a solution with multiple projects are given in <em class=\"calibre10\">Chapter 1<\/em>, <em class=\"calibre10\">Hello, C#! Welcome, .NET!<\/em>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Vocabulary<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, after the comment, add a statement to show the C# version as an error, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#error version<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">If you are using Visual Studio 2022, then navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Without Debugging<\/strong>. When prompted to continue and run the last successful build, click <strong class=\"calibre2\">No<\/strong>.<\/li>\n<li class=\"calibre3\">If you are using Visual Studio Code, then in a terminal for the <code class=\"calibre9\">Vocabulary<\/code> folder, enter the command <code class=\"calibre9\">dotnet run<\/code>. Note that we are expecting a compiler error, so do not panic when you see it!<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Note that the compiler version and the language version appear as a compiler error message number <code class=\"calibre9\">CS8304<\/code>, as shown in <em class=\"calibre10\">Figure 2.1<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.1: A compiler error that shows the C# language version\" height=\"733\" src=\"\/images\/cs12\/000030.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.1: A compiler error that shows the C# language version<\/figcaption><\/figure>\n<p class=\"rights\">The error message in the Visual Studio Code <strong class=\"calibre2\">PROBLEMS<\/strong> window or Visual Studio <strong class=\"calibre2\">Error List<\/strong> window says <code class=\"calibre9\">Compiler version: '4.8.0...'<\/code> with language version <code class=\"calibre9\">default (12.0)<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Comment out the statement that causes the error, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ #error version<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note that the compiler error messages disappear.<\/li>\n<\/ol>\n<\/section>\n<\/section>\n<section data-number=\"3.4\" id=\"calibre_link-90\">\n<h2 data-number=\"3.4\" class=\"calibre5\">Understanding C# grammar and vocabulary<\/h2>\n<p class=\"rights\">Let's start by looking at the basics of the grammar and vocabulary of C#. Throughout this chapter, you will create multiple console apps, with each one showing related features of the C# language.<\/p>\n<section data-number=\"3.4.1\" id=\"calibre_link-91\">\n<h3 data-number=\"3.4.1\" class=\"calibre8\">Understanding C# grammar<\/h3>\n<p class=\"rights\">The grammar of C# includes statements and blocks. To document your code, you can use comments.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Comments should not be the only way that you document your code. Choosing sensible names for variables and functions, writing unit tests, and creating actual documents are other ways to document your code.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.4.2\" id=\"calibre_link-92\">\n<h3 data-number=\"3.4.2\" class=\"calibre8\">Statements<\/h3>\n<p class=\"rights\">In English, we indicate the end of a sentence with a full stop. A sentence can be composed of multiple words and phrases, with the order of words being part of the grammar. For example, in English, we say \"the black cat.\"The adjective, <em class=\"calibre10\">black<\/em>, comes before the noun, <em class=\"calibre10\">cat<\/em>. Whereas French grammar has a different order; the adjective comes after the noun: \"le chat noir.\" What's important to take away from this is that the order matters.C# indicates the end of a <strong class=\"calibre2\">statement<\/strong> with a semicolon. A statement can be composed of multiple <strong class=\"calibre2\">types<\/strong>, <strong class=\"calibre2\">variables<\/strong>, and <strong class=\"calibre2\">expressions<\/strong> made up of <strong class=\"calibre2\">tokens<\/strong>. Each token is separated by white space or some other recognizably different token like an operator, for example, <code class=\"calibre9\">=<\/code> or <code class=\"calibre9\">+<\/code>. For example, in the following statement, <code class=\"calibre9\">decimal<\/code> is a type, <code class=\"calibre9\">totalPrice<\/code> is a variable, and <code class=\"calibre9\">subtotal + salesTax<\/code> is an expression:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">decimal totalPrice = subtotal + salesTax;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The expression is made up of an operand named <code class=\"calibre9\">subtotal<\/code>, an operator <code class=\"calibre9\">+<\/code>, and another operand named <code class=\"calibre9\">salesTax<\/code>. The order of operands and operators matters because the order affects the meaning and result.<\/p>\n<\/section>\n<section data-number=\"3.4.3\" id=\"calibre_link-93\">\n<h3 data-number=\"3.4.3\" class=\"calibre8\">Comments<\/h3>\n<p class=\"rights\">Comments are the primary method of documenting your code to increase an understanding of how it works, for other developers to read, or for you to read even when you come back to it months later.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In <em class=\"calibre10\">Chapter 4, Writing, Debugging, and Testing Functions<\/em>, you will learn about XML comments that start with three slashes <code class=\"calibre9\">\/\/\/<\/code> and work with a tool to generate web pages to document your code.<\/p>\n<\/blockquote>\n<p class=\"rights\">You can add comments to explain your code using a double slash, <code class=\"calibre9\">\/\/<\/code>. The compiler will ignore everything after the <code class=\"calibre9\">\/\/<\/code> until the end of the line, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Sales tax must be added to the subtotal.\nvar totalPrice = subtotal + salesTax;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To write a multiline comment, use <code class=\"calibre9\">\/*<\/code> at the beginning and <code class=\"calibre9\">*\/<\/code> at the end of the comment, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/*\nThis is a \nmulti-line comment.\n*\/<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Although <code class=\"calibre9\">\/* *\/<\/code> is mostly used for multiline comments, it is also useful for commenting in the middle of a statement, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">decimal totalPrice = subtotal \/* for this item *\/ + salesTax;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Well-designed code, including function signatures with well-named parameters and class encapsulation, can be somewhat self-documenting. When you find yourself putting too many comments and explanations in your code, ask yourself: can I rewrite, aka refactor, this code to make it more understandable without long comments?<\/p>\n<\/blockquote>\n<p class=\"rights\">Your code editor has commands to make it easier to add and remove comment characters, as shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Visual Studio 2022: Navigate to <strong class=\"calibre2\">Edit<\/strong> | <strong class=\"calibre2\">Advanced<\/strong> | <strong class=\"calibre2\">Comment Selection<\/strong> or <strong class=\"calibre2\">Uncomment Selection<\/strong>.<\/li>\n<li class=\"calibre3\">Visual Studio Code: Navigate to <strong class=\"calibre2\">Edit<\/strong> | <strong class=\"calibre2\">Toggle Line Comment<\/strong> or <strong class=\"calibre2\">Toggle Block Comment<\/strong>.<\/li>\n<li class=\"calibre3\">JetBrains Rider: Navigate to <strong class=\"calibre2\">Code<\/strong> | <strong class=\"calibre2\">Comment with Line Comment<\/strong> or <strong class=\"calibre2\">Comment with Block Comment<\/strong>.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You <strong class=\"calibre2\">comment<\/strong> code by adding descriptive text above or after code statements. You <strong class=\"calibre2\">comment out<\/strong> code by adding comment characters before or around statements to make them inactive. <strong class=\"calibre2\">Uncommenting<\/strong> means removing the comment characters.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.4.4\" id=\"calibre_link-94\">\n<h3 data-number=\"3.4.4\" class=\"calibre8\">Blocks<\/h3>\n<p class=\"rights\">In English, we indicate a new paragraph by starting a new line. C# indicates a <strong class=\"calibre2\">block<\/strong> of code with the use of curly brackets, <code class=\"calibre9\">{ }<\/code>.Blocks start with a declaration to indicate what is being defined. For example, a block can define the start and end of many language constructs including namespaces, classes, methods, or statements like <code class=\"calibre9\">foreach<\/code>.You will learn more about namespaces, classes, and methods later in this chapter and subsequent chapters, but to briefly introduce some of those concepts now:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A <strong class=\"calibre2\">namespace<\/strong> contains types like classes to group them together.<\/li>\n<li class=\"calibre3\">A <strong class=\"calibre2\">class<\/strong> contains the members of an object, including methods.<\/li>\n<li class=\"calibre3\">A <strong class=\"calibre2\">method<\/strong> contains statements that implement an action that an object can take.<\/li>\n<\/ul>\n<p class=\"rights\">Code editors like Visual Studio 2022 and Visual Studio Code provide a handy feature to collapse and expand blocks by toggling the <code class=\"calibre9\">[-]<\/code> or <code class=\"calibre9\">[+]<\/code> or an arrow symbol pointing down or left when you move your mouse cursor over the left margin of the code, as shown in <em class=\"calibre10\">Figure 2.2<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.2: Code editors with expanded and collapsed blocks\" height=\"490\" src=\"\/images\/cs12\/000096.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.2: Code editors with expanded and collapsed blocks<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"3.4.5\" id=\"calibre_link-95\">\n<h3 data-number=\"3.4.5\" class=\"calibre8\">Regions<\/h3>\n<p class=\"rights\">You can define your own labeled regions around any statements you want and then most code editors will allow you to collapse and expand them in the same way as blocks, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Three variables that store the number 2 million.\nint decimalNotation = 2_000_000;\nint binaryNotation = 0b_0001_1110_1000_0100_1000_0000; \nint hexadecimalNotation = 0x_001E_8480;\n#endregion<\/code><\/pre>\n<\/div>\n<p class=\"rights\">In this way, regions can be treated as commented blocks that can be collapsed to show a summary of what the block does. I will use <code class=\"calibre9\">#region<\/code> blocks throughout the solution code in the GitHub repository, especially for the early chapters before we start defining functions that act as natural collapsible regions, but I won't show them in the print book to save space. Use your own judgment to decide if you want to use regions in your own code.<\/p>\n<\/section>\n<section data-number=\"3.4.6\" id=\"calibre_link-96\">\n<h3 data-number=\"3.4.6\" class=\"calibre8\">Examples of statements and blocks<\/h3>\n<p class=\"rights\">In a simple console app that does not use the top-level program feature, I've added some comments to the statements and blocks, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System; \/\/ A semicolon indicates the end of a statement.\nnamespace Basics\n{ \/\/ An open brace indicates the start of a block.\n  class Program\n  {\n    static void Main(string[] args)\n    {\n      Console.WriteLine(\"Hello World!\"); \/\/ A statement.\n    }\n  }\n} \/\/ A close brace indicates the end of a block.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note that C# uses a brace style where both the open and close braces are on their own line and are at the same indentation level, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (x &lt; 3)\n{\n  \/\/ Do something if x is less than 3.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Other languages like JavaScript use curly braces but format them differently. They put the open curly brace at the end of the declaration statement, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (x &lt; 3) {\n  \/\/ Do something if x is less than 3.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You can use whatever style you prefer because the compiler does not care. Sometimes, to save vertical space in a print book, I use the JavaScript brace style, but mostly I stick with the C# brace style. I use two spaces instead of the more common four spaces for indenting because my code will be printed in a book and therefore has narrow width available.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: The official coding style conventions can be found at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/fundamentals\/coding-style\/coding-conventions\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/fundamentals\/coding-style\/coding-conventions<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Regardless of any official guidelines, I recommend that you conform to whatever standards have been adopted by your development team unless you are a solo developer, in which case as long as your code compiles, you can use any conventions you like. Be kind to your future self though by being consistent one way or the other!<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: The brace style used in the Microsoft official documentation is the most commonly used for C#. For example, see the <code class=\"calibre9\">for<\/code> statement, as found at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/statements\/iteration-statements\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/statements\/iteration-statements<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.4.7\" id=\"calibre_link-97\">\n<h3 data-number=\"3.4.7\" class=\"calibre8\">Formatting code using white space<\/h3>\n<p class=\"rights\">White space includes the space, tab, and newline characters. You can use white space to format your code however you like because extra white space has no effect on the compiler.The following four statements are all equivalent:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int sum = 1 + 2; \/\/ Most developers would prefer this format.\nint\nsum=1+\n2; \/\/ One statement over three lines.\nint       sum=    1    +2;int sum=1+2; \/\/ Two statements on one line.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The only white space characters required in the preceding statements is one between <code class=\"calibre9\">int<\/code> and <code class=\"calibre9\">sum<\/code> to tell the compiler they are separate tokens. Any single white space character, for example a space, tab, or newline would be acceptable.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can read the formal definition of C# white space at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/language-specification\/lexical-structure#634-white-space\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/language-specification\/lexical-structure#634-white-space<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.4.8\" id=\"calibre_link-98\">\n<h3 data-number=\"3.4.8\" class=\"calibre8\">Understanding C# vocabulary<\/h3>\n<p class=\"rights\">The C# vocabulary is made up of <strong class=\"calibre2\">keywords<\/strong>, <strong class=\"calibre2\">symbol characters<\/strong>, and <strong class=\"calibre2\">types<\/strong>.Some of the predefined, reserved keywords that you will see in this book and use frequently include <code class=\"calibre9\">using<\/code>, <code class=\"calibre9\">namespace<\/code>, <code class=\"calibre9\">class<\/code>, <code class=\"calibre9\">static<\/code>, <code class=\"calibre9\">int<\/code>, <code class=\"calibre9\">string<\/code>, <code class=\"calibre9\">double<\/code>, <code class=\"calibre9\">bool<\/code>, <code class=\"calibre9\">if<\/code>, <code class=\"calibre9\">switch<\/code>, <code class=\"calibre9\">break<\/code>, <code class=\"calibre9\">while<\/code>, <code class=\"calibre9\">do<\/code>, <code class=\"calibre9\">for<\/code>, <code class=\"calibre9\">foreach<\/code>, <code class=\"calibre9\">this<\/code>, and <code class=\"calibre9\">true<\/code>.Some of the symbol characters that you will see include <code class=\"calibre9\">\"<\/code>, <code class=\"calibre9\">'<\/code>, <code class=\"calibre9\">+<\/code>, <code class=\"calibre9\">-<\/code>, <code class=\"calibre9\">*<\/code>, <code class=\"calibre9\">\/<\/code>, <code class=\"calibre9\">%<\/code>, <code class=\"calibre9\">@<\/code>, and <code class=\"calibre9\">$<\/code>.There are other contextual keywords that only have a special meaning in a specific context like <code class=\"calibre9\">and<\/code>, <code class=\"calibre9\">or<\/code>, <code class=\"calibre9\">not<\/code>, <code class=\"calibre9\">record<\/code>, and <code class=\"calibre9\">init<\/code>.However, that still means that there are only about 100 actual C# keywords in the language.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: C# keywords use all lowercase. Although you can use all lowercase for your own type names, you should not. With C# 11 and later, the compiler will give a warning if you do, as shown in the following output: <code class=\"calibre9\">Warning CS8981 The type name 'person' only contains lower-cased ascii characters. Such names may become reserved for the language.<\/code><\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.4.9\" id=\"calibre_link-99\">\n<h3 data-number=\"3.4.9\" class=\"calibre8\">Comparing programming languages to human languages<\/h3>\n<p class=\"rights\">The English language has more than 250,000 distinct words, so how does C# get away with only having about 100 keywords? Moreover, why is C# so difficult to learn if it has only 0.0416% of the number of words in the English language?One of the key differences between a human language and a programming language is that developers need to be able to define the new \"words\" with new meanings. Apart from the (about) 100 keywords in the C# language, this book will teach you about some of the hundreds of thousands of \"words\" that other developers have defined, but you will also learn how to define your own \"words.\"Programmers all over the world must learn English because most programming languages use English words such as \"if\" and \"break.\" There are programming languages that use other human languages, such as Arabic, but they are rare. If you are interested in learning more, this YouTube video shows a demonstration of an Arabic programming language: <a href=\"https:\/\/youtu.be\/dkO8cdwf6v8\">https:\/\/youtu.be\/dkO8cdwf6v8<\/a>.<\/p>\n<\/section>\n<section data-number=\"3.4.10\" id=\"calibre_link-100\">\n<h3 data-number=\"3.4.10\" class=\"calibre8\">Changing the color scheme for C# syntax<\/h3>\n<p class=\"rights\">By default, Visual Studio 2022 and Visual Studio Code show C# keywords in blue to make them easier to differentiate from other code, which defaults to black. Both tools allow you to customize the color scheme.In Visual Studio 2022:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Tools<\/strong> | <strong class=\"calibre2\">Options<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Options<\/strong> dialog box, in the <strong class=\"calibre2\">Environment<\/strong> section, select <strong class=\"calibre2\">Fonts and Colors<\/strong>, and then select the display items that you would like to customize. You can also search for the section instead of browsing for it.<\/li>\n<\/ol>\n<p class=\"rights\">In Visual Studio Code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">File<\/strong> | <strong class=\"calibre2\">Preferences<\/strong> | <strong class=\"calibre2\">Theme<\/strong> | <strong class=\"calibre2\">Color Theme<\/strong>. It is in the <strong class=\"calibre2\">Code<\/strong> menu on macOS.<\/li>\n<li class=\"calibre3\">Select a color theme. For reference, I'll use the <strong class=\"calibre2\">Light+ (default light)<\/strong> color theme so that the screenshots look better in a printed book.<\/li>\n<\/ol>\n<p class=\"rights\">In JetBrains Rider:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">File<\/strong> | <strong class=\"calibre2\">Settings<\/strong> | <strong class=\"calibre2\">Editor<\/strong> | <strong class=\"calibre2\">Color Scheme<\/strong>.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"3.4.11\" id=\"calibre_link-101\">\n<h3 data-number=\"3.4.11\" class=\"calibre8\">Help for writing correct code<\/h3>\n<p class=\"rights\">Plain text editors such as Notepad don't help you write correct English. Likewise, Notepad won't help you write the correct C# either.Microsoft Word can help you write English by highlighting spelling mistakes with red squiggles, with Word saying that \"icecream\" should be ice-cream or ice cream, and grammatical errors with blue squiggles, such as a sentence should have an uppercase first letter.Similarly, Visual Studio 2022 and Visual Studio Code's C# extension help you write C# code by highlighting spelling mistakes, such as the method name needing to be <code class=\"calibre9\">WriteLine<\/code> with an uppercase <code class=\"calibre9\">L<\/code>, and grammatical errors, such as statements that must end with a semicolon.The C# extension constantly watches what you type and gives you feedback by highlighting problems with colored squiggly lines, like that of Microsoft Word.Let's see it in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, change the <code class=\"calibre9\">L<\/code> in the <code class=\"calibre9\">WriteLine<\/code> method to lowercase.<\/li>\n<li class=\"calibre3\">Delete the semicolon at the end of the statement.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In Visual Studio Code, navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Problems<\/strong>; in Visual Studio 2022, navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Error List<\/strong>; or in JetBrains Rider, navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Tool Windows<\/strong> | <strong class=\"calibre2\">Problems<\/strong>, and note that a red squiggle appears under the code mistakes and details are shown, as you can see in <em class=\"calibre10\">Figure 2.3<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.3: The Error List window showing two compile errors\" height=\"311\" src=\"\/images\/cs12\/000080.png\" width=\"845\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.3: The Error List window showing two compile errors<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Fix the two coding errors.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"3.4.12\" id=\"calibre_link-102\">\n<h3 data-number=\"3.4.12\" class=\"calibre8\">Importing namespaces<\/h3>\n<p class=\"rights\"><code class=\"calibre9\">System<\/code> is a namespace, which is like an address for a type. To refer to someone's location exactly, you might use <code class=\"calibre9\">Oxford.HighStreet.BobSmith<\/code>, which tells us to look for a person named Bob Smith on the High Street in the city of Oxford.<code class=\"calibre9\">System.Console.WriteLine<\/code> tells the compiler to look for a method named <code class=\"calibre9\">WriteLine<\/code> in a type named <code class=\"calibre9\">Console<\/code> in a namespace named <code class=\"calibre9\">System<\/code>. To simplify our code, the <strong class=\"calibre2\">Console App<\/strong> project template for every version of .NET before 6.0 added a statement at the top of the code file to tell the compiler to always look in the <code class=\"calibre9\">System<\/code> namespace for types that haven't been prefixed with their namespace, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System; \/\/ Import the System namespace.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">We call this <em class=\"calibre10\">importing the namespace<\/em>. The effect of importing a namespace is that all available types in that namespace will be available to your program without needing to enter the namespace prefix. All available types in that namespace will be seen in IntelliSense while you write code.<\/p>\n<\/section>\n<section data-number=\"3.4.13\" id=\"calibre_link-103\">\n<h3 data-number=\"3.4.13\" class=\"calibre8\">Implicitly and globally importing namespaces<\/h3>\n<p class=\"rights\">Traditionally, every <code class=\"calibre9\">.cs<\/code> file that needs to import namespaces would have to start with <code class=\"calibre9\">using<\/code> statements to import those namespaces. Namespaces like <code class=\"calibre9\">System<\/code> and <code class=\"calibre9\">System.Linq<\/code> are needed in almost all <code class=\"calibre9\">.cs<\/code> files, so the first few lines of every <code class=\"calibre9\">.cs<\/code> file often had at least a few <code class=\"calibre9\">using<\/code> statements, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System;\nusing System.Linq;\nusing System.Collections.Generic;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When creating websites and services using ASP.NET Core, there are often dozens of namespaces that each file would have to import.C# 10 introduced a new keyword combination and .NET SDK 6 introduced a new project setting that works together to simplify importing common namespaces.The <code class=\"calibre9\">global using<\/code> keyword combination means you only need to import a namespace in one <code class=\"calibre9\">.cs<\/code> file and it will be available throughout all <code class=\"calibre9\">.cs<\/code> files instead of having to import the namespace at the top of every file that needs it. You could put <code class=\"calibre9\">global using<\/code> statements in the <code class=\"calibre9\">Program.cs<\/code> file, but I recommend creating a separate file for those statements named something like <code class=\"calibre9\">GlobalUsings.cs<\/code> with the contents being all your <code class=\"calibre9\">global using<\/code> statements, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">global using System;\nglobal using System.Linq;\nglobal using System.Collections.Generic;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: As developers get used to this new C# feature, I expect one naming convention for this file to become the de facto standard. As you are about to see, the related .NET SDK feature uses a similar naming convention.<\/p>\n<\/blockquote>\n<p class=\"rights\">Any projects that target .NET 6 or later, and therefore use the C# 10 or later compiler, generate a <code class=\"calibre9\">&lt;ProjectName&gt;.GlobalUsings.g.cs<\/code> file in the <code class=\"calibre9\">obj\\Debug\\net8.0<\/code> folder to implicitly globally import some common namespaces like <code class=\"calibre9\">System<\/code>. The specific list of implicitly imported namespaces depends on which SDK you target, as shown in <em class=\"calibre10\">Table 2.19<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre19\"><\/col>\n<col class=\"calibre19\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">SDK<\/td>\n<td class=\"calibre21\">Implicitly imported namespaces<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Microsoft.NET.Sdk<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">SystemSystem.Collections.GenericSystem.IOSystem.LinqSystem.Net.HttpSystem.ThreadingSystem.Threading.Tasks<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Microsoft.NET.Sdk.Web<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Same as <code class=\"calibre9\">Microsoft.NET.Sdk<\/code> and:<\/p>\n<p class=\"rights\"><code class=\"calibre9\">System.Net.Http.Json<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.AspNetCore.Builder<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.AspNetCore.Hosting<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.AspNetCore.Http<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.AspNetCore.Routing<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.Extensions.Configuration<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.Extensions.DependencyInjection<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.Extensions.Hosting<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.Extensions.Logging<\/code><\/p>\n<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Microsoft.NET.Sdk.Worker<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Same as <code class=\"calibre9\">Microsoft.NET.Sdk<\/code> and:<\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.Extensions.Configuration<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.Extensions.DependencyInjection<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.Extensions.Hosting<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Microsoft.Extensions.Logging<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.19: .NET SDKs and their implicitly imported namespaces<\/p>\n<p class=\"rights\">Let's see the current autogenerated implicit imports file:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, toggle on the <strong class=\"calibre2\">Show All Files<\/strong> button, and note the compiler-generated <code class=\"calibre9\">bin<\/code> and <code class=\"calibre9\">obj<\/code> folders are now visible.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <code class=\"calibre9\">Vocabulary<\/code> project, expand the <code class=\"calibre9\">obj<\/code> folder, expand the <code class=\"calibre9\">Debug<\/code> folder, expand the <code class=\"calibre9\">net8.0<\/code> folder, and then open the file named <code class=\"calibre9\">Vocabulary.GlobalUsings.g.cs<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The naming convention for this file is <code class=\"calibre9\">&lt;ProjectName&gt;.GlobalUsings.g.cs<\/code>. Note the <strong class=\"calibre2\">g<\/strong> for <strong class=\"calibre2\">generated<\/strong> to differentiate it from developer-written code files.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Remember that this file is automatically created by the compiler for projects that target .NET 6 and later, and that it imports some commonly used namespaces including <code class=\"calibre9\">System.Threading<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ &lt;autogenerated \/&gt;\nglobal using global::System;\nglobal using global::System.Collections.Generic;\nglobal using global::System.IO;\nglobal using global::System.Linq;\nglobal using global::System.Net.Http;\nglobal using global::System.Threading;\nglobal using global::System.Threading.Tasks;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close the <code class=\"calibre9\">Vocabulary.GlobalUsings.g.cs<\/code> file.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, open the <code class=\"calibre9\">Vocabulary.csproj<\/code> project file, and then add additional entries to the project file to control which namespaces are implicitly imported, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n  &lt;\/PropertyGroup&gt;\n  &lt;ItemGroup&gt;\n    &lt;Using Remove=\"System.Threading\" \/&gt;\n    &lt;Using Include=\"System.Numerics\" \/&gt;\n    &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n    &lt;Using Include=\"System.Environment\" Alias=\"Env\" \/&gt;\n  &lt;\/ItemGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note that <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> is different from <code class=\"calibre9\">&lt;ImportGroup&gt;<\/code>. Be sure to use the correct one! Also, note that the order of elements in a project group or item group does not matter. For example, <code class=\"calibre9\">&lt;Nullable&gt;<\/code> can be before or after <code class=\"calibre9\">&lt;ImplicitUsings&gt;<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Save the changes to the project file.<\/li>\n<li class=\"calibre3\">Expand the <code class=\"calibre9\">obj<\/code> folder, expand the <code class=\"calibre9\">Debug<\/code> folder, expand the <code class=\"calibre9\">net8.0<\/code> folder, and open the file named <code class=\"calibre9\">Vocabulary.GlobalUsings.g.cs<\/code>.<\/li>\n<li class=\"calibre3\">Note this file now imports <code class=\"calibre9\">System.Numerics<\/code> instead of <code class=\"calibre9\">System.Threading<\/code>, the <code class=\"calibre9\">Environment<\/code> class has been imported and aliased to <code class=\"calibre9\">Env<\/code>, and we have statically imported the <code class=\"calibre9\">Console<\/code> class, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ &lt;autogenerated \/&gt;\nglobal using global::System;\nglobal using global::System.Collections.Generic;\nglobal using global::System.IO;\nglobal using global::System.Linq;\nglobal using global::System.Net.Http;\nglobal using global::System.Numerics;\nglobal using global::System.Threading.Tasks;\nglobal using Env = global::System.Environment;\nglobal using static global::System.Console;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement to output a message from the computer and note that because we statically imported the <code class=\"calibre9\">Console<\/code> class, we can call its methods like <code class=\"calibre9\">WriteLine<\/code> without prefixing them with <code class=\"calibre9\">Console<\/code>, and we can reference the <code class=\"calibre9\">Environment<\/code> class using its alias <code class=\"calibre9\">Env<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine($\"Computer named {Env.MachineName} says \\\"No.\\\"\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the project and note the message, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Computer named DAVROS says \"No.\"<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Your computer name will be different unless you name your computers after characters from Doctor Who like I do.<\/p>\n<\/blockquote>\n<p class=\"rights\">You can disable the implicitly imported namespaces feature for all SDKs by removing the <code class=\"calibre9\">&lt;ImplicitUsings&gt;<\/code> element completely from the project file, or changing its value to <code class=\"calibre9\">disable<\/code>, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ImplicitUsings&gt;disable&lt;\/ImplicitUsings&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You might choose to do this if you want to manually create a single file with all the <code class=\"calibre9\">global using<\/code> statements instead of potentially having one generated automatically and others created manually. But my recommendation is to leave the feature enabled and modify the project file to change what is included in the auto-generated class file in the <code class=\"calibre9\">obj<\/code> folder hierarchy.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.4.14\" id=\"calibre_link-104\">\n<h3 data-number=\"3.4.14\" class=\"calibre8\">Verbs are methods<\/h3>\n<p class=\"rights\">In English, verbs are doing or action words, like \"run\" and \"jump.\" In C#, doing or action words are called <strong class=\"calibre2\">methods<\/strong>. There are hundreds of thousands of methods available to C#. In English, verbs change how they are written based on when in time the action happens. For example, Amir <em class=\"calibre10\">was jumping<\/em> in the past, Beth <em class=\"calibre10\">jumps<\/em> in the present, they <em class=\"calibre10\">jumped<\/em> in the past, and Charlie <em class=\"calibre10\">will jump<\/em> in the future.In C#, methods such as <code class=\"calibre9\">WriteLine<\/code> change how they are called or executed based on the specifics of the action. This is called overloading, which we'll cover in more detail in <em class=\"calibre10\">Chapter 5<\/em>, <em class=\"calibre10\">Building Your Own Types with Object-Oriented Programming<\/em>. But for now, consider the following example:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Outputs the current line terminator.\n\/\/ By default, this is a carriage-return and line feed.\nConsole.WriteLine();\n\/\/ Outputs the greeting and the current line terminator.\nConsole.WriteLine(\"Hello Ahmed\");\n\/\/ Outputs a formatted number and date and the current line terminator.\nConsole.WriteLine( \n  \"Temperature on {0:D} is {1}\u00b0C.\", DateTime.Today, 23.4);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">When I show code snippets without numbered step-by-step instructions, I do not expect you to enter them as code, so they won\u2019t execute out of context .<\/p>\n<\/blockquote>\n<p class=\"rights\">A different and not-quite-exact analogy is that some verbs are spelled the same but have different effects depending on the context, for example, you can lose a game, lose your place in a book, or lose your keys.<\/p>\n<\/section>\n<section data-number=\"3.4.15\" id=\"calibre_link-105\">\n<h3 data-number=\"3.4.15\" class=\"calibre8\">Nouns are types, variables, fields, and properties<\/h3>\n<p class=\"rights\">In English, nouns are names that refer to things. For example, Fido is the name of a dog. The word \"dog\" tells us the type of thing that Fido is, and so to order Fido to fetch a ball, we would use his name.In C#, their equivalents are <strong class=\"calibre2\">types<\/strong>, <strong class=\"calibre2\">variables<\/strong>, <strong class=\"calibre2\">fields<\/strong>, and <strong class=\"calibre2\">properties<\/strong>. For example:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Animal<\/code> and <code class=\"calibre9\">Car<\/code> are types; they are nouns for categorizing things.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Head<\/code> and <code class=\"calibre9\">Engine<\/code> might be fields or properties; they are nouns that belong to <code class=\"calibre9\">Animal<\/code> and <code class=\"calibre9\">Car<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Fido<\/code> and <code class=\"calibre9\">Bob<\/code> are variables; they are nouns for referring to a specific object.<\/li>\n<\/ul>\n<p class=\"rights\">There are tens of thousands of types available to C#, though have you noticed how I didn't say, \"There are tens of thousands of types <em class=\"calibre10\">in<\/em> C#?\" The difference is subtle but important. The language of C# only has a few keywords for types, such as <code class=\"calibre9\">string<\/code> and <code class=\"calibre9\">int<\/code>, and strictly speaking, C# doesn't define any types. Keywords such as <code class=\"calibre9\">string<\/code> that look like types are <strong class=\"calibre2\">aliases<\/strong>, which represent types provided by the platform on which C# runs.It's important to know that C# cannot exist alone; after all, it's a language that runs on variants of .NET. In theory, someone could write a compiler for C# that uses a different platform, with different underlying types. In practice, the platform for C# is .NET, which provides tens of thousands of types to C#, including <code class=\"calibre9\">System.Int32<\/code>, which is the C# keyword alias <code class=\"calibre9\">int<\/code> maps to, as well as many more complex types, such as <code class=\"calibre9\">System.Xml.Linq.XDocument<\/code>.It's worth taking note that the term <strong class=\"calibre2\">type<\/strong> is often confused with <strong class=\"calibre2\">class<\/strong>. Have you ever played the parlor game <em class=\"calibre10\">Twenty Questions<\/em>, also known as <em class=\"calibre10\">Animal, Vegetable, or Mineral<\/em>? In the game, everything can be categorized as an animal, vegetable, or mineral. In C#, every <strong class=\"calibre2\">type<\/strong> can be categorized as a <code class=\"calibre9\">class<\/code>, <code class=\"calibre9\">struct<\/code>, <code class=\"calibre9\">enum<\/code>, <code class=\"calibre9\">interface<\/code>, or <code class=\"calibre9\">delegate<\/code>. You will learn what these mean in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>. As an example, the C# keyword <code class=\"calibre9\">string<\/code> is a <code class=\"calibre9\">class<\/code>, but <code class=\"calibre9\">int<\/code> is a <code class=\"calibre9\">struct<\/code>. So, it is best to use the term <strong class=\"calibre2\">type<\/strong> to refer to both.<\/p>\n<\/section>\n<section data-number=\"3.4.16\" id=\"calibre_link-106\">\n<h3 data-number=\"3.4.16\" class=\"calibre8\">Revealing the extent of the C# vocabulary<\/h3>\n<p class=\"rights\">We know that there are more than 100 keywords in C#, but how many types are there? Let's write some code to find out how many types (and their methods) are available to C# in our simple console app.Don't worry about exactly how this code works for now, but know that it uses a technique called <strong class=\"calibre2\">reflection<\/strong>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Comment out all the existing statements in <code class=\"calibre9\">Program.cs<\/code>.<\/li>\n<li class=\"calibre3\">We'll start by importing the <code class=\"calibre9\">System.Reflection<\/code> namespace at the top of the <code class=\"calibre9\">Program.cs<\/code> file so that we can use some of the types in that namespace like <code class=\"calibre9\">Assembly<\/code> and <code class=\"calibre9\">TypeName<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Reflection; \/\/ To use Assembly, TypeName, and so on.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: We could use the implicit imports and <code class=\"calibre9\">global using<\/code> features to import this namespace for all <code class=\"calibre9\">.cs<\/code> files in this project, but since there is only one file, it is better to import the namespace in the one file in which it is needed.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Write statements to get the compiled console app and loop through all the types that it has access to, outputting the names and number of methods each has, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Get the assembly that is the entry point for this app.\nAssembly? myApp = Assembly.GetEntryAssembly();\n\/\/ If the previous line returned nothing then end the app.\nif (myApp is null) return;\n\/\/ Loop through the assemblies that my app references.\nforeach (AssemblyName name in myApp.GetReferencedAssemblies())\n{\n  \/\/ Load the assembly so we can read its details.\n  Assembly a = Assembly.Load(name);\n  \/\/ Declare a variable to count the number of methods.\n  int methodCount = 0;\n  \/\/ Loop through all the types in the assembly.\n  foreach (TypeInfo t in a.DefinedTypes)\n  {\n    \/\/ Add up the counts of all the methods.\n    methodCount += t.GetMethods().Length;\n  }\n  \/\/ Output the count of types and their methods.\n  WriteLine(\"{0:N0} types with {1:N0} methods in {2} assembly.\",\n    arg0: a.DefinedTypes.Count(),\n    arg1: methodCount, \n    arg2: name.Name);\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">N0<\/code> is uppercase <code class=\"calibre9\">N<\/code> followed by the digit zero. It is not uppercase <code class=\"calibre9\">N<\/code> followed by uppercase <code class=\"calibre9\">O<\/code>. It means \u201cformat a number (<code class=\"calibre9\">N<\/code>) with zero (<code class=\"calibre9\">0<\/code>) decimal places\u201d.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the project. You will see the actual number of types and methods that are available to you in the simplest application when running on your <strong class=\"calibre2\">operating system<\/strong> (<strong class=\"calibre2\">OS<\/strong>). The number of types and methods displayed will be different depending on the OS that you are using, as shown in the following output on Windows:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">0 types with 0 methods in System.Runtime assembly.\n41 types with 639 methods in System.Console assembly.\n112 types with 1,190 methods in System.Linq assembly.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Why does the <code class=\"calibre9\">System.Runtime<\/code> assembly contain zero types? This assembly is special because it contains only <strong class=\"calibre2\">type-forwarders<\/strong> rather than actual types. A type-forwarder represents a type that has been implemented outside of .NET or for some other advanced reason.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to the top of the file (after importing the <code class=\"calibre9\">System.Reflection<\/code> namespace) to declare some variables, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Declare some unused variables using types in\n\/\/ additional assemblies to make them load too.\nSystem.Data.DataSet ds = new();\nHttpClient client = new();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app again and view the results, which should look like the following outputs:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">0 types with 0 methods in System.Runtime assembly.\n406 types with 7,139 methods in System.Data.Common assembly.\n425 types with 4,681 methods in System.Net.Http assembly.\n41 types with 639 methods in System.Console assembly.\n112 types with 1,190 methods in System.Linq assembly.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Now, you have a better sense of why learning C# is a challenge &ndash; because there are so many types and methods to learn. Methods are only one category of a member that a type can have, and you and other programmers are constantly defining new types and members!<\/p>\n<\/section>\n<section data-number=\"3.4.17\" id=\"calibre_link-107\">\n<h3 data-number=\"3.4.17\" class=\"calibre8\">Example of asking ChatGPT to explain code<\/h3>\n<p class=\"rights\">The code we wrote in the <code class=\"calibre9\">Vocabulary<\/code> project is a good example of when you might want to ask ChatGPT to explain something. If you enter a prompt of \"Explain the following code:\" followed by the code, here's what it responded with at the time of writing in July 2023:<em class=\"calibre10\">\"This C# code performs an analysis of the assemblies (essentially libraries or modules) referenced by the current application. It tallies up the total number of types and methods in each referenced assembly.Let's break down the code in more detail:<\/em><\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\"><em class=\"calibre10\">System.Reflection namespace is used to work with assemblies, modules, types, methods, and so on, at runtime.<\/em><\/li>\n<li class=\"calibre3\"><em class=\"calibre10\">The System.Data.DataSet and HttpClient instances are declared but not used. The comment implies that these are declared to ensure their respective assemblies are loaded for the subsequent analysis. Creating instances of classes from certain assemblies can cause those assemblies to be loaded into memory.<\/em><\/li>\n<li class=\"calibre3\"><em class=\"calibre10\">Assembly.GetEntryAssembly() gets the assembly that is the entry point of the application.<\/em><\/li>\n<li class=\"calibre3\"><em class=\"calibre10\">If myApp is null (meaning there's no entry assembly, which should be impossible in a normally running .NET app), the application exits.<\/em><\/li>\n<li class=\"calibre3\"><em class=\"calibre10\">The foreach loop iterates over each assembly name in the referenced assemblies of the entry point assembly.<\/em><\/li>\n<li class=\"calibre3\"><em class=\"calibre10\">Assembly.Load(name) loads an assembly given the assembly name. This allows you to interact with the assembly programmatically.<\/em><\/li>\n<li class=\"calibre3\"><em class=\"calibre10\">A counter variable methodCount is declared and initialized to 0. This is used to count the total number of methods in the assembly.<\/em><\/li>\n<li class=\"calibre3\"><em class=\"calibre10\">Another nested foreach loop then iterates over each type in the assembly.<\/em><\/li>\n<li class=\"calibre3\"><em class=\"calibre10\">For each type, it gets the number of methods (t.GetMethods().Length) and adds it to the methodCount.<\/em><\/li>\n<li class=\"calibre3\"><em class=\"calibre10\">Finally, the number of types and their methods in the assembly are output to the console using WriteLine(). The {0:N0} format specifier in the string is a placeholder for a number (0 refers to the argument index, N is for number format, and 0 after N specifies the number of decimal places).<\/em><\/li>\n<\/ol>\n<p class=\"rights\"><em class=\"calibre10\">So, in essence, this script counts how many types and methods exist in each assembly referenced by the application. This might be useful to understand the complexity or size of the dependencies the application has.\"<\/em>And now back to the flesh and blood Mark: That's a pretty good explanation with no mistakes or hallucinations!<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Tools like GitHub Copilot and ChatGPT are especially useful for programmers when they are learning new things. And a good programmer is always learning new things! These tools are not just for writing code for you. They can explain existing code written by others and even suggest improvements.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"3.5\" id=\"calibre_link-108\">\n<h2 data-number=\"3.5\" class=\"calibre5\">Working with variables<\/h2>\n<p class=\"rights\">All applications process data. Data comes in, data is processed, and then data goes out.Data usually comes into our program from files, databases, or user input, and it can be put temporarily into variables, which will be stored in the memory of the running program. When the program ends, the data in memory is lost. Data is usually output to files and databases, or to the screen or a printer. When using variables, you should think about, firstly, how much space the variable takes up in the memory, and, secondly, how fast it can be processed.We control this by picking an appropriate type. You can think of simple common types such as <code class=\"calibre9\">int<\/code> and <code class=\"calibre9\">double<\/code> as being different-sized storage boxes, where a smaller box would take less memory but may not be as fast at being processed; for example, adding 16-bit numbers might not be processed as quickly as adding 64-bit numbers on a 64-bit operating system. Some of these boxes may be stacked close by, and some may be thrown into a big heap further away.<\/p>\n<section data-number=\"3.5.1\" id=\"calibre_link-109\">\n<h3 data-number=\"3.5.1\" class=\"calibre8\">Naming things and assigning values<\/h3>\n<p class=\"rights\">There are naming conventions for things, and it is a good practice to follow them, as shown in <em class=\"calibre10\">Table 2.20<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Naming convention<\/td>\n<td class=\"calibre21\">Examples<\/td>\n<td class=\"calibre21\">Used for<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Camel case<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">cost<\/code> , <code class=\"calibre9\">orderDetail<\/code> , and <code class=\"calibre9\">dateOfBirth<\/code><\/td>\n<td class=\"calibre21\">Local variables, private fields.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Title case aka Pascal case<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">String<\/code> , <code class=\"calibre9\">Int32<\/code> , <code class=\"calibre9\">Cost<\/code> , <code class=\"calibre9\">DateOfBirth<\/code> , and <code class=\"calibre9\">Run<\/code><\/td>\n<td class=\"calibre21\">Types, non-private fields, and other members like methods.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.20: Naming conventions and what they should be used for<\/p>\n<p class=\"rights\">Some C# programmers like to prefix the names of private fields with an underscore, for example, <code class=\"calibre9\">_dateOfBirth<\/code> instead of <code class=\"calibre9\">dateOfBirth<\/code>. The naming of private members of all kinds is not formally defined because they will not be visible outside the class, so writing them with or without an underscore prefix are both valid.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Following a consistent set of naming conventions will enable your code to be easily understood by other developers (and yourself in the future!).<\/p>\n<\/blockquote>\n<p class=\"rights\">The following code block shows an example of declaring a named local variable and assigning a value to it with the <code class=\"calibre9\">=<\/code> symbol. You should note that you can output the name of a variable using a keyword introduced in C# 6, <code class=\"calibre9\">nameof<\/code>:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Let the heightInMetres variable become equal to the value 1.88.\ndouble heightInMetres = 1.88;\nConsole.WriteLine($\"The variable {nameof(heightInMetres)} has the value\n{heightInMetres}.\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> The message in double quotes in the preceding code wraps onto a second line because the width of a printed page is too narrow. When entering a statement like this in your code editor, type it all in a single line.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In C# 12, <code class=\"calibre9\">nameof<\/code> can now access instance data from a static context. You will learn the difference between instance and static data in <em class=\"calibre10\">Chapter 5<\/em>, <em class=\"calibre10\">Building Your Own Types with Object-Oriented Programming<\/em>.<\/p>\n<\/blockquote>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.5.2\" id=\"calibre_link-110\">\n<h3 data-number=\"3.5.2\" class=\"calibre8\">Literal values<\/h3>\n<p class=\"rights\">When you assign to a variable, you often, but not always, assign a <strong class=\"calibre2\">literal<\/strong> value. But what is a literal value? A literal is a notation that represents a fixed value. Data types have different notations for their literal values, and over the next few sections, you will see examples of using literal notation to assign values to variables.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can read the formal definition of literals in the C# language specification: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/language-specification\/lexical-structure#645-literals\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/language-specification\/lexical-structure#645-literals<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.5.3\" id=\"calibre_link-111\">\n<h3 data-number=\"3.5.3\" class=\"calibre8\">Storing text<\/h3>\n<p class=\"rights\">For text, a single letter, such as an <code class=\"calibre9\">A<\/code>, is stored as a <code class=\"calibre9\">char<\/code> type.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Actually, it can be more complicated than that. Egyptian Hieroglyph A002 (U+13001) needs two <code class=\"calibre9\">System.Char<\/code> values (known as surrogate pairs) to represent it: <code class=\"calibre9\">\\uD80C<\/code> and <code class=\"calibre9\">\\uDC01<\/code>. Do not always assume one <code class=\"calibre9\">char<\/code> equals one letter or you could introduce hard-to-notice bugs into your code.<\/p>\n<\/blockquote>\n<p class=\"rights\">A <code class=\"calibre9\">char<\/code> is assigned using single quotes around the literal value, or assigning the return value of a function call, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">char letter = 'A'; \/\/ Assigning literal characters.\nchar digit = '1'; \nchar symbol = '$';\nchar userChoice = GetChar(); \/\/ Assigning from a fictitious function.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">For text, multiple letters, such as <code class=\"calibre9\">Bob<\/code>, are stored as a <code class=\"calibre9\">string<\/code> type and are assigned using double quotes around the literal value, or by assigning the return value of a function call or constructor, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string firstName = \"Bob\"; \/\/ Assigning literal strings.\nstring lastName = \"Smith\";\nstring phoneNumber = \"(215) 555-4256\";\n\/\/ Assigning a string returned from the string class constructor.\nstring horizontalLine = new('-', count: 74); \/\/ 74 hyphens.\n\/\/ Assigning a string returned from a fictitious function.\nstring address = GetAddressFromDatabase(id: 563);\n\/\/ Assigning an emoji by converting from Unicode.\nstring grinningEmoji = char.ConvertFromUtf32(0x1F600);<\/code><\/pre>\n<\/div>\n<section data-number=\"3.5.3.1\" id=\"calibre_link-1896\">\n<h4 data-number=\"3.5.3.1\" class=\"calibre15\">Outputting emojis<\/h4>\n<p class=\"rights\">To output emojis at a command prompt on Windows, you must use Windows Terminal because Command Prompt does not support emojis and set the output encoding of the console to use UTF-8, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Console.OutputEncoding = System.Text.Encoding.UTF8;\nstring grinningEmoji = char.ConvertFromUtf32(0x1F600);\nConsole.WriteLine(grinningEmoji);<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"3.5.3.2\" id=\"calibre_link-1897\">\n<h4 data-number=\"3.5.3.2\" class=\"calibre15\">Verbatim strings<\/h4>\n<p class=\"rights\">When storing text in a <code class=\"calibre9\">string<\/code> variable, you can include escape sequences, which represent special characters like tabs and new lines using a backslash, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string fullNameWithTabSeparator = \"Bob\\tSmith\";<\/code><\/pre>\n<\/div>\n<p class=\"rights\">But what if you are storing the path to a file on Windows, and one of the folder names starts with a <code class=\"calibre9\">T<\/code>, as shown in the following code?<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string filePath = \"C:\\televisions\\sony\\bravia.txt\";<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The compiler will convert the <code class=\"calibre9\">\\t<\/code> into a tab character and you will get errors!You must prefix it with the <code class=\"calibre9\">@<\/code> symbol to use a verbatim literal <code class=\"calibre9\">string<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string filePath = @\"C:\\televisions\\sony\\bravia.txt\";<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"3.5.3.3\" id=\"calibre_link-1898\">\n<h4 data-number=\"3.5.3.3\" class=\"calibre15\">Raw string literals<\/h4>\n<p class=\"rights\">Introduced in C# 11, raw string literals are convenient for entering any arbitrary text without needing to escape the contents. They make it easy to define literals containing other languages like XML, HTML, or JSON.Raw string literals start and end with three or more double-quote characters, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string xml = \"\"\"\n             &lt;person age=\"50\"&gt;\n               &lt;first_name&gt;Mark&lt;\/first_name&gt;\n             &lt;\/person&gt;\n             \"\"\";<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Why three <em class=\"calibre10\">or more<\/em> double-quote characters? This is for scenarios where the content itself needs to have three double-quote characters; you can then use four double-quote characters to indicate the beginning and end of the content. Where the content needs to have four double-quote characters, you can then use five double-quote characters to indicate the beginning and end of the content. And so on.In the previous code, the XML is indented by 13 spaces. The compiler looks at the indentation of the last three or more double-quote characters, and then automatically removes that level of indentation from all the content inside the raw string literal. The results of the previous code would therefore not be indented as in the defining code, but instead be aligned with the left margin, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;person age=\"50\"&gt;\n  &lt;first_name&gt;Mark&lt;\/first_name&gt;\n&lt;\/person&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If the end three double-quote characters are aligned with the left margin, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string xml = \"\"\"\n             &lt;person age=\"50\"&gt;\n               &lt;first_name&gt;Mark&lt;\/first_name&gt;\n             &lt;\/person&gt;\n\"\"\";<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Then the 13-space indentation would not be removed, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">             &lt;person age=\"50\"&gt;\n               &lt;first_name&gt;Mark&lt;\/first_name&gt;\n             &lt;\/person&gt;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"3.5.3.4\" id=\"calibre_link-1899\">\n<h4 data-number=\"3.5.3.4\" class=\"calibre15\">Raw interpolated string literals<\/h4>\n<p class=\"rights\">You can mix interpolated strings that use curly braces <code class=\"calibre9\">{<\/code> <code class=\"calibre9\">}<\/code> with raw string literals. You specify the number of braces that indicates a replaced expression by adding that number of dollar signs to the start of the literal. Any fewer braces than that are treated as raw content.For example, if we want to define some JSON, single braces will be treated as normal braces, but the two dollar symbols tell the compiler that any two curly braces indicate a replaced expression value, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var person = new { FirstName = \"Alice\", Age = 56 };\nstring json = $$\"\"\"\n              {\n                \"first_name\": \"{{person.FirstName}}\",\n                \"age\": {{person.Age}},\n                \"calculation\": \"{{{ 1 + 2 }}}\"\n              }\n              \"\"\";\nConsole.WriteLine(json);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The previous code would generate the following JSON document:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"first_name\": \"Alice\",\n  \"age\": 56,\n  \"calculation\": \"{3}\"\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The number of dollars tells the compiler how many curly braces are needed to become recognized as an interpolated expression.<\/p>\n<\/section>\n<section data-number=\"3.5.3.5\" id=\"calibre_link-1900\">\n<h4 data-number=\"3.5.3.5\" class=\"calibre15\">Summarizing options for storing text<\/h4>\n<p class=\"rights\">To summarize:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Literal string<\/strong>: Characters enclosed in double-quote characters. They can use escape characters like <code class=\"calibre9\">\\t<\/code> for tab. To represent a backslash, use two: <code class=\"calibre9\">\\\\<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Raw string literal<\/strong>: Characters enclosed in three or more double-quote characters.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Verbatim string<\/strong>: A literal string prefixed with <code class=\"calibre9\">@<\/code> to disable escape characters so that a backslash is a backslash. It also allows the <code class=\"calibre9\">string<\/code> value to span multiple lines because the whitespace characters are treated as themselves instead of instructions to the compiler.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Interpolated string<\/strong>: A literal string prefixed with <code class=\"calibre9\">$<\/code> to enable embedded formatted variables. You will learn more about this later in this chapter.<\/li>\n<\/ul>\n<\/section>\n<\/section>\n<section data-number=\"3.5.4\" id=\"calibre_link-112\">\n<h3 data-number=\"3.5.4\" class=\"calibre8\">Storing numbers<\/h3>\n<p class=\"rights\">Numbers are data that we want to perform an arithmetic calculation on, for example, multiplying. A telephone number is not a number. To decide whether a variable should be stored as a number or not, ask yourself whether you need to perform arithmetic operations on the number or whether the number includes non-digit characters such as parentheses or hyphens to format the number, such as (414) 555-1234. In this case, the \"number\" is a sequence of characters, so it should be stored as a <code class=\"calibre9\">string<\/code>.Numbers can be natural numbers, such as 42, used for counting (also called whole numbers); they can also be negative numbers, such as -42 (called integers); or they can be real numbers, such as 3.9 (with a fractional part), which are called single- or double-precision floating-point numbers in computing.Let's explore numbers:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">Numbers<\/code> to the <code class=\"calibre9\">Chapter02<\/code> solution.\n<ul class=\"calibre16\">\n<li class=\"calibre3\">For Visual Studio 2022, configure the startup project to the current selection.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing code, and then type statements to declare some number variables using various data types, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ An unsigned integer is a positive whole number or 0.\nuint naturalNumber = 23;\n\/\/ An integer is a negative or positive whole number or 0.\nint integerNumber = -23;\n\/\/ A float is a single-precision floating-point number.\n\/\/ The F or f suffix makes the value a float literal.\n\/\/ The suffix is required to compile.\nfloat realNumber = 2.3f;\n\/\/ A double is a double-precision floating-point number.\n\/\/ double is the default for a number value with a decimal point.\ndouble anotherRealNumber = 2.3; \/\/ A double literal value.<\/code><\/pre>\n<\/div>\n<section data-number=\"3.5.4.1\" id=\"calibre_link-1901\">\n<h4 data-number=\"3.5.4.1\" class=\"calibre15\">Storing whole numbers<\/h4>\n<p class=\"rights\">You might know that computers store everything as bits. The value of a bit is either <code class=\"calibre9\">0<\/code> or <code class=\"calibre9\">1<\/code>. This is called a <strong class=\"calibre2\">binary number system<\/strong>. Humans use a <strong class=\"calibre2\">decimal number system<\/strong>.The decimal number system, also known as Base 10, has 10 as its <strong class=\"calibre2\">base<\/strong>, meaning there are 10 digits, from 0 to 9. Although it is the number base most used by human civilizations, other number base systems are popular in science, engineering, and computing. The binary number system, also known as Base 2, has two as its base, meaning there are two digits, 0 and 1.The following image shows how computers store the decimal number 10. Take note of the bits with the value 1 in the 8 and 2 columns; 8 + 2 = 10:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.4: Computers storing the decimal number 10\" height=\"167\" src=\"\/images\/cs12\/000072.png\" width=\"1730\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.4: Computers storing the decimal number 10<\/figcaption><\/figure>\n<p class=\"rights\">So, <code class=\"calibre9\">10<\/code> in decimal is <code class=\"calibre9\">00001010<\/code> in a binary byte (8 bits).<\/p>\n<\/section>\n<section data-number=\"3.5.4.2\" id=\"calibre_link-1902\">\n<h4 data-number=\"3.5.4.2\" class=\"calibre15\">Improving legibility by using digit separators<\/h4>\n<p class=\"rights\">Two of the improvements seen in C# 7 and later are the use of the underscore character <code class=\"calibre9\">_<\/code> as a digit separator and support for binary literals.You can insert underscores anywhere into the digits of a number literal, including decimal, binary, or hexadecimal notation, to improve legibility.For example, you could write the value for 1 million in decimal notation, that is, Base 10, as <code class=\"calibre9\">1_000_000<\/code>.You can even use the 2\/3 grouping common in India: <code class=\"calibre9\">10_00_000<\/code>.<\/p>\n<\/section>\n<section data-number=\"3.5.4.3\" id=\"calibre_link-1903\">\n<h4 data-number=\"3.5.4.3\" class=\"calibre15\">Using binary or hexadecimal notation<\/h4>\n<p class=\"rights\">To use binary notation, that is, Base 2, using only 1s and 0s, start the number literal with <code class=\"calibre9\">0b<\/code>. To use hexadecimal notation, that is, Base 16, using 0 to 9 and A to F, start the number literal with <code class=\"calibre9\">0x<\/code>.<\/p>\n<\/section>\n<section data-number=\"3.5.4.4\" id=\"calibre_link-1904\">\n<h4 data-number=\"3.5.4.4\" class=\"calibre15\">Exploring whole numbers<\/h4>\n<p class=\"rights\">Let\u2019s enter some code to see some examples:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Numbers<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, type statements to declare some number variables using underscore separators, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int decimalNotation = 2_000_000;\nint binaryNotation = 0b_0001_1110_1000_0100_1000_0000; \nint hexadecimalNotation = 0x_001E_8480;\n\/\/ Check the three variables have the same value.\nConsole.WriteLine($\"{decimalNotation == binaryNotation}\"); \nConsole.WriteLine(\n  $\"{decimalNotation == hexadecimalNotation}\");\n\/\/ Output the variable values in decimal.\nConsole.WriteLine($\"{decimalNotation:N0}\");\nConsole.WriteLine($\"{binaryNotation:N0}\");\nConsole.WriteLine($\"{hexadecimalNotation:N0}\");\n\/\/ Output the variable values in hexadecimal.\nConsole.WriteLine($\"{decimalNotation:X}\");\nConsole.WriteLine($\"{binaryNotation:X}\");\nConsole.WriteLine($\"{hexadecimalNotation:X}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the project and note the result is that all three numbers are the same, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">True\nTrue\n2,000,000\n2,000,000\n2,000,000\n1E8480\n1E8480\n1E8480<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Computers can always exactly represent integers using the <code class=\"calibre9\">int<\/code> type or one of its sibling types, such as <code class=\"calibre9\">long<\/code> and <code class=\"calibre9\">short<\/code>.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"3.5.5\" id=\"calibre_link-113\">\n<h3 data-number=\"3.5.5\" class=\"calibre8\">Storing real numbers<\/h3>\n<p class=\"rights\">Computers cannot always represent real, aka decimal or non-integer, numbers precisely. The <code class=\"calibre9\">float<\/code> and <code class=\"calibre9\">double<\/code> types store real numbers using single- and double-precision floating points.Most programming languages implement the <strong class=\"calibre2\">Institute of Electrical and Electronics Engineers<\/strong> (<strong class=\"calibre2\">IEEE<\/strong>) Standard for Floating-Point Arithmetic. IEEE 754 is a technical standard for floating-point arithmetic established in 1985 by the IEEE.The following image shows a simplification of how a computer represents the number <code class=\"calibre9\">12.75<\/code> in binary notation. Note the bits with the value <code class=\"calibre9\">1<\/code> in the 8, 4, \u00bd, and \u00bc columns.8 + 4 + \u00bd + \u00bc = 12\u00be = 12.75.<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.5: Computer representing number 12.75 in binary notation\" height=\"164\" src=\"\/images\/cs12\/000036.png\" width=\"1730\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.5: Computer representing number 12.75 in binary notation<\/figcaption><\/figure>\n<p class=\"rights\">So, <code class=\"calibre9\">12.75<\/code> in decimal is <code class=\"calibre9\">00001100.1100<\/code> in binary. As you can see, the number <code class=\"calibre9\">12.75<\/code> can be exactly represented using bits. However, most numbers can\u2019t, which is something that we\u2019ll be exploring shortly.<\/p>\n<section data-number=\"3.5.5.1\" id=\"calibre_link-1905\">\n<h4 data-number=\"3.5.5.1\" class=\"calibre15\">Writing code to explore number sizes<\/h4>\n<p class=\"rights\">C# has an operator named <code class=\"calibre9\">sizeof()<\/code> that returns the number of bytes that a type uses in memory. Some types have members named <code class=\"calibre9\">MinValue<\/code> and <code class=\"calibre9\">MaxValue<\/code>, which return the minimum and maximum values that can be stored in a variable of that type. We are now going to use these features to create a console app to explore number types:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, at the bottom of the file, type statements to show the size of three number data types, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Console.WriteLine($\"int uses {sizeof(int)} bytes and can store numbers in the range {int.MinValue:N0} to {int.MaxValue:N0}.\"); \nConsole.WriteLine($\"double uses {sizeof(double)} bytes and can store numbers in the range {double.MinValue:N0} to {double.MaxValue:N0}.\"); \nConsole.WriteLine($\"decimal uses {sizeof(decimal)} bytes and can store numbers in the range {decimal.MinValue:N0} to {decimal.MaxValue:N0}.\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> The width of the printed pages in this book makes the <code class=\"calibre9\">string<\/code> values (in double quotes) wrap over multiple lines. You must type them on a single line, or you will get compile errors.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the output, as shown in <em class=\"calibre10\">Figure 2.6<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.6: Size and range information for common number data types\" height=\"313\" src=\"\/images\/cs12\/000053.png\" width=\"850\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.6: Size and range information for common number data types<\/figcaption><\/figure>\n<p class=\"rights\">An <code class=\"calibre9\">int<\/code> variable uses four bytes of memory and can store positive or negative numbers up to about 2 billion. A <code class=\"calibre9\">double<\/code> variable uses 8 bytes of memory and can store much bigger values! A <code class=\"calibre9\">decimal<\/code> variable uses 16 bytes of memory and can store big numbers, but not as big as a <code class=\"calibre9\">double<\/code> type.But you may be asking yourself, why might a <code class=\"calibre9\">double<\/code> variable be able to store bigger numbers than a <code class=\"calibre9\">decimal<\/code> variable, yet it\u2019s only using half the space in memory? Well, let\u2019s now find out!<\/p>\n<\/section>\n<section data-number=\"3.5.5.2\" id=\"calibre_link-1906\">\n<h4 data-number=\"3.5.5.2\" class=\"calibre15\">Comparing double and decimal types<\/h4>\n<p class=\"rights\">You will now write some code to compare <code class=\"calibre9\">double<\/code> and <code class=\"calibre9\">decimal<\/code> values. Although it isn\u2019t hard to follow, don\u2019t worry about understanding the syntax right now:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type statements to declare two <code class=\"calibre9\">double<\/code> variables, add them together, and compare them to the expected result. Then, write the result to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Console.WriteLine(\"Using doubles:\"); \ndouble a = 0.1;\ndouble b = 0.2;\nif (a + b == 0.3)\n{\n  Console.WriteLine($\"{a} + {b} equals {0.3}\");\n}\nelse\n{\n  Console.WriteLine($\"{a} + {b} does NOT equal {0.3}\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Using doubles:\n0.1 + 0.2 does NOT equal 0.3<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In cultures that use a comma for the decimal separator, the result will look slightly different, as shown in the following output: <code class=\"calibre9\">0,1 + 0,2 does NOT equal 0,3<\/code>.<\/p>\n<\/blockquote>\n<p class=\"rights\">The <code class=\"calibre9\">double<\/code> type is not guaranteed to be accurate because most numbers like <code class=\"calibre9\">0.1<\/code>, <code class=\"calibre9\">0.2<\/code>, and <code class=\"calibre9\">0.3<\/code> literally cannot be exactly represented as floating-point values.If you were to try different values like <code class=\"calibre9\">0.1 + 0.3 == 0.4<\/code> it would happen to return <code class=\"calibre9\">true<\/code> because with <code class=\"calibre9\">double<\/code> values, some imprecise values happen to be exactly equal in their current representation even though they might not actually be equal mathematically. So, some numbers can be directly compared but some cannot. I deliberately picked <code class=\"calibre9\">0.1<\/code> and <code class=\"calibre9\">0.2<\/code> to compare to <code class=\"calibre9\">0.3<\/code> because they cannot be compared, as proven by the result.You could compare real numbers stored in the <code class=\"calibre9\">float<\/code> type, which is less accurate than the <code class=\"calibre9\">double<\/code> type, but the comparison would actual appear to be <code class=\"calibre9\">true<\/code> because of that lower accuracy!<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">float a = 0.1F;\nfloat b = 0.2F;\nif (a + b == 0.3F) \/\/ True because float is less \"accurate\" than double.\n...<\/code><\/pre>\n<\/div>\n<p class=\"rights\">As a rule of thumb, you should only use <code class=\"calibre9\">double<\/code> when accuracy, especially when comparing the equality of two numbers, is not important. An example of this might be when you're measuring a person's height; you will only compare values using greater than or less than, but never equals.The problem with the preceding code is illustrated by how the computer stores the number <code class=\"calibre9\">0.1<\/code>, or multiples of it. To represent <code class=\"calibre9\">0.1<\/code> in binary, the computer stores 1 in the 1\/16 column, 1 in the 1\/32 column, 1 in the 1\/256 column, 1 in the 1\/512 column, and so on.The number <code class=\"calibre9\">0.1<\/code> in decimal is <code class=\"calibre9\">0.00011001100110011<\/code>\u2026 in binary, repeating forever:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.7: Number 0.1 in decimal repeating forever in binary\" height=\"166\" src=\"\/images\/cs12\/000163.png\" width=\"1725\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.7: Number 0.1 in decimal repeating forever in binary<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Never compare <code class=\"calibre9\">double<\/code> values using <code class=\"calibre9\">==<\/code>. During the First Gulf War, an American Patriot missile battery used <code class=\"calibre9\">double<\/code> values in its calculations. The inaccuracy caused it to fail to track and intercept an incoming Iraqi Scud missile, and 28 soldiers were killed; you can read about this at <a href=\"https:\/\/www.ima.umn.edu\/~arnold\/disasters\/patriot.xhtml\">https:\/\/www.ima.umn.edu\/~arnold\/disasters\/patriot.xhtml<\/a>. The Patriot missile system has improved since then. <em class=\"calibre10\">\"Forty years after it was brought into service, the Patriot air-defense system is finally doing what it was designed for.\" \"No one was 100% sure that the Patriot was capable of destroying a Kh-47 hypersonic missile,\" said Col. Serhiy Yaremenko, commander of the 96th Anti-Aircraft Missile Brigade, which defends Kyiv. \"Ukrainians proved it.\":<\/em> <a href=\"https:\/\/archive.ph\/2023.06.11-132200\/https:\/\/www.wsj.com\/amp\/articles\/u-s-patriot-missile-is-an-unsung-hero-of-ukraine-war-db6053a0\">https:\/\/archive.ph\/2023.06.11-132200\/https:\/\/www.wsj.com\/amp\/articles\/u-s-patriot-missile-is-an-unsung-hero-of-ukraine-war-db6053a0<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Now let's see the same code using the <code class=\"calibre9\">decimal<\/code> number type:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Copy and paste the statements that you wrote before (which used the <code class=\"calibre9\">double<\/code> variables).<\/li>\n<li class=\"calibre3\">Modify the statements to use <code class=\"calibre9\">decimal<\/code> and rename the variables to <code class=\"calibre9\">c<\/code> and <code class=\"calibre9\">d<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Console.WriteLine(\"Using decimals:\");\ndecimal c = 0.1M; \/\/ M suffix means a decimal literal value\ndecimal d = 0.2M;\nif (c + d == 0.3M)\n{\n  Console.WriteLine($\"{c} + {d} equals {0.3M}\");\n}\nelse\n{\n  Console.WriteLine($\"{c} + {d} does NOT equal {0.3M}\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Using decimals:\n0.1 + 0.2 equals 0.3<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">decimal<\/code> type is accurate because it stores the number as a large integer and shifts the decimal point. For example, <code class=\"calibre9\">0.1<\/code> is stored as <code class=\"calibre9\">1<\/code>, with a note to shift the decimal point one place to the left. <code class=\"calibre9\">12.75<\/code> is stored as <code class=\"calibre9\">1275<\/code>, with a note to shift the decimal point two places to the left.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Use <code class=\"calibre9\">int<\/code> for whole numbers. Use <code class=\"calibre9\">double<\/code> for real numbers that will not be compared for equality to other values; it is okay to compare <code class=\"calibre9\">double<\/code> values being less than or greater than, and so on. Use <code class=\"calibre9\">decimal<\/code> for money, CAD drawings, general engineering, and wherever the accuracy of a real number is important.<\/p>\n<\/blockquote>\n<p class=\"rights\">The <code class=\"calibre9\">float<\/code> and <code class=\"calibre9\">double<\/code> types have some useful special values: <code class=\"calibre9\">NaN<\/code> represents not-a-number (for example, the result of dividing by zero), <code class=\"calibre9\">Epsilon<\/code> represents the smallest positive number that can be stored in a <code class=\"calibre9\">float<\/code> or <code class=\"calibre9\">double<\/code>, and <code class=\"calibre9\">PositiveInfinity<\/code> and <code class=\"calibre9\">NegativeInfinity<\/code> represent infinitely large positive and negative values. They also have methods for checking for these special values like <code class=\"calibre9\">IsInfinity<\/code> and <code class=\"calibre9\">IsNaN<\/code>.<\/p>\n<\/section>\n<section data-number=\"3.5.5.3\" id=\"calibre_link-1907\">\n<h4 data-number=\"3.5.5.3\" class=\"calibre15\">New number types and unsafe code<\/h4>\n<p class=\"rights\">The <code class=\"calibre9\">System.Half<\/code> type was introduced in .NET 5. Like <code class=\"calibre9\">float<\/code> and <code class=\"calibre9\">double<\/code> it can store real numbers. It normally uses two bytes of memory. The <code class=\"calibre9\">System.Int128<\/code> and <code class=\"calibre9\">System.UInt128<\/code> types were introduced in .NET 7. Like <code class=\"calibre9\">int<\/code> and <code class=\"calibre9\">uint<\/code>, they can store signed (positive and negative) and unsigned (only zero and positive) integer values. They normally use 16 bytes of memory.For these new number types, the <code class=\"calibre9\">sizeof<\/code> operator only works in an unsafe code block, and you must compile the project using an option to enable unsafe code. Let's explore how this works:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, at the bottom of the file, type statements to show the size of the <code class=\"calibre9\">Half<\/code> and <code class=\"calibre9\">Int128<\/code> number data types, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">unsafe\n{\n  Console.WriteLine($\"Half uses {sizeof(Half)} bytes and can store numbers in the range {Half.MinValue:N0} to {Half.MaxValue:N0}.\"); \n  Console.WriteLine($\"Int128 uses {sizeof(Int128)} bytes and can store numbers in the range {Int128.MinValue:N0} to {Int128.MaxValue:N0}.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Numbers.csproj<\/code>, add an element to enable unsafe code, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PropertyGroup&gt;\n  &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n  &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n  &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n  &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n  &lt;AllowUnsafeBlocks&gt;True&lt;\/AllowUnsafeBlocks&gt;\n&lt;\/PropertyGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">Numbers<\/code> project and note the sizes of the two new number types, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Half uses 2 bytes and can store numbers in the range -65,504 to 65,504.\nInt128 uses 16 bytes and can store numbers in the range -170,141,183,460,469,231,731,687,303,715,884,105,728 to 170,141,183,460,469,231,731,687,303,715,884,105,727.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: The <code class=\"calibre9\">sizeof<\/code> operator requires an unsafe code block except for the commonly used types like <code class=\"calibre9\">int<\/code> and <code class=\"calibre9\">byte<\/code>. You can learn more about sizeof at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/operators\/sizeof\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/operators\/sizeof<\/a>. Unsafe code cannot have its safety verified. You can learn more about unsafe code blocks at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/unsafe-code\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/unsafe-code<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"3.5.6\" id=\"calibre_link-114\">\n<h3 data-number=\"3.5.6\" class=\"calibre8\">Storing Booleans<\/h3>\n<p class=\"rights\">Booleans can only contain one of the two literal values <code class=\"calibre9\">true<\/code> or <code class=\"calibre9\">false<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">bool happy = true; \nbool sad = false;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">They are most used to branch and loop. You don't need to fully understand them yet, as they are covered more in <em class=\"calibre10\">Chapter 3<\/em>, <em class=\"calibre10\">Controlling Flow, Converting Types, and Handling Exceptions<\/em>.<\/p>\n<\/section>\n<section data-number=\"3.5.7\" id=\"calibre_link-115\">\n<h3 data-number=\"3.5.7\" class=\"calibre8\">Storing any type of object<\/h3>\n<p class=\"rights\">There is a special type named <code class=\"calibre9\">object<\/code> that can store any type of data, but its flexibility comes at the cost of messier code and possibly poor performance. Because of those two reasons, you should avoid it whenever possible. The following steps show you how to use object types if you need to use them because you must use a Microsoft or third-party library that uses them:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">Variables<\/code> to the <code class=\"calibre9\">Chapter02<\/code> solution.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then type statements to declare and use some variables using the <code class=\"calibre9\">object<\/code> type, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">object height = 1.88; \/\/ Storing a double in an object.\nobject name = \"Amir\"; \/\/ Storing a string in an object.\nConsole.WriteLine($\"{name} is {height} metres tall.\");\nint length1 = name.Length; \/\/ This gives a compile error!\nint length2 = ((string)name).Length; \/\/ Cast name to a string.\nConsole.WriteLine($\"{name} has {length2} characters.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Run the code and note that the fourth statement cannot compile because the data type of the <code class=\"calibre9\">name<\/code> variable is not known by the compiler, as shown in <em class=\"calibre10\">Figure 2.8<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.8: The object type does not have a Length property\" height=\"251\" src=\"\/images\/cs12\/000004.png\" width=\"845\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.8: The object type does not have a Length property<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Add double slashes to the beginning of the statement that cannot compile to comment out the statement, making it inactive.<\/li>\n<li class=\"calibre3\">Run the code again and note that the compiler can access the <code class=\"calibre9\">length<\/code> of a <code class=\"calibre9\">string<\/code> if the programmer explicitly tells the compiler that the <code class=\"calibre9\">object<\/code> variable contains a <code class=\"calibre9\">string<\/code> by prefixing <code class=\"calibre9\">name<\/code> variable with a cast expression like <code class=\"calibre9\">(string)name<\/code>. The results can then successfully be written to the console, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Amir is 1.88 meters tall.\nAmir has 4 characters.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You will learn about cast expressions in <em class=\"calibre10\">Chapter 3<\/em>, <em class=\"calibre10\">Controlling Flow, Converting Types, and Handling Exceptions<\/em>.The <code class=\"calibre9\">object<\/code> type has been available since the first version of C#, but C# 2 and later have a better alternative called <strong class=\"calibre2\">generics<\/strong>, which we will cover in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>. This will provide us with the flexibility we want but without the performance overhead.<\/p>\n<\/section>\n<section data-number=\"3.5.8\" id=\"calibre_link-116\">\n<h3 data-number=\"3.5.8\" class=\"calibre8\">Storing dynamic types<\/h3>\n<p class=\"rights\">There is another special type named <code class=\"calibre9\">dynamic<\/code> that can also store any type of data, but even more than <code class=\"calibre9\">object<\/code>, its flexibility comes at the cost of performance. The <code class=\"calibre9\">dynamic<\/code> keyword was introduced in C# 4. However, unlike <code class=\"calibre9\">object<\/code>, the value stored in the variable can have its members invoked without an explicit cast. Let's make use of a <code class=\"calibre9\">dynamic<\/code> type:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to declare a <code class=\"calibre9\">dynamic<\/code> variable. Assign a <code class=\"calibre9\">string<\/code> literal value, and then an integer value, and then an array of integer values. Finally, add a statement to output the length of the <code class=\"calibre9\">dynamic<\/code> variable, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dynamic something;\n\/\/ Storing an array of int values in a dynamic object.\n\/\/ An array of any type has a Length property.\nsomething = new[] { 3, 5, 7 };\n\/\/ Storing an int in a dynamic object.\n\/\/ int does not have a Length property.\nsomething = 12;\n\/\/ Storing a string in a dynamic object.\n\/\/ string has a Length property.\nsomething = \"Ahmed\";\n\/\/ This compiles but might throw an exception at run-time.\nConsole.WriteLine($\"The length of something is {something.Length}\");\n\/\/ Output the type of the something variable.\nConsole.WriteLine($\"something is a {something.GetType()}\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You will learn about arrays in <em class=\"calibre10\">Chapter 3<\/em>, <em class=\"calibre10\">Controlling Flow, Converting Types, and Handling Exceptions<\/em>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note it works because a <code class=\"calibre9\">string<\/code> value does have a <code class=\"calibre9\">Length<\/code> property, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">The length of something is 5\nsomething is a System.String<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Comment out the statement that assigns a <code class=\"calibre9\">string<\/code> value to the <code class=\"calibre9\">something<\/code> variable by prefixing the statement with two slashes <code class=\"calibre9\">\/\/<\/code>.<\/li>\n<li class=\"calibre3\">Run the code and note the runtime error because the last value assigned to <code class=\"calibre9\">something<\/code> is an <code class=\"calibre9\">int<\/code> that does not have a <code class=\"calibre9\">Length<\/code> property, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Unhandled exception. Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'int' does not contain a definition for 'Length'<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Comment out the statement that assigns an <code class=\"calibre9\">int<\/code> to the <code class=\"calibre9\">something<\/code> variable.<\/li>\n<li class=\"calibre3\">Run the code and note the output because an array of three <code class=\"calibre9\">int<\/code> values does have a <code class=\"calibre9\">Length<\/code> property, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">The length of something is 3\nsomething is a System.Int32[]<\/code><\/pre>\n<\/div>\n<p class=\"rights\">One limitation of <code class=\"calibre9\">dynamic<\/code> is that code editors cannot show IntelliSense to help you write the code. This is because the compiler cannot check what the type is during build time. Instead, the CLR checks for the member at runtime and throws an exception if it is missing.Exceptions are a way to indicate that something has gone wrong at runtime. You will learn more about them and how to handle them in <em class=\"calibre10\">Chapter 3<\/em>, <em class=\"calibre10\">Controlling Flow, Converting Types, and Handling Exceptions<\/em>.Dynamic types are most useful when interoperating with non-.NET systems. For example, you might need to work with a class library written in F#, Python, or some JavaScript. You might also need to interop with technologies like the <strong class=\"calibre2\">Component Object Model<\/strong> (<strong class=\"calibre2\">COM<\/strong>), for example, when automating Excel or Word.<\/p>\n<\/section>\n<section data-number=\"3.5.9\" id=\"calibre_link-117\">\n<h3 data-number=\"3.5.9\" class=\"calibre8\">Declaring local variables<\/h3>\n<p class=\"rights\">Local variables are declared inside methods, and they only exist during the execution of that method. Once the method returns, the memory allocated to any local variables is released.Strictly speaking, value types are released while reference types must wait for garbage collection. You will learn about the difference between value types and reference types and how to make sure that only one garbage collection is needed rather than two when releasing unmanaged resources in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>.<\/p>\n<section data-number=\"3.5.9.1\" id=\"calibre_link-1908\">\n<h4 data-number=\"3.5.9.1\" class=\"calibre15\">Specifying the type of a local variable<\/h4>\n<p class=\"rights\">Let's explore local variables declared with specific types and using type inference:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Type statements to declare and assign values to some local variables using specific types, as shown in the following code:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int population = 67_000_000; \/\/ 67 million in UK.\ndouble weight = 1.88; \/\/ in kilograms.\ndecimal price = 4.99M; \/\/ in pounds sterling.\nstring fruit = \"Apples\"; \/\/ string values use double-quotes.\nchar letter = 'Z'; \/\/ char values use single-quotes.\nbool happy = true; \/\/ Booleans can only be true or false.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Depending on your code editor and color scheme, it will show green squiggles under each of the variable names and lighten their text color to warn you that the variable is assigned but its value is never used.<\/p>\n<\/section>\n<section data-number=\"3.5.9.2\" id=\"calibre_link-1909\">\n<h4 data-number=\"3.5.9.2\" class=\"calibre15\">Inferring the type of a local variable<\/h4>\n<p class=\"rights\">You can use the <code class=\"calibre9\">var<\/code> keyword to declare local variables with C# 3 and later. The compiler will infer the type from the value that you assign after the assignment operator, <code class=\"calibre9\">=<\/code>. This happens at compile time so using <code class=\"calibre9\">var<\/code> has no effect on runtime performance.A literal number without a decimal point is inferred as an <code class=\"calibre9\">int<\/code> variable, that is, unless you add a suffix, as described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">L<\/code>: Compiler infers <code class=\"calibre9\">long<\/code><\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">UL<\/code>: Compiler infers <code class=\"calibre9\">ulong<\/code><\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">M<\/code>: Compiler infers <code class=\"calibre9\">decimal<\/code><\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">D<\/code>: Compiler infers <code class=\"calibre9\">double<\/code><\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">F<\/code>: Compiler infers <code class=\"calibre9\">float<\/code><\/li>\n<\/ul>\n<p class=\"rights\">A literal number with a decimal point is inferred as <code class=\"calibre9\">double<\/code> unless you add the <code class=\"calibre9\">M<\/code> suffix, in which case the compiler infers a <code class=\"calibre9\">decimal<\/code> variable, or the <code class=\"calibre9\">F<\/code> suffix, in which case it infers a <code class=\"calibre9\">float<\/code> variable.Double quotes indicate a <code class=\"calibre9\">string<\/code> variable, single quotes indicate a <code class=\"calibre9\">char<\/code> variable, and the <code class=\"calibre9\">true<\/code> and <code class=\"calibre9\">false<\/code> values infer a <code class=\"calibre9\">bool<\/code> type:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the previous statements to use <code class=\"calibre9\">var<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var population = 67_000_000; \/\/ 67 million in UK.\nvar weight = 1.88; \/\/ in kilograms.\nvar price = 4.99M; \/\/ in pounds sterling.\nvar fruit = \"Apples\"; \/\/ string values use double-quotes.\nvar letter = 'Z'; \/\/ char values use single-quotes.\nvar happy = true; \/\/ Booleans can only be true or false.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Hover your mouse over each of the <code class=\"calibre9\">var<\/code> keywords and note that your code editor shows a tooltip with information about the type that has been inferred.<\/li>\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.cs<\/code>, import the namespace for working with XML to enable us to declare some variables using types in that namespace, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Xml; \/\/ To use XmlDocument.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of <code class=\"calibre9\">Program.cs<\/code>, add statements to create some new objects, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Good use of var because it avoids the repeated type\n\/\/ as shown in the more verbose second statement.\nvar xml1 = new XmlDocument(); \/\/ Works with C# 3 and later.\nXmlDocument xml2 = new XmlDocument(); \/\/ Works with all C# versions.\n\/\/ Bad use of var because we cannot tell the type, so we\n\/\/ should use a specific type declaration as shown in\n\/\/ the second statement.\nvar file1 = File.CreateText(\"something1.txt\"); \nStreamWriter file2 = File.CreateText(\"something2.txt\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Although using <code class=\"calibre9\">var<\/code> is convenient, some developers avoid using it to make it easier for a code reader to understand the types in use. Personally, I use it only when the type is obvious. For example, in the preceding code statements, the first statement is just as clear as the second in stating what the types of the <code class=\"calibre9\">xml<\/code> variables are, but it is shorter. However, the third statement isn't clear in showing the type of the <code class=\"calibre9\">file<\/code> variable, so the fourth is better because it shows that the type is <code class=\"calibre9\">StreamWriter<\/code>. If in doubt, spell it out!<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.5.9.3\" id=\"calibre_link-1910\">\n<h4 data-number=\"3.5.9.3\" class=\"calibre15\">Using target-typed new to instantiate objects<\/h4>\n<p class=\"rights\">With C# 9, Microsoft introduced another syntax for instantiating objects known as <strong class=\"calibre2\">target-typed new<\/strong>. When instantiating an object, you can specify the type first and then use <code class=\"calibre9\">new<\/code> without repeating the type, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">XmlDocument xml3 = new(); \/\/ Target-typed new in C# 9 or later.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you have a type with a field or property that needs to be set, then the type can be inferred, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ In Program.cs.\nPerson kim = new();\nkim.BirthDate = new(1967, 12, 26); \/\/ i.e. new DateTime(1967, 12, 26)\n\/\/ In a separate Person.cs file or at the bottom of Program.cs.\nclass Person\n{\n  public DateTime BirthDate;\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This way of instantiating objects is especially useful with arrays and collections because they have multiple objects often of the same type, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">List&lt;Person&gt; people = new() \/\/ Instead of: new List&lt;Person&gt;()\n{\n  new() { FirstName = \"Alice\" }, \/\/ Instead of: new Person() { ... }\n  new() { FirstName = \"Bob\" },\n  new() { FirstName = \"Charlie\" }\n};<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You will learn about arrays in <em class=\"calibre10\">Chapter 3<\/em>, <em class=\"calibre10\">Controlling Flow, Converting Types, and Handling Exceptions<\/em>, and collections in <em class=\"calibre10\">Chapter 8<\/em>, <em class=\"calibre10\">Working with Common .NET Types<\/em>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Use target-typed new to instantiate objects because it requires fewer characters, when reading a statement from left to right, as in English, you immediately know the type of the variable, and it is not limited to local variables like <code class=\"calibre9\">var<\/code> is. IMHO, the only reason not to use target-typed new is if you must use a pre-version 9 C# compiler. I do acknowledge that my opinion is not accepted by the whole C# community. I have used target-typed new throughout the remainder of this book. Please let me know if you spot any cases that I missed!<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"3.5.10\" id=\"calibre_link-118\">\n<h3 data-number=\"3.5.10\" class=\"calibre8\">Getting and setting the default values for types<\/h3>\n<p class=\"rights\">Most of the primitive types except <code class=\"calibre9\">string<\/code> are <strong class=\"calibre2\">value types<\/strong>, which means that they must have a value. You can determine the default value of a type by using the <code class=\"calibre9\">default()<\/code> operator and passing the type as a parameter. You can assign the default value of a type by using the <code class=\"calibre9\">default<\/code> keyword.The <code class=\"calibre9\">string<\/code> type is a <strong class=\"calibre2\">reference type<\/strong>. This means that <code class=\"calibre9\">string<\/code> variables contain the memory address of a value, not the value itself. A reference type variable can have a <code class=\"calibre9\">null<\/code> value, which is a literal that indicates that the variable does not reference anything (yet). <code class=\"calibre9\">null<\/code> is the default for all reference types.You'll learn more about value types and reference types in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>.Let's explore default values:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to show the default values of an <code class=\"calibre9\">int<\/code>, a <code class=\"calibre9\">bool<\/code>, a <code class=\"calibre9\">DateTime<\/code>, and a <code class=\"calibre9\">string<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Console.WriteLine($\"default(int) = {default(int)}\"); \nConsole.WriteLine($\"default(bool) = {default(bool)}\"); \nConsole.WriteLine($\"default(DateTime) = {default(DateTime)}\"); \nConsole.WriteLine($\"default(string) = {default(string)}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result. Note that your output for the date and time might be formatted differently if you are not running it in the UK because date and time values are formatted using the current culture of your computer, and that <code class=\"calibre9\">null<\/code> values output as an empty <code class=\"calibre9\">string<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">default(int) = 0 \ndefault(bool) = False\ndefault(DateTime) = 01\/01\/0001 00:00:00 \ndefault(string) =<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to declare a number, assign a value, and then reset it to its default value, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int number = 13;\nConsole.WriteLine($\"number set to: {number}\");\nnumber = default;\nConsole.WriteLine($\"number reset to its default: {number}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">number set to: 13\nnumber reset to its default: 0<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"3.6\" id=\"calibre_link-119\">\n<h2 data-number=\"3.6\" class=\"calibre5\">Exploring more about console apps<\/h2>\n<p class=\"rights\">We have already created and used basic console apps, but we're now at a stage where we should delve into them more deeply.Console apps are text-based and are run at the command prompt. They typically perform simple tasks that need to be scripted, such as compiling a file or encrypting a section of a configuration file.Equally, they can also have arguments passed to them to control their behavior.An example of this would be to create a new console app using the F# language with a specified name instead of using the name of the current folder, as shown in the following command:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new console -lang \"F#\" --name \"ExploringConsole\"<\/code><\/pre>\n<\/div>\n<section data-number=\"3.6.1\" id=\"calibre_link-120\">\n<h3 data-number=\"3.6.1\" class=\"calibre8\">Displaying output to the user<\/h3>\n<p class=\"rights\">The two most common tasks that a console app performs are writing and reading data. We have already used the <code class=\"calibre9\">WriteLine<\/code> method to output, but if we didn't want a carriage return at the end of a line, for example, if we later wanted to continue to write more text at the end of that line, we could have used the <code class=\"calibre9\">Write<\/code> method.If you want to write three letters to the console without carriage returns after them, then call the <code class=\"calibre9\">Write<\/code> method, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Write(\"A\");\nWrite(\"B\");\nWrite(\"C\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This would write the three characters on a single line and leave the cursor at the end of the line, as shown in the following output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ABC<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you want to write three letters to the console with carriage returns after them, then call the <code class=\"calibre9\">WriteLine<\/code> method, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(\"A\");\nWriteLine(\"B\");\nWriteLine(\"C\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This would write three lines and leave the cursor on the fourth line:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">A\nB\nC<\/code><\/pre>\n<\/div>\n<section data-number=\"3.6.1.1\" id=\"calibre_link-1911\">\n<h4 data-number=\"3.6.1.1\" class=\"calibre15\">Formatting using numbered positional arguments<\/h4>\n<p class=\"rights\">One way of generating formatted strings is to use numbered positional arguments.This feature is supported by methods like <code class=\"calibre9\">Write<\/code> and <code class=\"calibre9\">WriteLine<\/code>. For methods that do not support the feature, the <code class=\"calibre9\">string<\/code> parameter can be formatted using the <code class=\"calibre9\">Format<\/code> method of <code class=\"calibre9\">string<\/code>.Let's begin formatting:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">Formatting<\/code> to the <code class=\"calibre9\">Chapter02<\/code> solution.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then type statements to declare some number variables and write them to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int numberOfApples = 12; \ndecimal pricePerApple = 0.35M;\nConsole.WriteLine(\n  format: \"{0} apples cost {1:C}\", \n  arg0: numberOfApples,\n  arg1: pricePerApple * numberOfApples);\nstring formatted = string.Format(\n  format: \"{0} apples cost {1:C}\",\n  arg0: numberOfApples,\n  arg1: pricePerApple * numberOfApples);\n\/\/WriteToFile(formatted); \/\/ Writes the string into a file.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">WriteToFile<\/code> method is a nonexistent method used to illustrate the idea.<\/p>\n<\/blockquote>\n<p class=\"rights\">The <code class=\"calibre9\">Write<\/code>, <code class=\"calibre9\">WriteLine<\/code>, and <code class=\"calibre9\">Format<\/code> methods can have up to three numbered arguments, named <code class=\"calibre9\">arg0<\/code>, <code class=\"calibre9\">arg1<\/code>, and <code class=\"calibre9\">arg2<\/code>. If you need to pass more than three values, then you cannot name them.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, type statements to write three and then five arguments to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Three parameter values can use named arguments.\nConsole.WriteLine(\"{0} {1} lived in {2}.\", \n  arg0: \"Roger\", arg1: \"Cevung\", arg2: \"Stockholm\");\n\/\/ Four or more parameter values cannot use named arguments.\nConsole.WriteLine(\n  \"{0} {1} lived in {2} and worked in the {3} team at {4}.\", \n  \"Roger\", \"Cevung\", \"Stockholm\", \"Education\", \"Optimizely\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Once you become more comfortable with formatting strings, you should stop naming the parameters, for example, stop using <code class=\"calibre9\">format:<\/code>, <code class=\"calibre9\">arg0:<\/code>, and <code class=\"calibre9\">arg1:<\/code>. The preceding code uses a non-canonical style to show where the <code class=\"calibre9\">0<\/code> and <code class=\"calibre9\">1<\/code> came from while you are learning.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.6.1.2\" id=\"calibre_link-1912\">\n<h4 data-number=\"3.6.1.2\" class=\"calibre15\">JetBrains Rider and its warnings about boxing<\/h4>\n<p class=\"rights\">If you use JetBrains Rider and you have installed the Unity Support plugin, then it will complain a lot about boxing. A common scenario when boxing happens is when value types like <code class=\"calibre9\">int<\/code> and <code class=\"calibre9\">DateTime<\/code> are passed as positional arguments to <code class=\"calibre9\">string<\/code> formats. This is a problem for Unity projects because they use a different memory garbage collector to the normal .NET runtime. For non-Unity projects, like all the projects in this book, you can ignore these boxing warnings because they are not relevant. You can read more about this Unity-specific issue at the following link: <a href=\"https:\/\/docs.unity3d.com\/Manual\/performance-garbage-collection-best-practices.xhtml#boxing\">https:\/\/docs.unity3d.com\/Manual\/performance-garbage-collection-best-practices.xhtml#boxing<\/a>.<\/p>\n<\/section>\n<section data-number=\"3.6.1.3\" id=\"calibre_link-1913\">\n<h4 data-number=\"3.6.1.3\" class=\"calibre15\">Formatting using interpolated strings<\/h4>\n<p class=\"rights\">C# 6 and later have a handy feature named <strong class=\"calibre2\">interpolated strings<\/strong>. A <code class=\"calibre9\">string<\/code> prefixed with <code class=\"calibre9\">$<\/code> can use curly braces around the name of a variable or expression to output the current value of that variable or expression at that position in the <code class=\"calibre9\">string<\/code>, as the following shows:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Enter a statement at the bottom of the <code class=\"calibre9\">Program.cs<\/code> file, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ The following statement must be all on one line when using C# 10\n\/\/ or earlier. If using C# 11 or later, we can include a line break\n\/\/ in the middle of an expression but not in the string text.\nConsole.WriteLine($\"{numberOfApples} apples cost {pricePerApple \n  * numberOfApples:C}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">12 apples cost \u00a34.20<\/code><\/pre>\n<\/div>\n<p class=\"rights\">For short, formatted <code class=\"calibre9\">string<\/code> values, an interpolated <code class=\"calibre9\">string<\/code> can be easier for people to read. But for code examples in a book, where statements need to wrap over multiple lines, this can be tricky. For many of the code examples in this book, I will use numbered positional arguments. Another reason to avoid interpolated strings is that they can't be read from resource files to be localized.The next code example is not meant to be entered in your project.Before C# 10, <code class=\"calibre9\">string<\/code> constants could only be combined by using concatenation with the <code class=\"calibre9\">+<\/code> operator, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private const string firstname = \"Omar\";\nprivate const string lastname = \"Rudberg\";\nprivate const string fullname = firstname + \" \" + lastname;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">With C# 10, interpolated strings (prefixed with <code class=\"calibre9\">$<\/code>) can now be used, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private const string fullname = $\"{firstname} {lastname}\";<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This only works for combining <code class=\"calibre9\">string<\/code> constant values. It cannot work with other types like numbers, which would require runtime data type conversions. You cannot enter <code class=\"calibre9\">private const<\/code> declarations in a top-level program like <code class=\"calibre9\">Program.cs<\/code>. You will see how to use them in <em class=\"calibre10\">Chapter 5<\/em>, <em class=\"calibre10\">Building Your Own Types with Object-Oriented Programming<\/em>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If you are writing code that will be part of a Unity project then interpolated string formats is an easy way to avoid boxing.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.6.1.4\" id=\"calibre_link-1914\">\n<h4 data-number=\"3.6.1.4\" class=\"calibre15\">Understanding format strings<\/h4>\n<p class=\"rights\">A variable or expression can be formatted using a format string after a comma or colon.An <code class=\"calibre9\">N0<\/code> format string means a number with thousand separators and no decimal places, while a <code class=\"calibre9\">C<\/code> format string means currency. The currency format will be determined by the current thread.For instance, if you run code that uses the number or currency format on a PC in the UK, you'll get pounds sterling with commas as the thousand separators, but if you run it on a PC in Germany, you will get euros with dots as the thousand separators.The full syntax of a format item is:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{ index [, alignment ] [ : formatString ] }<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Each format item can have an alignment, which is useful when outputting tables of values, some of which might need to be left- or right-aligned within a width of characters. Alignment values are integers. Positive integers mean right-aligned and negative integers mean left-aligned.For example, to output a table of fruit and how many of each there are, we might want to left-align the names within a column of 10 characters and right-align the counts formatted as numbers with zero decimal places within a column of six characters:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of <code class=\"calibre9\">Program.cs<\/code>, enter the following statements:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string applesText = \"Apples\"; \nint applesCount = 1234;\nstring bananasText = \"Bananas\"; \nint bananasCount = 56789;\nConsole.WriteLine();\nConsole.WriteLine(format: \"{0,-10} {1,6}\",\n  arg0: \"Name\", arg1: \"Count\");\nConsole.WriteLine(format: \"{0,-10} {1,6:N0}\",\n  arg0: applesText, arg1: applesCount);\nConsole.WriteLine(format: \"{0,-10} {1,6:N0}\",\n  arg0: bananasText, arg1: bananasCount);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the effect of the alignment and number format, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Name          Count\nApples        1,234\nBananas      56,789<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"3.6.1.5\" id=\"calibre_link-1915\">\n<h4 data-number=\"3.6.1.5\" class=\"calibre15\">Custom number formatting<\/h4>\n<p class=\"rights\">You can take complete control of number formatting using custom format codes, as shown in <em class=\"calibre10\">Table 2.21<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Format code<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">0<\/code><\/td>\n<td class=\"calibre21\">Zero placeholder. Replaces the zero with the corresponding digit if present; otherwise, it uses zero. For example, <code class=\"calibre9\">0000.00<\/code> formatting the value <code class=\"calibre9\">123.4<\/code> would give <code class=\"calibre9\">0123.40<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">#<\/code><\/td>\n<td class=\"calibre21\">Digit placeholder. Replaces the hash with the corresponding digit if present; otherwise, it uses nothing. For example, <code class=\"calibre9\">####.##<\/code> formatting the value <code class=\"calibre9\">123.4<\/code> would give <code class=\"calibre9\">123.4<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">.<\/code><\/td>\n<td class=\"calibre21\">Decimal point. Sets the location of the decimal point in the number. Respects culture formatting, so it is a <code class=\"calibre9\">.<\/code> (dot) in US English but a <code class=\"calibre9\">,<\/code> (comma) in French.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">,<\/code><\/td>\n<td class=\"calibre21\">Group separator. Inserts a localized group separator between each group. For example, <code class=\"calibre9\">0,000<\/code> formatting the value <code class=\"calibre9\">1234567<\/code> would give <code class=\"calibre9\">1,234,567<\/code> . Also used to scale a number by dividing by multiples of 1000 for each comma. For example, <code class=\"calibre9\">0.00,,<\/code> formatting the value <code class=\"calibre9\">1234567<\/code> would give <code class=\"calibre9\">1.23<\/code> because the two commas mean divide by 1,000 twice.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">%<\/code><\/td>\n<td class=\"calibre21\">Percentage placeholder. Multiples the value by 100 and adds a percentage character.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\\<\/code><\/td>\n<td class=\"calibre21\">Escape character. Makes the next character a literal instead of a format code. For example, <code class=\"calibre9\">\\##,####\\#<\/code> formatting the value <code class=\"calibre9\">1234<\/code> would give <code class=\"calibre9\">#1,234#<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">;<\/code><\/td>\n<td class=\"calibre21\">Section separator. Defines different format strings for positive, negative, and zero numbers. For example, <code class=\"calibre9\">[0];(0);Zero<\/code> formatting: <code class=\"calibre9\">13<\/code> would give <code class=\"calibre9\">[13]<\/code> , <code class=\"calibre9\">-13<\/code> would give <code class=\"calibre9\">(13)<\/code> , and <code class=\"calibre9\">0<\/code> would give <code class=\"calibre9\">Zero<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Others<\/td>\n<td class=\"calibre21\">All other characters are shown in the output as is.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.21: Custom numeric format codes<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: A full list of custom number format codes can be found at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/base-types\/custom-numeric-format-strings\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/base-types\/custom-numeric-format-strings<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">You can apply standard number formatting using simpler format codes, like <code class=\"calibre9\">C<\/code> and <code class=\"calibre9\">N<\/code>. They support a precision number to indicate how many digits of precision you want. The default is two. The most common, as shown in <em class=\"calibre10\">Table 2.22<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Format code<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">C<\/code> or <code class=\"calibre9\">c<\/code><\/td>\n<td class=\"calibre21\">Currency. For example, in US culture, <code class=\"calibre9\">C<\/code> formatting the value <code class=\"calibre9\">123.4<\/code> gives <code class=\"calibre9\">$123.40<\/code> , and <code class=\"calibre9\">C0<\/code> formatting the value <code class=\"calibre9\">123.4<\/code> gives <code class=\"calibre9\">$123<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">N<\/code> or <code class=\"calibre9\">n<\/code><\/td>\n<td class=\"calibre21\">Number. Integer digits with an optional negative sign and grouping characters.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">D<\/code> or <code class=\"calibre9\">d<\/code><\/td>\n<td class=\"calibre21\">Decimal. Integer digits with an optional negative sign but no grouping characters.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">B<\/code> or <code class=\"calibre9\">b<\/code><\/td>\n<td class=\"calibre21\">Binary. For example, <code class=\"calibre9\">B<\/code> formatting the value <code class=\"calibre9\">13<\/code> gives <code class=\"calibre9\">1101<\/code> and <code class=\"calibre9\">B8<\/code> formatting the value <code class=\"calibre9\">13<\/code> gives <code class=\"calibre9\">00001101<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">X<\/code> or <code class=\"calibre9\">x<\/code><\/td>\n<td class=\"calibre21\">Hexadecimal. For example, <code class=\"calibre9\">X<\/code> formatting the value <code class=\"calibre9\">255<\/code> gives <code class=\"calibre9\">FF<\/code> and <code class=\"calibre9\">X4<\/code> formatting the value <code class=\"calibre9\">255<\/code> gives <code class=\"calibre9\">00FF<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">E<\/code> or <code class=\"calibre9\">e<\/code><\/td>\n<td class=\"calibre21\">Exponential notation. For example, <code class=\"calibre9\">E<\/code> formatting the value <code class=\"calibre9\">1234.567<\/code> would give <code class=\"calibre9\">1.234567000E+003<\/code> and <code class=\"calibre9\">E2<\/code> formatting the value <code class=\"calibre9\">1234.567<\/code> would give <code class=\"calibre9\">1.23E+003<\/code> .<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.22: Standard numeric format codes<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: A full list of standard number format codes can be found at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/base-types\/standard-numeric-format-strings\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/base-types\/standard-numeric-format-strings<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"3.6.2\" id=\"calibre_link-121\">\n<h3 data-number=\"3.6.2\" class=\"calibre8\">Getting text input from the user<\/h3>\n<p class=\"rights\">We can get text input from the user using the <code class=\"calibre9\">ReadLine<\/code> method. This method waits for the user to type some text. Then, as soon as the user presses <span>Enter<\/span>, whatever the user has typed is returned as a <code class=\"calibre9\">string<\/code> value.Let's get input from the user:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type statements to ask the user for their name and age and then output what they entered, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Console.Write(\"Type your first name and press ENTER: \"); \nstring firstName = Console.ReadLine();\nConsole.Write(\"Type your age and press ENTER: \"); \nstring age = Console.ReadLine();\nConsole.WriteLine($\"Hello {firstName}, you look good for {age}.\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">By default, with .NET 6 and later, nullability checks are enabled, so the C# compiler gives two warnings because the <code class=\"calibre9\">ReadLine<\/code> method could return a <code class=\"calibre9\">null<\/code> value instead of a <code class=\"calibre9\">string<\/code> value. But there is no scenario where this method would actually return <code class=\"calibre9\">null<\/code>, so instead we will see how to switch off these specific warnings in this scenario.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">For the <code class=\"calibre9\">firstName<\/code> variable, append a <code class=\"calibre9\">?<\/code> after <code class=\"calibre9\">string<\/code>, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string? firstName = Console.ReadLine();<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">This tells the compiler that we are expecting a possible <code class=\"calibre9\">null<\/code> value, so it does not need to warn us. If the variable is <code class=\"calibre9\">null<\/code> then when it is later output with <code class=\"calibre9\">WriteLine<\/code>, it will just be blank, so that works fine in this case. If we were going to access any of the members of the <code class=\"calibre9\">firstName<\/code> variable, then we would need to handle the case where it is <code class=\"calibre9\">null<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">For the <code class=\"calibre9\">age<\/code> variable, append a <code class=\"calibre9\">!<\/code> before the semi-colon at the end of the statement, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string age = Console.ReadLine()!;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">This is called the <strong class=\"calibre2\">null-forgiving operator<\/strong> because it tells the compiler that, in this case, <code class=\"calibre9\">ReadLine<\/code> will not return <code class=\"calibre9\">null<\/code>, so it can stop showing the warning. It is now our responsibility to ensure this is the case. Luckily, the <code class=\"calibre9\">Console<\/code> type's implementation of <code class=\"calibre9\">ReadLine<\/code> always returns a <code class=\"calibre9\">string<\/code> even if it is just an empty <code class=\"calibre9\">string<\/code> value.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, and then enter a name and age, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Type your name and press ENTER: Gary \nType your age and press ENTER: 34 \nHello Gary, you look good for 34.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You have now seen two common ways to handle nullability warnings from the compiler. We will cover nullability and how to handle it in more detail in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.6.3\" id=\"calibre_link-122\">\n<h3 data-number=\"3.6.3\" class=\"calibre8\">Simplifying the usage of the console<\/h3>\n<p class=\"rights\">In C# 6 and later, the <code class=\"calibre9\">using<\/code> statement can be used not only to import a namespace but also to further simplify our code by importing a static class. Then, we won't need to enter the <code class=\"calibre9\">Console<\/code> type name throughout our code.<\/p>\n<section data-number=\"3.6.3.1\" id=\"calibre_link-1916\">\n<h4 data-number=\"3.6.3.1\" class=\"calibre15\">Importing a static type for a single file<\/h4>\n<p class=\"rights\">You can use your code editor's <strong class=\"calibre2\">Find and Replace<\/strong> feature to remove the times we have previously written <code class=\"calibre9\">Console<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of the <code class=\"calibre9\">Program.cs<\/code> file, add a statement to <strong class=\"calibre2\">statically import<\/strong> the <code class=\"calibre9\">System.Console<\/code> class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using static System.Console;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Select the first <code class=\"calibre9\">Console.<\/code> in your code, ensuring that you select the dot after the word <code class=\"calibre9\">Console<\/code> too.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In Visual Studio 2022, navigate to <strong class=\"calibre2\">Edit<\/strong> | <strong class=\"calibre2\">Find and Replace<\/strong> | <strong class=\"calibre2\">Quick Replace<\/strong>; in Visual Studio Code, navigate to <strong class=\"calibre2\">Edit<\/strong> | <strong class=\"calibre2\">Replace<\/strong>; or in JetBrains Rider, navigate to <strong class=\"calibre2\">Edit<\/strong> | <strong class=\"calibre2\">Find<\/strong> | <strong class=\"calibre2\">Replace<\/strong>, and note that an overlay dialog appears ready for you to enter what you would like to replace <code class=\"calibre9\">Console.<\/code> with, as shown in <em class=\"calibre10\">Figure 2.9<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.9: Using the Replace feature in Visual Studio to simplify your code\" height=\"261\" src=\"\/images\/cs12\/000017.png\" width=\"849\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.9: Using the Replace feature in Visual Studio to simplify your code<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Leave the replace box empty, click on the <strong class=\"calibre2\">Replace all<\/strong> button (the second of the two buttons to the right of the replace box), and then close the replace box by clicking on the cross in its top-right corner.<\/li>\n<li class=\"calibre3\">Run the console app and note the behavior is the same as before.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"3.6.3.2\" id=\"calibre_link-1917\">\n<h4 data-number=\"3.6.3.2\" class=\"calibre15\">Importing a static type for all code files in a project<\/h4>\n<p class=\"rights\">Instead of statically importing the <code class=\"calibre9\">Console<\/code> class just for one code file, it would probably be better to import it globally for all code files in the project:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Delete the statement to statically import <code class=\"calibre9\">System.Console<\/code>.<\/li>\n<li class=\"calibre3\">Open <code class=\"calibre9\">Formatting.csproj<\/code>, and after the <code class=\"calibre9\">&lt;PropertyGroup&gt;<\/code> section, add a new <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> section to globally and statically import <code class=\"calibre9\">System.Console<\/code> using the implicit <code class=\"calibre9\">using<\/code> .NET SDK feature, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app and note the behavior is the same as before.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: In the future, for all console app projects you create for this book, add the section above to simplify the code you need to write in all C# files to work with the <code class=\"calibre9\">Console<\/code> class.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"3.6.4\" id=\"calibre_link-123\">\n<h3 data-number=\"3.6.4\" class=\"calibre8\">Getting key input from the user<\/h3>\n<p class=\"rights\">We can get key input from the user using the <code class=\"calibre9\">ReadKey<\/code> method. This method waits for the user to press a key or key combination, which is then returned as a <code class=\"calibre9\">ConsoleKeyInfo<\/code> value.Let's explore reading key presses:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type statements to ask the user to press any key combination and then output information about it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Write(\"Press any key combination: \"); \nConsoleKeyInfo key = ReadKey(); \nWriteLine();\nWriteLine(\"Key: {0}, Char: {1}, Modifiers: {2}\",\n  arg0: key.Key, arg1: key.KeyChar, arg2: key.Modifiers);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, press the <span>K<\/span> key, and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Press any key combination: k \nKey: K, Char: k, Modifiers: 0<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, hold down <span>Shift<\/span> and press the <span>K<\/span> key, and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Press any key combination: K  \nKey: K, Char: K, Modifiers: Shift<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, press the <span>F12<\/span> key, and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Press any key combination: \nKey: F12, Char: , Modifiers: 0<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> When running a console app in a terminal within Visual Studio Code, some keyboard combinations will be captured by the code editor before they can be processed by your console app. For example, <span>Ctrl<\/span> + <span>Shift<\/span> + <span>X<\/span> in Visual Studio Code activates the <strong class=\"calibre2\">Extensions<\/strong> view in the sidebar. To fully test this console app, open a command prompt or terminal in the project folder and run the console app from there.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.6.5\" id=\"calibre_link-124\">\n<h3 data-number=\"3.6.5\" class=\"calibre8\">Passing arguments to a console app<\/h3>\n<p class=\"rights\">When you run a console app, you often want to change its behavior by passing arguments. For example, with the <code class=\"calibre9\">dotnet<\/code> command-line tool, you can pass the name of a new project template, as shown in the following commands:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new console\ndotnet new mvc<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You might have been wondering how to get any arguments that might be passed to a console app.In every version of .NET prior to version 6, the console app project template made it obvious, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System;\nnamespace Arguments\n{\n  class Program\n  {\n    static void Main(string[] args)\n    {\n      Console.WriteLine(\"Hello World!\");\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">string[] args<\/code> arguments are declared and passed in the <code class=\"calibre9\">Main<\/code> method of the <code class=\"calibre9\">Program<\/code> class. They're an array used to pass arguments into a console app. But in top-level programs, as used by the console app project template in .NET 6 and later, the <code class=\"calibre9\">Program<\/code> class and its <code class=\"calibre9\">Main<\/code> method are hidden, along with the declaration of the <code class=\"calibre9\">args<\/code> array. The trick is that you must know it still exists.Command-line arguments are separated by spaces. Other characters like hyphens and colons are treated as part of an argument value.To include spaces in an argument value, enclose the argument value in single or double quotes.Imagine that we want to be able to enter the names of some colors for the foreground and background and the dimensions of the terminal window at the command line. We would be able to read the colors and numbers by reading them from the <code class=\"calibre9\">args<\/code> array, which is always passed into the <code class=\"calibre9\">Main<\/code> method, aka the entry point of a console app:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">Arguments<\/code> to the <code class=\"calibre9\">Chapter02<\/code> solution.<\/li>\n<li class=\"calibre3\">Open <code class=\"calibre9\">Arguments.csproj<\/code>, and after the <code class=\"calibre9\">&lt;PropertyGroup&gt;<\/code> section, add a new <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> section to statically import <code class=\"calibre9\">System.Console<\/code> for all C# files using the implicit usings .NET SDK feature, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Remember to use the implicit usings .NET SDK feature to statically import the <code class=\"calibre9\">System.Console<\/code> type in all future console app projects to simplify your code, as these instructions will not be repeated every time.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, and then add a statement to output the number of arguments passed to the application, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine($\"There are {args.Length} arguments.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">There are 0 arguments.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you are using Visual Studio 2022 for Windows:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Project<\/strong> | <strong class=\"calibre2\">Arguments<\/strong> <strong class=\"calibre2\">Properties<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Select the <strong class=\"calibre2\">Debug<\/strong> tab, click <strong class=\"calibre2\">Open debug launch profiles UI<\/strong>, and in the <strong class=\"calibre2\">Command line arguments<\/strong> box, enter the following arguments: <code class=\"calibre9\">firstarg second-arg third:arg \"fourth arg\"<\/code>, as shown in <em class=\"calibre10\">Figure 2.10<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.10: Entering command-line arguments in the Visual Studio project properties on Windows\" height=\"701\" src=\"\/images\/cs12\/000113.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.10: Entering command-line arguments in the Visual Studio project properties on Windows<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Close the <strong class=\"calibre2\">Launch Profiles<\/strong> window.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, in the <code class=\"calibre9\">Properties<\/code> folder, open the <code class=\"calibre9\">launchSettings.json<\/code> file and note it defines the command-line arguments when you run the project, as shown highlighted in the following configuration:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"profiles\": {\n    \"Arguments\": {\n      \"commandName\": \"Project\",\n      \"commandLineArgs\": \"firstarg second-arg third:arg \\\"fourth arg\\\"\"\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">launchSettings.json<\/code> file can also be used by JetBrains Rider. The equivalent for Visual Studio Code is the <code class=\"calibre9\">.vscode\/launch.json<\/code> file.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app project.<\/li>\n<\/ol>\n<p class=\"rights\">If you are using JetBrains Rider:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Right-click the <strong class=\"calibre2\">Arguments<\/strong> project.<\/li>\n<li class=\"calibre3\">In the popup menu, select <strong class=\"calibre2\">More Run\/Debug<\/strong> | <strong class=\"calibre2\">Modify Run Configuration\u2026<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <strong class=\"calibre2\">Edit Run Configuration: 'Arguments'<\/strong> dialog box, in the <strong class=\"calibre2\">Program arguments<\/strong> box, enter <code class=\"calibre9\">firstarg second-arg third:arg \"fourth arg\"<\/code>, as shown in <em class=\"calibre10\">Figure 2.11<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.11: Entering command-line arguments in the JetBrains Rider run configuration\" height=\"1043\" src=\"\/images\/cs12\/000130.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.11: Entering command-line arguments in the JetBrains Rider run configuration<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<li class=\"calibre3\">Run the console app.<\/li>\n<\/ol>\n<p class=\"rights\">If you are using Visual Studio Code:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">Terminal<\/strong>, enter some arguments after the <code class=\"calibre9\">dotnet run<\/code> command, as shown in the following command:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet run firstarg second-arg third:arg \"fourth arg\"<\/code><\/pre>\n<\/div>\n<p class=\"rights\">For all code editors:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the result indicates four arguments, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">There are 4 arguments.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, to enumerate or iterate (that is, loop through) the values of those four arguments, add the following statements after outputting the length of the array:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">foreach (string arg in args)\n{\n  WriteLine(arg);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code again and note the result shows the details of the four arguments, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">There are 4 arguments. \nfirstarg\nsecond-arg \nthird:arg \nfourth arg<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"3.6.6\" id=\"calibre_link-125\">\n<h3 data-number=\"3.6.6\" class=\"calibre8\">Setting options with arguments<\/h3>\n<p class=\"rights\">We will now use these arguments to allow the user to pick a color for the background, foreground, and cursor size of the output window. The cursor size can be an integer value from 1, meaning a line at the bottom of the cursor cell, up to 100, meaning a percentage of the height of the cursor cell.We have statically imported the <code class=\"calibre9\">System.Console<\/code> class. It has properties like <code class=\"calibre9\">ForegroundColor<\/code>, <code class=\"calibre9\">BackgroundColor<\/code>, and <code class=\"calibre9\">CursorSize<\/code> that we can now set just by using their names without needing to prefix them with <code class=\"calibre9\">Console<\/code>. The <code class=\"calibre9\">System<\/code> namespace is already imported so that the compiler knows about the <code class=\"calibre9\">ConsoleColor<\/code> and <code class=\"calibre9\">Enum<\/code> types:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to warn the user if they do not enter three arguments, and then parse those arguments and use them to set the color and dimensions of the console window, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (args.Length &lt; 3)\n{\n  WriteLine(\"You must specify two colors and cursor size, e.g.\");\n  WriteLine(\"dotnet run red yellow 50\");\n  return; \/\/ Stop running.\n}\nForegroundColor = (ConsoleColor)Enum.Parse(\n  enumType: typeof(ConsoleColor),\n  value: args[0], ignoreCase: true);\nBackgroundColor = (ConsoleColor)Enum.Parse(\n  enumType: typeof(ConsoleColor),\n  value: args[1], ignoreCase: true);\nCursorSize = int.Parse(args[2]);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note the compiler warning that setting the <code class=\"calibre9\">CursorSize<\/code> is only supported on Windows. For now, do not worry about most of this code like <code class=\"calibre9\">(ConsoleColor)<\/code>, <code class=\"calibre9\">Enum.Parse<\/code>, or <code class=\"calibre9\">typeof<\/code>, as it will all be explained in the next few chapters.<\/p>\n<\/blockquote>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">\n<p class=\"rights\">If you are using Visual Studio 2022, change the arguments to <code class=\"calibre9\">red yellow 50<\/code>. Run the console app and note the cursor is half the size and the colors have changed in the window, as shown in <em class=\"calibre10\">Figure 2.12<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.13: Setting colors and cursor size on Windows\" height=\"969\" src=\"\/images\/cs12\/000147.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.13: Setting colors and cursor size on Windows<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">If you are using Visual Studio Code, then run the code with arguments to set the foreground color to red, the background color to yellow, and the cursor size to 50%, as shown in the following command:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet run red yellow 50<\/code><\/pre>\n<\/div>\n<p class=\"rights\">On macOS or Linux, you'll see an unhandled exception, as shown in <em class=\"calibre10\">Figure 2.13<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.13: An unhandled exception on unsupported macOS\" height=\"324\" src=\"\/images\/cs12\/000063.png\" width=\"856\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.13: An unhandled exception on unsupported macOS<\/figcaption><\/figure>\n<p class=\"rights\">Although the compiler did not give an error or warning, at runtime, some API calls may fail on some platforms. Although a console app running on Windows can change its cursor size, on macOS, it cannot, and it complains if you try.<\/p>\n<\/section>\n<section data-number=\"3.6.7\" id=\"calibre_link-126\">\n<h3 data-number=\"3.6.7\" class=\"calibre8\">Handling platforms that do not support an API<\/h3>\n<p class=\"rights\">So how do we solve this problem? We can solve this by using an exception handler. You will learn more details about the <code class=\"calibre9\">try<\/code>-<code class=\"calibre9\">catch<\/code> statement in <em class=\"calibre10\">Chapter 3<\/em>, <em class=\"calibre10\">Controlling Flow, Converting Types, and Handling Exceptions<\/em>, so for now, just enter the code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the code to wrap the lines that change the cursor size in a <code class=\"calibre9\">try<\/code> statement, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">try\n{\n  CursorSize = int.Parse(args[2]);\n}\ncatch (PlatformNotSupportedException)\n{\n  WriteLine(\"The current platform does not support changing the size of the cursor.\");\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you were to run the code on macOS, then you would see the exception is caught, and a friendlier message is shown to the user.Another way to handle differences in operating systems is to use the <code class=\"calibre9\">OperatingSystem<\/code> class in the <code class=\"calibre9\">System<\/code> namespace, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (OperatingSystem.IsWindows())\n{\n  \/\/ Execute code that only works on Windows.\n}\nelse if (OperatingSystem.IsWindowsVersionAtLeast(major: 10))\n{\n  \/\/ Execute code that only works on Windows 10 or later.\n}\nelse if (OperatingSystem.IsIOSVersionAtLeast(major: 14, minor: 5))\n{\n  \/\/ Execute code that only works on iOS 14.5 or later.\n}\nelse if (OperatingSystem.IsBrowser())\n{\n  \/\/ Execute code that only works in the browser with Blazor.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">OperatingSystem<\/code> class has equivalent methods for other common operating systems like Android, iOS, Linux, macOS, and even the browser, which is useful for Blazor web components.A third way to handle different platforms is to use conditional compilation statements.There are four preprocessor directives that control conditional compilation: <code class=\"calibre9\">#if<\/code>, <code class=\"calibre9\">#elif<\/code>, <code class=\"calibre9\">#else<\/code>, and <code class=\"calibre9\">#endif<\/code>.You define symbols using <code class=\"calibre9\">#define<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#define MYSYMBOL<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Many symbols are automatically defined for you, as shown in <em class=\"calibre10\">Table 2.23<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Target Framework<\/td>\n<td class=\"calibre21\">Symbols<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">.NET Standard<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">NETSTANDARD2_0<\/code> , <code class=\"calibre9\">NETSTANDARD2_1<\/code> , and so on<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Modern .NET<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">NET7_0<\/code> , <code class=\"calibre9\">NET7_0_ANDROID<\/code> , <code class=\"calibre9\">NET7_0_IOS<\/code> , <code class=\"calibre9\">NET7_0_WINDOWS<\/code> , and so on<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 2.23: Predefined compiler symbols<\/p>\n<p class=\"rights\">You can then write statements that will compile only for the specified platforms, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#if NET7_0_ANDROID\n\/\/ Compile statements that only work on Android.\n#elif NET7_0_IOS\n\/\/ Compile statements that only work on iOS.\n#else\n\/\/ Compile statements that work everywhere else.\n#endif<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"3.7\" id=\"calibre_link-127\">\n<h2 data-number=\"3.7\" class=\"calibre5\">Understanding async and await<\/h2>\n<p class=\"rights\">C# 5 introduced two C# keywords when working with the <code class=\"calibre9\">Task<\/code> type that enable easy multithreading. The pair of keywords is especially useful for the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Implementing multitasking for a <strong class=\"calibre2\">graphical user interface<\/strong> (<strong class=\"calibre2\">GUI<\/strong>).<\/li>\n<li class=\"calibre3\">Improving the scalability of web applications and web services.<\/li>\n<li class=\"calibre3\">Preventing blocking calls when interacting with the filesystem, databases, and remote services, all of which tend to take a long time to complete their work.<\/li>\n<\/ul>\n<p class=\"rights\">In <em class=\"calibre10\">Chapter 13<\/em>, <em class=\"calibre10\">Building Websites Using the Model-View-Controller Pattern<\/em>, we will see how the <code class=\"calibre9\">async<\/code> and <code class=\"calibre9\">await<\/code> keywords can improve scalability for websites. But for now, let's see an example of how they can be used in a console app, and then later you will see them used in a more practical example within web projects.<\/p>\n<section data-number=\"3.7.1\" id=\"calibre_link-128\">\n<h3 data-number=\"3.7.1\" class=\"calibre8\">Improving responsiveness for console apps<\/h3>\n<p class=\"rights\">One of the limitations with console apps is that you can only use the <code class=\"calibre9\">await<\/code> keyword inside methods that are marked as <code class=\"calibre9\">async<\/code>, but C# 7 and earlier do not allow the <code class=\"calibre9\">Main<\/code> method to be marked as <code class=\"calibre9\">async<\/code>! Luckily, a new feature introduced in C# 7.1 was support for <code class=\"calibre9\">async<\/code> in <code class=\"calibre9\">Main<\/code>.Let's see it in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">AsyncConsole<\/code> to the <code class=\"calibre9\">Chapter02<\/code> solution.<\/li>\n<li class=\"calibre3\">Open <code class=\"calibre9\">AsyncConsole.csproj<\/code>, and after the <code class=\"calibre9\">&lt;PropertyGroup&gt;<\/code> section, add a new <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> section to statically import <code class=\"calibre9\">System.Console<\/code> for all C# files using the implicit usings .NET SDK feature, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, and then add statements to create an <code class=\"calibre9\">HttpClient<\/code> instance, make a request for Apple's home page, and output how many bytes it has, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">HttpClient client = new();\nHttpResponseMessage response =\n  await client.GetAsync(\"http:\/\/www.apple.com\/\");\nWriteLine(\"Apple's home page has {0:N0} bytes.\",\n  response.Content.Headers.ContentLength);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Navigate to <strong class=\"calibre2\">Build<\/strong> | <strong class=\"calibre2\">Build AsyncConsole<\/strong> and note that the project builds successfully.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In .NET 5 and earlier, you would have seen an error message, as shown in the following output:<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">Program.cs(14,9): error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'. [\/Users\/markjprice\/Code\/ Chapter02\/AsyncConsole\/AsyncConsole.csproj]<\/code><\/p>\n<\/blockquote>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You would have had to add the <code class=\"calibre9\">async<\/code> keyword to your <code class=\"calibre9\">Main<\/code> method and change its return type from <code class=\"calibre9\">void<\/code> to <code class=\"calibre9\">Task<\/code>. With .NET 6 and later, the console app project template uses the top-level program feature to automatically define the <code class=\"calibre9\">Program<\/code> class with an asynchronous <code class=\"calibre9\">&lt;Main&gt;$<\/code> method for you.<\/p>\n<\/blockquote>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Run the code and view the result, which is likely to have a different number of bytes since Apple changes its home page frequently, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Apple's home page has 170,688 bytes.<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"3.8\" id=\"calibre_link-129\">\n<h2 data-number=\"3.8\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring the topics covered in this chapter with deeper research.<\/p>\n<section data-number=\"3.8.1\" id=\"calibre_link-130\">\n<h3 data-number=\"3.8.1\" class=\"calibre8\">Exercise 2.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">To get the best answer to some of these questions, you will need to do your own research. I want you to \"think outside the book,\" so I have deliberately not provided all the answers in the book.I want to encourage you to get into the good habit of looking for help elsewhere, following the principle of \"teach a person to fish.\"<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What statement can you type in a C# file to discover the compiler and language version?<\/li>\n<li class=\"calibre3\">What are the two types of comments in C#?<\/li>\n<li class=\"calibre3\">What is the difference between a verbatim string and an interpolated string?<\/li>\n<li class=\"calibre3\">Why should you be careful when using <code class=\"calibre9\">float<\/code> and <code class=\"calibre9\">double<\/code> values?<\/li>\n<li class=\"calibre3\">How can you determine how many bytes a type like <code class=\"calibre9\">double<\/code> uses in memory?<\/li>\n<li class=\"calibre3\">When should you use the <code class=\"calibre9\">var<\/code> keyword?<\/li>\n<li class=\"calibre3\">What is the newest syntax to create an instance of a class like <code class=\"calibre9\">XmlDocument<\/code>?<\/li>\n<li class=\"calibre3\">Why should you be careful when using the <code class=\"calibre9\">dynamic<\/code> type?<\/li>\n<li class=\"calibre3\">How do you right-align a format string?<\/li>\n<li class=\"calibre3\">What character separates arguments for a console app?<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><em class=\"calibre10\">Appendix<\/em>, <em class=\"calibre10\">Answers to the Test Your Knowledge Questions<\/em>, is available to download from a link in the README on the GitHub repository: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\">https:\/\/github.com\/markjprice\/cs12dotnet8<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"3.8.2\" id=\"calibre_link-131\">\n<h3 data-number=\"3.8.2\" class=\"calibre8\">Exercise 2.2 &ndash; Test your knowledge of number types<\/h3>\n<p class=\"rights\">What type would you choose for the following \"numbers\"?<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A person's telephone number<\/li>\n<li class=\"calibre3\">A person's height<\/li>\n<li class=\"calibre3\">A person's age<\/li>\n<li class=\"calibre3\">A person's salary<\/li>\n<li class=\"calibre3\">A book's ISBN<\/li>\n<li class=\"calibre3\">A book's price<\/li>\n<li class=\"calibre3\">A book's shipping weight<\/li>\n<li class=\"calibre3\">A country's population<\/li>\n<li class=\"calibre3\">The number of stars in the universe<\/li>\n<li class=\"calibre3\">The number of employees in each of the small or medium businesses in the UK (up to about 50,000 employees per business)<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"3.8.3\" id=\"calibre_link-132\">\n<h3 data-number=\"3.8.3\" class=\"calibre8\">Exercise 2.3 &ndash; Practice number sizes and ranges<\/h3>\n<p class=\"rights\">In the <code class=\"calibre9\">Chapter02<\/code> solution, create a console app project named <code class=\"calibre9\">Ch02Ex03Numbers<\/code> that outputs the number of bytes in memory that each of the following number types uses and the minimum and maximum values they can have: <code class=\"calibre9\">sbyte<\/code>, <code class=\"calibre9\">byte<\/code>, <code class=\"calibre9\">short<\/code>, <code class=\"calibre9\">ushort<\/code>, <code class=\"calibre9\">int<\/code>, <code class=\"calibre9\">uint<\/code>, <code class=\"calibre9\">long<\/code>, <code class=\"calibre9\">ulong<\/code>, <code class=\"calibre9\">Int128<\/code>, <code class=\"calibre9\">UInt128<\/code>, <code class=\"calibre9\">Half<\/code>, <code class=\"calibre9\">float<\/code>, <code class=\"calibre9\">double<\/code>, and <code class=\"calibre9\">decimal<\/code>.The result of running your console app should look something like <em class=\"calibre10\">Figure 2.14<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 2.14: The result of outputting number type sizes\" height=\"800\" src=\"\/images\/cs12\/000079.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 2.14: The result of outputting number type sizes<\/figcaption><\/figure>\n<p class=\"rights\">Code solutions for all exercises are available to download or clone from the GitHub repository at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\">https:\/\/github.com\/markjprice\/cs12dotnet8<\/a>.<\/p>\n<\/section>\n<section data-number=\"3.8.4\" id=\"calibre_link-133\">\n<h3 data-number=\"3.8.4\" class=\"calibre8\">Exercise 2.4 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more details about the topics covered in this chapter:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-2---speaking-c\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-2---speaking-c<\/a><\/p>\n<\/section>\n<section data-number=\"3.8.5\" id=\"calibre_link-134\">\n<h3 data-number=\"3.8.5\" class=\"calibre8\">Exercise 2.5 &ndash; Explore Spectre<\/h3>\n<p class=\"rights\">No, not the villainous organization from the James Bond films! <strong class=\"calibre2\">Spectre<\/strong> is a package that enhances console apps. You can read about it at the following link: <code class=\"calibre9\">https:\/\/spectreconsole.net\/<\/code>.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"3.9\" id=\"calibre_link-135\">\n<h2 data-number=\"3.9\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned how to:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Declare variables with a specified or inferred type.<\/li>\n<li class=\"calibre3\">Use some of the built-in types for numbers, text, and Booleans.<\/li>\n<li class=\"calibre3\">Choose between number types.<\/li>\n<li class=\"calibre3\">Control output formatting in console apps.<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will learn about operators, branching, looping, converting between types, and how to handle exceptions.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-933\">\n<div id=\"calibre_link-1918\" class=\"calibre1\">\n<section data-number=\"4\" id=\"calibre_link-136\">\n<h1 data-number=\"4\" class=\"title\">3 Controlling Flow, Converting Types, and Handling Exceptions<\/h1>\n<section data-number=\"4.1\" id=\"calibre_link-137\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"4.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000095.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is all about writing code that performs simple operations on variables, makes decisions, performs pattern matching, and repeats statements or blocks. You will also learn how to work with arrays to store multiple values, how to convert variable or expression values from one type to another, how to handle exceptions, and how to check for overflows in number variables.This chapter covers the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Operating on variables<\/li>\n<li class=\"calibre3\">Understanding selection statements<\/li>\n<li class=\"calibre3\">Understanding iteration statements<\/li>\n<li class=\"calibre3\">Storing multiple values in an array<\/li>\n<li class=\"calibre3\">Casting and converting between types<\/li>\n<li class=\"calibre3\">Handling exceptions<\/li>\n<li class=\"calibre3\">Checking for overflow<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"4.2\" id=\"calibre_link-138\">\n<h2 data-number=\"4.2\" class=\"calibre5\">Operating on variables<\/h2>\n<p class=\"rights\"><strong class=\"calibre2\">Operators<\/strong>&nbsp;apply simple operations such as&nbsp;addition and multiplication to&nbsp;<strong class=\"calibre2\">operands<\/strong>&nbsp;such as variables and literal values. Operators return a new value that is the result of the operation and can be assigned to a variable, and they can also affect the operands.<\/p>\n<section data-number=\"4.2.1\" id=\"calibre_link-139\">\n<h3 data-number=\"4.2.1\" class=\"calibre8\">Understanding binary operators<\/h3>\n<p class=\"rights\">Most operators are <strong class=\"calibre2\">binary<\/strong>, meaning that they work on two operands, as shown in the following pseudocode:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var resultOfOperation = firstOperand operator secondOperand;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Examples of binary operators include adding and multiplying, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int x = 5;\nint y = 3;\nint resultOfAdding = x + y;\nint resultOfMultiplying = x * y;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.2.2\" id=\"calibre_link-140\">\n<h3 data-number=\"4.2.2\" class=\"calibre8\">Understanding unary operators<\/h3>\n<p class=\"rights\">Some operators are <strong class=\"calibre2\">unary<\/strong>, meaning they work on a single operand and can be applied before or after the operand, as shown in the following pseudocode:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var resultOfOperationAfter = onlyOperand operator; \nvar resultOfOperationBefore = operator onlyOperand;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Examples of unary operators include incrementors and retrieving a type or its size in bytes, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int x = 5;\nint postfixIncrement = x++;\nint prefixIncrement = ++x;\nType theTypeOfAnInteger = typeof(int);\nstring nameOfVariable = nameof(x);\nint howManyBytesInAnInteger = sizeof(int);<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.2.3\" id=\"calibre_link-141\">\n<h3 data-number=\"4.2.3\" class=\"calibre8\">Understanding ternary operators<\/h3>\n<p class=\"rights\">A <strong class=\"calibre2\">ternary<\/strong> operator works on three&nbsp;operands, as shown in the following pseudocode:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var resultOfOperation = firstOperand firstOperator \n  secondOperand secondOperator thirdOperand;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">An example of a ternary operator is the conditional operator <code class=\"calibre9\">?:<\/code>, which acts like a simplified <code class=\"calibre9\">if<\/code> statement. The first operand is a Boolean expression, the second operand is a value to return if it is <code class=\"calibre9\">true<\/code>, and the third operand is a value to return if it is <code class=\"calibre9\">false<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Syntax of conditional operator.\nvar result = boolean_expression ? value_if_true : value_if_false;\n\/\/ Example of conditional operator.\nstring result = x &gt; 3 ? \"Greater than 3\" : \"Less than or equal to 3\";\n\/\/ Equivalent using an if statement.\nstring result;\nif (x &gt; 3)\n{\n  result = \"Greater than 3\";\n}\nelse\n{\n  result = \"Less than or equal to 3\";\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">More experienced C# developers adopt ternary operators as much as possible because they are concise and can result in cleaner code once you are used to reading them.<\/p>\n<\/section>\n<section data-number=\"4.2.4\" id=\"calibre_link-142\">\n<h3 data-number=\"4.2.4\" class=\"calibre8\">Exploring unary operators<\/h3>\n<p class=\"rights\">Two common unary operators are used to increment,&nbsp;<code class=\"calibre9\">++<\/code>, and decrement,&nbsp;<code class=\"calibre9\">--<\/code>, a number. Let us write some example code&nbsp;to show how they work:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you've completed the previous chapters, then you will already have a&nbsp;<code class=\"calibre9\">cs12dotnet8<\/code>&nbsp;folder. If not, then you'll need to create it.<\/li>\n<li class=\"calibre3\">Use your preferred coding tool to create a new solution and project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template:&nbsp;<strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code><\/li>\n<li class=\"calibre3\">Project file and folder:&nbsp;<code class=\"calibre9\">Operators<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder:&nbsp;<code class=\"calibre9\">Chapter03<\/code><\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Do not use top-level statements<\/strong>: Cleared<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Enable native AOT publish<\/strong>: Cleared<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Operators.csproj<\/code>, add a new <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> section to statically import <code class=\"calibre9\">System.Console<\/code> for all C# files using the <code class=\"calibre9\">implicit usings<\/code> .NET SDK feature, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In&nbsp;<code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then declare two integer variables named&nbsp;<code class=\"calibre9\">a<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">b<\/code>, set&nbsp;<code class=\"calibre9\">a<\/code>&nbsp;to&nbsp;<code class=\"calibre9\">3<\/code>, increment&nbsp;<code class=\"calibre9\">a<\/code>&nbsp;while assigning the result to&nbsp;<code class=\"calibre9\">b<\/code>, and then output their values, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Exploring unary operators\nint a = 3; \nint b = a++;\nWriteLine($\"a is {a}, b is {b}\");\n#endregion<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: I recommend wrapping the statements for each section in <code class=\"calibre9\">#region<\/code> and <code class=\"calibre9\">#endregion<\/code> as shown in the preceding code so that you can easily collapse the sections. But I will not show this in future code tasks to save space.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Before running the console app, ask yourself a question: what do you think the value of&nbsp;<code class=\"calibre9\">b<\/code>&nbsp;will be when output? Once you've thought about that, run the code and compare your prediction against the actual result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">a is 4, b is 3<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The variable&nbsp;<code class=\"calibre9\">b<\/code>&nbsp;has&nbsp;the value&nbsp;<code class=\"calibre9\">3<\/code>&nbsp;because the&nbsp;<code class=\"calibre9\">++<\/code>&nbsp;operator executes&nbsp;<em class=\"calibre10\">after<\/em>&nbsp;the&nbsp;assignment; this is known as a&nbsp;<strong class=\"calibre2\">postfix operator<\/strong>. If you need to increment&nbsp;<em class=\"calibre10\">before<\/em>&nbsp;the assignment, then use the&nbsp;<strong class=\"calibre2\">prefix operator<\/strong>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Copy and paste the statements, and then modify them to rename the variables and use the prefix operator, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int c = 3;\nint d = ++c; \/\/ Prefix means increment c before assigning it.\nWriteLine($\"c is {c}, d is {d}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Rerun the code and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">a is 4, b is 3\nc is 4, d is 4<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Due to the confusion between the prefix and postfix for the increment and decrement operators when combined with an assignment, the Swift programming language designers decided to drop support for this operator in version 3. My recommendation for usage in C# is to never combine the use of&nbsp;the <code class=\"calibre9\">++<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">--<\/code>&nbsp;operators with an assignment operator,&nbsp;<code class=\"calibre9\">=<\/code>. Perform the operations as separate statements.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.2.5\" id=\"calibre_link-143\">\n<h3 data-number=\"4.2.5\" class=\"calibre8\">Exploring binary arithmetic operators<\/h3>\n<p class=\"rights\">Increment and decrement are unary arithmetic operators. Other arithmetic operators are usually binary and allow&nbsp;you to perform arithmetic operations on two numbers, as the following shows:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to declare and assign values to two integer variables named&nbsp;<code class=\"calibre9\">e<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">f<\/code>, and then apply the five common binary arithmetic operators to the two numbers, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int e = 11; \nint f = 3;\nWriteLine($\"e is {e}, f is {f}\"); \nWriteLine($\"e + f = {e + f}\"); \nWriteLine($\"e - f = {e - f}\"); \nWriteLine($\"e * f = {e * f}\"); \nWriteLine($\"e \/ f = {e \/ f}\"); \nWriteLine($\"e % f = {e % f}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">e is 11, f is 3 \ne + f = 14\ne - f = 8 \ne * f = 33 \ne \/ f = 3 \ne % f = 2<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To understand the divide&nbsp;<code class=\"calibre9\">\/<\/code>&nbsp;and modulo&nbsp;<code class=\"calibre9\">%<\/code>&nbsp;operators when applied to integers, you need to think back to primary school. Imagine you have eleven sweets and three friends.How can you divide the sweets between your friends? You can give three sweets to each of your friends, and there&nbsp;will be two left over. Those two sweets are the&nbsp;<strong class=\"calibre2\">modulus<\/strong>, also known as the&nbsp;<strong class=\"calibre2\">remainder<\/strong>&nbsp;after dividing. If you had twelve sweets, then each friend would get four of them, and there would be none left over, so the remainder would be 0.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to declare and assign a value to a&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;variable named&nbsp;<code class=\"calibre9\">g<\/code>&nbsp;to show the difference between whole-number and real-number divisions, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">double g = 11.0;\nWriteLine($\"g is {g:N1}, f is {f}\"); \nWriteLine($\"g \/ f = {g \/ f}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">g is 11.0, f is 3\ng \/ f = 3.6666666666666665<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If the first operand is a floating-point number, such as&nbsp;<code class=\"calibre9\">g<\/code>&nbsp;with the value&nbsp;<code class=\"calibre9\">11.0<\/code>, then the divide operator returns a floating-point value, such as&nbsp;<code class=\"calibre9\">3.6666666666665<\/code>, rather than a whole number.<\/p>\n<\/section>\n<section data-number=\"4.2.6\" id=\"calibre_link-144\">\n<h3 data-number=\"4.2.6\" class=\"calibre8\">Assignment operators<\/h3>\n<p class=\"rights\">You have already been using the most common assignment operator,&nbsp;<code class=\"calibre9\">=<\/code>.To make your code&nbsp;more concise, you can combine the assignment operator with other operators like arithmetic operators, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int p = 6;\np += 3; \/\/ Equivalent to: p = p + 3;\np -= 3; \/\/ Equivalent to: p = p - 3;\np *= 3; \/\/ Equivalent to: p = p * 3;\np \/= 3; \/\/ Equivalent to: p = p \/ 3;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.2.7\" id=\"calibre_link-145\">\n<h3 data-number=\"4.2.7\" class=\"calibre8\">Null-coalescing operators<\/h3>\n<p class=\"rights\">Related operators to the assignment operators are the null-coalescing operators. Sometimes, you want to either assign a variable to a result or if the variable is <code class=\"calibre9\">null<\/code>, then assign an alternative value. You can do this using the null-coalescing operators, <code class=\"calibre9\">??<\/code> or <code class=\"calibre9\">??=<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string? authorName = ReadLine(); \/\/ Prompt user to enter an author name.\n\/\/ The maxLength variable will be the length of authorName if it is \n\/\/ not null, or 30 if authorName is null.\nint maxLength = authorName?.Length ?? 30;\n\/\/ The authorName variable will be \"unknown\" if authorName was null.\nauthorName ??= \"unknown\";<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.2.8\" id=\"calibre_link-146\">\n<h3 data-number=\"4.2.8\" class=\"calibre8\">Exploring logical operators<\/h3>\n<p class=\"rights\">Logical operators operate on Boolean values, so they return either&nbsp;<code class=\"calibre9\">true<\/code>&nbsp;or&nbsp;<code class=\"calibre9\">false<\/code>. Let's explore binary logical operators&nbsp;that operate on two Boolean values, traditionally named <code class=\"calibre9\">p<\/code> and <code class=\"calibre9\">q<\/code> in mathematics:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In&nbsp;<code class=\"calibre9\">Program.cs<\/code>, add statements to declare two Boolean variables <code class=\"calibre9\">p<\/code> and <code class=\"calibre9\">q<\/code> with values of&nbsp;<code class=\"calibre9\">true<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">false<\/code>, and then output truth tables showing the results of applying AND, OR, and XOR (exclusive OR) logical operators, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">bool p = true;\nbool q = false;\nWriteLine($\"AND  | p     | q    \");\nWriteLine($\"p    | {p &amp; p,-5} | {p &amp; q,-5} \");\nWriteLine($\"q    | {q &amp; p,-5} | {q &amp; q,-5} \");\nWriteLine();\nWriteLine($\"OR   | p     | q    \");\nWriteLine($\"p    | {p | p,-5} | {p | q,-5} \");\nWriteLine($\"q    | {q | p,-5} | {q | q,-5} \");\nWriteLine();\nWriteLine($\"XOR  | p     | q    \");\nWriteLine($\"p    | {p ^ p,-5} | {p ^ q,-5} \");\nWriteLine($\"q    | {q ^ p,-5} | {q ^ q,-5} \");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Remember that <code class=\"calibre9\">,-5<\/code> means left-align within a five-width column.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">AND  | p     | q\np    | True  | False\nq    | False | False\nOR   | p     | q\np    | True  | True\nq    | True  | False\nXOR  | p     | q\np    | False | True\nq    | True  | False<\/code><\/pre>\n<\/div>\n<p class=\"rights\">For the AND&nbsp;<code class=\"calibre9\">&amp;<\/code>&nbsp;logical operator, both&nbsp;operands must be&nbsp;<code class=\"calibre9\">true<\/code>&nbsp;for the result to be&nbsp;<code class=\"calibre9\">true<\/code>. For the OR&nbsp;<code class=\"calibre9\">|<\/code>&nbsp;logical operator, either operand can be&nbsp;<code class=\"calibre9\">true<\/code>&nbsp;for the result to be&nbsp;<code class=\"calibre9\">true<\/code>. For the XOR&nbsp;<code class=\"calibre9\">^<\/code>&nbsp;logical operator, either operand can be&nbsp;<code class=\"calibre9\">true<\/code>&nbsp;(but not both!) for the result to be&nbsp;<code class=\"calibre9\">true<\/code>.<\/p>\n<\/section>\n<section data-number=\"4.2.9\" id=\"calibre_link-147\">\n<h3 data-number=\"4.2.9\" class=\"calibre8\">Exploring conditional logical operators<\/h3>\n<p class=\"rights\">Conditional logical operators are like logical operators, but you use two symbols instead of one, for example,&nbsp;<code class=\"calibre9\">&amp;&amp;<\/code>&nbsp;instead&nbsp;of&nbsp;<code class=\"calibre9\">&amp;<\/code>, or&nbsp;<code class=\"calibre9\">||<\/code>&nbsp;instead of&nbsp;<code class=\"calibre9\">|<\/code>.In&nbsp;<em class=\"calibre10\">Chapter 4<\/em>,&nbsp;<em class=\"calibre10\">Writing, Debugging, and Testing Functions<\/em>, you will learn about functions in more detail, but I need to introduce&nbsp;functions now to explain conditional logical operators, also known as short-circuiting Boolean operators.A function executes statements and then returns a value. That value could be a Boolean value like&nbsp;<code class=\"calibre9\">true<\/code>&nbsp;that is used in a Boolean operation. Let's make use of conditional logical operators:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of&nbsp;<code class=\"calibre9\">Program.cs<\/code>, write&nbsp;statements to declare a function that writes a message to the console and returns&nbsp;<code class=\"calibre9\">true<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static bool DoStuff()\n{\n  WriteLine(\"I am doing some stuff.\");\n  return true;\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Local functions can be anywhere within the statements in <code class=\"calibre9\">Program.cs<\/code> that uses the top-level program feature but it is good practice to put them at the bottom of the file.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">After the previous&nbsp;<code class=\"calibre9\">WriteLine<\/code>&nbsp;statements, perform an AND&nbsp;<code class=\"calibre9\">&amp;<\/code>&nbsp;operation on the&nbsp;<code class=\"calibre9\">p<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">q<\/code>&nbsp;variables, and the result of calling the function, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine();\n\/\/ Note that DoStuff() returns true.\nWriteLine($\"p &amp; DoStuff() = {p &amp; DoStuff()}\"); \nWriteLine($\"q &amp; DoStuff() = {q &amp; DoStuff()}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that the function was called twice, once for <code class=\"calibre9\">p<\/code> and once for <code class=\"calibre9\">q<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">I am doing some stuff. \np &amp; DoStuff() = True\nI am doing some stuff. \nq &amp; DoStuff() = False<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Copy and paste the three statements and then change the&nbsp;<code class=\"calibre9\">&amp;<\/code>&nbsp;operators into&nbsp;<code class=\"calibre9\">&amp;&amp;<\/code>&nbsp;operators, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine();\nWriteLine($\"p &amp;&amp; DoStuff() = {p &amp;&amp; DoStuff()}\"); \nWriteLine($\"q &amp;&amp; DoStuff() = {q &amp;&amp; DoStuff()}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that the function does run when combined with the&nbsp;<code class=\"calibre9\">p<\/code>&nbsp;variable. It does not&nbsp;run when combined with the&nbsp;<code class=\"calibre9\">q<\/code>&nbsp;variable because the&nbsp;<code class=\"calibre9\">q<\/code>&nbsp;variable is&nbsp;<code class=\"calibre9\">false<\/code>&nbsp;so the result will be&nbsp;<code class=\"calibre9\">false<\/code>&nbsp;anyway, so it does not need to execute the function, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">I am doing some stuff. \np &amp;&amp; DoStuff() = True\nq &amp;&amp; DoStuff() = False \/\/ DoStuff function was not executed!<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Now you can see why the conditional logical operators are described as being short-circuiting. They can make your apps more efficient, but they can also introduce subtle bugs in cases where you assume that the function will always be called. It is safest to avoid them when used in combination with functions that cause side effects.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.2.10\" id=\"calibre_link-148\">\n<h3 data-number=\"4.2.10\" class=\"calibre8\">Exploring bitwise and binary shift operators<\/h3>\n<p class=\"rights\">Bitwise operators compare the&nbsp;bits in the binary representation of a number. Each bit, either the <code class=\"calibre9\">0<\/code> (zero) or <code class=\"calibre9\">1<\/code> (one) value, is compared individually to the bit in the same column.Binary shift operators can perform some common&nbsp;arithmetic calculations much faster than traditional operators, for example, any multiplication by a factor of 2.Let's explore bitwise and binary shift operators:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In&nbsp;<code class=\"calibre9\">Program.cs<\/code>, add statements to declare two integer variables named <code class=\"calibre9\">x<\/code> and <code class=\"calibre9\">y<\/code> with values <code class=\"calibre9\">10<\/code> and <code class=\"calibre9\">6<\/code>, and then output the results of applying AND, OR, and XOR bitwise operators, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine();\nint x = 10;\nint y = 6;\nWriteLine($\"Expression | Decimal |   Binary\");\nWriteLine($\"-------------------------------\");\nWriteLine($\"x          | {x,7} | {x:B8}\");\nWriteLine($\"y          | {y,7} | {y:B8}\");\nWriteLine($\"x &amp; y      | {x &amp; y,7} | {x &amp; y:B8}\");\nWriteLine($\"x | y      | {x | y,7} | {x | y:B8}\");\nWriteLine($\"x ^ y      | {x ^ y,7} | {x ^ y:B8}\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Remember that <code class=\"calibre9\">,7<\/code> means right-align in a seven-width column and <code class=\"calibre9\">:B8<\/code> means format in binary with eight digits.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Expression | Decimal |   Binary\n-------------------------------\nx          |      10 | 00001010\ny          |       6 | 00000110\nx &amp; y      |       2 | 00000010\nx | y      |      14 | 00001110\nx ^ y      |      12 | 00001100<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">For <code class=\"calibre9\">x &amp; y<\/code>, only the 2-bit column is set. For <code class=\"calibre9\">x | y<\/code>, the 8, 4 and 2-bit columns are set. For <code class=\"calibre9\">x ^ y<\/code>, the 8 and 4 columns are set.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In&nbsp;<code class=\"calibre9\">Program.cs<\/code>, add statements to output the results of applying the left-shift operator to move the bits of the&nbsp;variable&nbsp;<code class=\"calibre9\">a<\/code>&nbsp;by three columns, multiplying&nbsp;<code class=\"calibre9\">a<\/code>&nbsp;by 8, and&nbsp;right-shifting the bits of the variable&nbsp;<code class=\"calibre9\">b<\/code>&nbsp;by one column, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Left-shift x by three bit columns.\nWriteLine($\"x &lt;&lt; 3     | {x &lt;&lt; 3,7} | {x &lt;&lt; 3:B8}\");\n\/\/ Multiply x by 8.\nWriteLine($\"x * 8      | {x * 8,7} | {x * 8:B8}\");\n\/\/ Right-shift y by one bit column.\nWriteLine($\"y &gt;&gt; 1     | {y &gt;&gt; 1,7} | {y &gt;&gt; 1:B8}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">x &lt;&lt; 3     |      80 | 01010000\nx * 8      |      80 | 01010000\ny &gt;&gt; 1     |       3 | 00000011<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The&nbsp;<code class=\"calibre9\">80<\/code>&nbsp;result is because the bits in it were shifted three columns to the left, so the 1 bits moved into the 64- and 16-bit columns, and 64 + 16 = 80. This is the equivalent of multiplying by 8, but CPUs can perform a bit-shift faster. The <code class=\"calibre9\">3<\/code> result is because the 1 bits in&nbsp;<code class=\"calibre9\">b<\/code>&nbsp;were shifted one column into the 2- and 1-bit columns.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Remember that when operating on integer values, the&nbsp;<code class=\"calibre9\">&amp;<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">|<\/code>&nbsp;symbols are bitwise operators, and when operating on Boolean values like&nbsp;<code class=\"calibre9\">true<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">false<\/code>, the&nbsp;<code class=\"calibre9\">&amp;<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">|<\/code>&nbsp;symbols are logical operators.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.2.11\" id=\"calibre_link-149\">\n<h3 data-number=\"4.2.11\" class=\"calibre8\">Miscellaneous operators<\/h3>\n<p class=\"rights\"><code class=\"calibre9\">nameof<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">sizeof<\/code>&nbsp;are convenient operators when working with types:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">nameof<\/code>&nbsp;returns the short name (without the namespace) of a variable, type, or member as a&nbsp;<code class=\"calibre9\">string<\/code>&nbsp;value, which is useful when outputting exception messages.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">sizeof<\/code>&nbsp;returns the size in bytes of simple types, which is useful for determining the efficiency of data storage. Technically, the <code class=\"calibre9\">sizeof<\/code> operator requires an unsafe code block but the sizes of value types with a C# alias, like <code class=\"calibre9\">int<\/code> and <code class=\"calibre9\">double<\/code>, are hardcoded as constants by the compiler so they do not need an unsafe block.<\/li>\n<\/ul>\n<p class=\"rights\">For example:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int age = 50;\nWriteLine($\"The {nameof(age)} variable uses {sizeof(int)} bytes of memory.\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">There are many other operators; for example, the dot between a variable and its members is called the&nbsp;<strong class=\"calibre2\">member access operator<\/strong>&nbsp;and the&nbsp;round brackets at the end of a function or method&nbsp;name are called the&nbsp;<strong class=\"calibre2\">invocation operator<\/strong>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int age = 50;\n\/\/ How many operators in the following statement?\nchar firstDigit = age.ToString()[0];\n\/\/ There are four operators:\n\/\/ = is the assignment operator\n\/\/ . is the member access operator\n\/\/ () is the invocation operator\n\/\/ [] is the indexer access operator<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"4.3\" id=\"calibre_link-150\">\n<h2 data-number=\"4.3\" class=\"calibre5\">Understanding selection statements<\/h2>\n<p class=\"rights\">Every application needs to be able to select from choices and branch along different code paths. The two selection statements in C# are&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">switch<\/code>. You can use&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;for all your code, but&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;can simplify your code in&nbsp;some common scenarios, such as when there is a single variable that can have multiple values that each require different processing.<\/p>\n<section data-number=\"4.3.1\" id=\"calibre_link-151\">\n<h3 data-number=\"4.3.1\" class=\"calibre8\">Branching with the if statement<\/h3>\n<p class=\"rights\">The&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;statement determines which branch to follow by evaluating a Boolean expression. If the expression is&nbsp;<code class=\"calibre9\">true<\/code>, then the&nbsp;block executes. The&nbsp;<code class=\"calibre9\">else<\/code>&nbsp;block is optional, and it executes if the&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;expression is&nbsp;<code class=\"calibre9\">false<\/code>. The&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;statement can be nested.The&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;statement can be combined with other&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;statements as&nbsp;<code class=\"calibre9\">else if<\/code>&nbsp;branches, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (expression1)\n{\n  \/\/ Executes if expression1 is true.\n}\nelse if (expression2)\n{\n  \/\/ Executes if expression1 is false and expression2 is true.\n}\nelse if (expression3)\n{\n  \/\/ Executes if expression1 and expression2 are false\n  \/\/ and expression3 is true.\n}\nelse\n{\n  \/\/ Executes if all expressions are false.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Each&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;statement's Boolean&nbsp;expression is independent of the others and, unlike&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;statements, does not need to reference a single value.Let's write some code to explore selection statements like&nbsp;<code class=\"calibre9\">if<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Use your preferred coding tool to add a new&nbsp;<strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named&nbsp;<code class=\"calibre9\">SelectionStatements<\/code> to the&nbsp;<code class=\"calibre9\">Chapter03<\/code>&nbsp;solution.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Remember to statically import <code class=\"calibre9\">System.Console<\/code> in your project file. And if you are using Visual Studio 2022, then configure the startup project to be the current selection.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">In&nbsp;<code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then add statements to check if a password is at least eight characters, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string password = \"ninja\";\nif (password.Length &lt; 8)\n{\n  WriteLine(\"Your password is too short. Use at least 8 chars.\");\n}\nelse\n{\n  WriteLine(\"Your password is strong.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\"> Your password is too short. Use at least 8 chars.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.3.2\" id=\"calibre_link-152\">\n<h3 data-number=\"4.3.2\" class=\"calibre8\">Why you should always use braces with if statements<\/h3>\n<p class=\"rights\">As there is only a single statement inside each block, the preceding code could be written without the curly braces, as shown&nbsp;in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (password.Length &lt; 8)\n  WriteLine(\"Your password is too short. Use at least 8 chars.\"); \nelse\n  WriteLine(\"Your password is strong.\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This style of&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;statement should be avoided because it can introduce serious bugs. An infamous example is the #gotofail bug in Apple's iPhone iOS operating system. For 18 months after Apple's iOS 6 was released, in September 2012, it had a bug due to an <code class=\"calibre9\">if<\/code> statement without braces in its&nbsp;<strong class=\"calibre2\">Secure Sockets Layer<\/strong>&nbsp;(<strong class=\"calibre2\">SSL<\/strong>) encryption code. This meant that any user running Safari, the device's web browser, who tried to&nbsp;connect to secure websites, such as their bank, was not properly secure because an important check was being accidentally skipped.Just because you can leave out the curly braces, doesn't mean you should. Your code is not \"more efficient\" without them; instead, it is harder to read, less maintainable, and potentially more dangerous.<\/p>\n<\/section>\n<section data-number=\"4.3.3\" id=\"calibre_link-153\">\n<h3 data-number=\"4.3.3\" class=\"calibre8\">Pattern matching with the if statement<\/h3>\n<p class=\"rights\">A feature introduced with C# 7 and later is pattern matching. The&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;statement can use the&nbsp;<code class=\"calibre9\">is<\/code>&nbsp;keyword in combination with&nbsp;declaring a local variable to make your code safer:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements so that if the value stored in the variable named&nbsp;<code class=\"calibre9\">o<\/code>&nbsp;is an&nbsp;<code class=\"calibre9\">int<\/code>, then the value is assigned to the local variable named&nbsp;<code class=\"calibre9\">i<\/code>, which can then be used inside the&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;statement. This is safer than using the variable named&nbsp;<code class=\"calibre9\">o<\/code>&nbsp;because we know for sure that&nbsp;<code class=\"calibre9\">i<\/code>&nbsp;is an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;variable and not something else, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Add and remove the \"\" to change between string and int.\nobject o = \"3\"; \nint j = 4;\nif (o is int i)\n{\n  WriteLine($\"{i} x {j} = {i * j}\");\n}\nelse\n{\n  WriteLine(\"o is not an int so it cannot multiply!\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">o is not an int so it cannot multiply!<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Delete the double-quote characters around the&nbsp;<code class=\"calibre9\">\"3\"<\/code>&nbsp;value so that the value stored in the variable named&nbsp;<code class=\"calibre9\">o<\/code>&nbsp;is an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;type instead of a&nbsp;<code class=\"calibre9\">string<\/code>&nbsp;type.<\/li>\n<li class=\"calibre3\">Rerun the code to view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">3 x 4 = 12<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.3.4\" id=\"calibre_link-154\">\n<h3 data-number=\"4.3.4\" class=\"calibre8\">Branching with the switch statement<\/h3>\n<p class=\"rights\">The&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;statement is different from the&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;statement because&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;compares a single expression against a list&nbsp;of multiple possible&nbsp;<code class=\"calibre9\">case<\/code>&nbsp;statements. Every&nbsp;<code class=\"calibre9\">case<\/code>&nbsp;statement is related to the single expression. Every&nbsp;<code class=\"calibre9\">case<\/code>&nbsp;section must end with one of the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The&nbsp;<code class=\"calibre9\">break<\/code>&nbsp;keyword (like <code class=\"calibre9\">case 1<\/code> in the following code).<\/li>\n<li class=\"calibre3\">The&nbsp;<code class=\"calibre9\">goto<\/code>&nbsp;<code class=\"calibre9\">case<\/code>&nbsp;keywords (like <code class=\"calibre9\">case 2<\/code> in the following code).<\/li>\n<li class=\"calibre3\">They should have no statements (like <code class=\"calibre9\">case 3<\/code> in the following code).<\/li>\n<li class=\"calibre3\">The&nbsp;<code class=\"calibre9\">goto<\/code>&nbsp;keyword that references a named label (like <code class=\"calibre9\">case 5<\/code> in the following code).<\/li>\n<li class=\"calibre3\">The&nbsp;<code class=\"calibre9\">return<\/code>&nbsp;keyword to leave the current function (not shown in the code).<\/li>\n<\/ul>\n<p class=\"rights\">Let's write some code to explore the&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;statements:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type the following code for a&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;statement. You should note that the penultimate statement is a label that can be jumped to, and the first statement generates a random number between 1 and 6 (the number 7 in the code is an exclusive upper bound). The&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;statement branches are based on the value of this random number, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Inclusive lower bound but exclusive upper bound.\nint number = Random.Shared.Next(minValue: 1, maxValue: 7);\nWriteLine($\"My random number is {number}\");\nswitch (number)\n{\n  case 1: \n    WriteLine(\"One\");\n    break; \/\/ Jumps to end of switch statement.\n  case 2:\n    WriteLine(\"Two\");\n    goto case 1;\n  case 3: \/\/ Multiple case section.\n  case 4:\n    WriteLine(\"Three or four\");\n    goto case 1;\n  case 5:\n    goto A_label;\n  default:\n    WriteLine(\"Default\");\n    break;\n} \/\/ End of switch statement.\nWriteLine(\"After end of switch\");\nA_label:\nWriteLine($\"After A_label\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You can use the&nbsp;<code class=\"calibre9\">goto<\/code>&nbsp;keyword to jump to another case or a label. The&nbsp;<code class=\"calibre9\">goto<\/code>&nbsp;keyword is frowned upon by most programmers but can be a good solution to code logic in some scenarios. However, you should use it sparingly, if at all. To see how often Microsoft uses <code class=\"calibre9\">goto<\/code> in the .NET base class libraries, use the following link: <a href=\"https:\/\/github.com\/search?q=%22goto%20%22+repo%3Adotnet%2Fruntime+language%3AC%23&amp;type=code&amp;ref=advsearch\">https:\/\/github.com\/search?q=%22goto%20%22+repo%3Adotnet%2Fruntime+language%3AC%23&amp;type=code&amp;ref=advsearch<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code multiple&nbsp;times to see what happens in various cases of random numbers, as shown in the following example output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ First random run.\nMy random number is 4 \nThree or four\nOne\nAfter end of switch\nAfter A_label\n\/\/ Second random run.\nMy random number is 2 \nTwo\nOne\nAfter end of switch\nAfter A_label\n\/\/ Third random run.\nMy random number is 6\nDefault\nAfter end of switch\nAfter A_label\n\/\/ Fourth random run.\nMy random number is 1 \nOne\nAfter end of switch\nAfter A_label\n\/\/ Fifth random run.\nMy random number is 5\nAfter A_label<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: The <code class=\"calibre9\">Random<\/code> class that we used to generate a random number has a <code class=\"calibre9\">Next<\/code> method that allows you to specify an inclusive lower bound and an exclusive upper bound and will generate a pseudo-random number. Instead of creating a new instance of <code class=\"calibre9\">Random<\/code> that is not thread-safe, since .NET 6 you can use a <code class=\"calibre9\">Shared<\/code> instance that is thread-safe so it can be used concurrently from any thread.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.3.5\" id=\"calibre_link-155\">\n<h3 data-number=\"4.3.5\" class=\"calibre8\">Adding a new item to a project using Visual Studio 2022<\/h3>\n<p class=\"rights\">Visual Studio 2022 version 17.6 or later has an optional simplified dialog box for adding a new item to a project. After navigating to <strong class=\"calibre2\">Project<\/strong> | <strong class=\"calibre2\">Add New Item\u2026<\/strong>, or right-clicking on a project in <strong class=\"calibre2\">Solution Explorer<\/strong> and selecting <strong class=\"calibre2\">Add<\/strong> | <strong class=\"calibre2\">New Item\u2026<\/strong>, you will see the traditional dialog box, as shown in <em class=\"calibre10\">Figure 3.1<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 3.1: Add New Item dialog box in normal view\" height=\"617\" src=\"\/images\/cs12\/000012.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 3.1: Add New Item dialog box in normal view<\/figcaption><\/figure>\n<p class=\"rights\">If you click the <strong class=\"calibre2\">Show Compact View<\/strong> button, then it switches to a simplified dialog box, as shown in <em class=\"calibre10\">Figure 3.2<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 3.2: Add New Item dialog box in compact view\" height=\"637\" src=\"\/images\/cs12\/000029.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 3.2: Add New Item dialog box in compact view<\/figcaption><\/figure>\n<p class=\"rights\">To revert to the normal dialog box, click the <strong class=\"calibre2\">Show All Templates<\/strong> button.<\/p>\n<\/section>\n<section data-number=\"4.3.6\" id=\"calibre_link-156\">\n<h3 data-number=\"4.3.6\" class=\"calibre8\">Pattern matching with the switch statement<\/h3>\n<p class=\"rights\">Like the&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;statement, the&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;statement supports pattern matching in C# 7 and later. The&nbsp;<code class=\"calibre9\">case<\/code>&nbsp;values no longer&nbsp;need to be literal values; they can be patterns.In C# 7 and later, your code can more concisely branch, based on the subtype of a class, and you can declare and assign a local variable to safely use it. Additionally,&nbsp;<code class=\"calibre9\">case<\/code>&nbsp;statements can include a&nbsp;<code class=\"calibre9\">when<\/code>&nbsp;keyword to perform more specific pattern matching.Let's see an example of pattern matching with the&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;statement using a custom class hierarchy of animals with different properties:<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You will learn more details about defining classes in <em class=\"calibre10\">Chapter 5<\/em>, <em class=\"calibre10\">Building Your Own Types with Object-Oriented Programming<\/em>. For now, you should be able to get the idea from reading the code.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">SelectionStatements<\/code> project, add a new class file named <code class=\"calibre9\">Animals.cs<\/code>:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">In Visual Studio 2022, navigate to <strong class=\"calibre2\">Project<\/strong> | <strong class=\"calibre2\">Add New Item\u2026<\/strong> or press <span>Ctrl<\/span> + <span>Shift<\/span> + <span>A<\/span>, type the name, and then click <strong class=\"calibre2\">Add<\/strong>.<\/li>\n<li class=\"calibre3\">In Visual Studio Code, click the <strong class=\"calibre2\">New File\u2026<\/strong> button and type the name.<\/li>\n<li class=\"calibre3\">In JetBrains Rider, right-click on the project and select <strong class=\"calibre2\">Add<\/strong> | <strong class=\"calibre2\">Class\/Interface\u2026<\/strong>.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Animals.cs<\/code>, delete any existing statements, and then define three classes, a base class, <code class=\"calibre9\">Animal<\/code>, and two inherited classes, <code class=\"calibre9\">Cat<\/code> and <code class=\"calibre9\">Spider<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">class Animal \/\/ This is the base type for all animals.\n{\n  public string? Name;\n  public DateTime Born;\n  public byte Legs;\n}\nclass Cat : Animal \/\/ This is a subtype of animal.\n{\n  public bool IsDomestic;\n}\nclass Spider : Animal \/\/ This is another subtype of animal.\n{\n  public bool IsPoisonous;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to declare an array of nullable animals, and then show a message based on what type and attributes each animal has, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var animals = new Animal?[]\n{\n  new Cat { Name = \"Karen\", Born = new(year: 2022, month: 8,\n    day: 23), Legs = 4, IsDomestic = true },\n  null,\n  new Cat { Name = \"Mufasa\", Born = new(year: 1994, month: 6,\n    day: 12) },\n  new Spider { Name = \"Sid Vicious\", Born = DateTime.Today, \n    IsPoisonous = true},\n  new Spider { Name = \"Captain Furry\", Born = DateTime.Today }\n};\nforeach (Animal? animal in animals)\n{\n  string message;\n  switch (animal)\n  {\n    case Cat fourLeggedCat when fourLeggedCat.Legs == 4:\n      message = $\"The cat named {fourLeggedCat.Name} has four legs.\";\n      break;\n    case Cat wildCat when wildCat.IsDomestic == false:\n      message = $\"The non-domestic cat is named {wildCat.Name}.\";\n      break;\n    case Cat cat:\n      message = $\"The cat is named {cat.Name}.\";\n      break;\n    default: \/\/ default is always evaluated last.\n      message = $\"{animal.Name} is a {animal.GetType().Name}.\";\n      break;\n    case Spider spider when spider.IsPoisonous:\n      message = $\"The {spider.Name} spider is poisonous. Run!\";\n      break;\n    case null:\n      message = \"The animal is null.\";\n      break;\n  }\n  WriteLine($\"switch statement: {message}\");\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">case<\/code> statement shown in the following code:<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">case Cat fourLeggedCat when fourLeggedCat.Legs == 4:<\/code><\/p>\n<\/blockquote>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Can also be written using the more concise property pattern-matching syntax, as shown in the following code:<\/p>\n<\/blockquote>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">case Cat { Legs: 4 } fourLeggedCat:<\/code><\/p>\n<\/blockquote>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note that the array named&nbsp;<code class=\"calibre9\">animals<\/code>&nbsp;is declared to contain the&nbsp;<code class=\"calibre9\">Animal?<\/code>&nbsp;type, so it could be any subtype of <code class=\"calibre9\">Animal<\/code>, such as&nbsp;a <code class=\"calibre9\">Cat<\/code> or a <code class=\"calibre9\">Spider<\/code>, or a <code class=\"calibre9\">null<\/code> value. In this code, we create four instances of <code class=\"calibre9\">Animal<\/code> of different types with different properties, and one <code class=\"calibre9\">null<\/code> one, so the result will be five messages that describe each of the animals, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">switch statement: The cat named Karen has four legs.\nswitch statement: The animal is null.\nswitch statement: The non-domestic cat is named Mufasa.\nswitch statement: The Sid Vicious spider is poisonous. Run!\nswitch statement: Captain Furry is a Spider.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.3.7\" id=\"calibre_link-157\">\n<h3 data-number=\"4.3.7\" class=\"calibre8\">Simplifying switch statements with switch expressions<\/h3>\n<p class=\"rights\">In C# 8 or later, you can simplify&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;statements using&nbsp;<strong class=\"calibre2\">switch expressions<\/strong>.Most&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;statements&nbsp;are very simple, yet they require a lot of typing.&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;expressions are designed to simplify the code you need to type while still expressing the same intent in scenarios where all cases return a value to set a single variable.&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;expressions use a lambda,&nbsp;<code class=\"calibre9\">=&gt;<\/code>, to indicate a return value.Let's implement the previous code that used a&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;statement using a&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;expression so that you can compare the two styles:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, at the bottom and inside the <code class=\"calibre9\">foreach<\/code> loop, add statements to set the message based on what type and attributes the animal has, using a&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;expression, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">message = animal switch\n{\n  Cat fourLeggedCat when fourLeggedCat.Legs == 4\n    =&gt; $\"The cat named {fourLeggedCat.Name} has four legs.\",\n  Cat wildCat when wildCat.IsDomestic == false\n    =&gt; $\"The non-domestic cat is named {wildCat.Name}.\",\n  Cat cat\n    =&gt; $\"The cat is named {cat.Name}.\",\n  Spider spider when spider.IsPoisonous\n    =&gt; $\"The {spider.Name} spider is poisonous. Run!\",\n  null\n    =&gt; \"The animal is null.\",\n  _\n    =&gt; $\"{animal.Name} is a {animal.GetType().Name}.\"\n};\nWriteLine($\"switch expression: {message}\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The main differences&nbsp;are the removal of the&nbsp;<code class=\"calibre9\">case<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">break<\/code>&nbsp;keywords. The underscore character&nbsp;<code class=\"calibre9\">_<\/code>&nbsp;is used to represent the default return value. It is known as a <strong class=\"calibre2\">discard<\/strong> and you can read more about it at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/fundamentals\/functional\/discards\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/fundamentals\/functional\/discards<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, and note that the result is the same as before, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">switch statement: The cat named Karen has four legs.\nswitch expression: The cat named Karen has four legs.\nswitch statement: The animal is null.\nswitch expression: The animal is null.\nswitch statement: The non-domestic cat is named Mufasa.\nswitch expression: The non-domestic cat is named Mufasa.\nswitch statement: The Sid Vicious spider is poisonous. Run!\nswitch expression: The Sid Vicious spider is poisonous. Run!\nswitch statement: Captain Furry is a Spider.\nswitch expression: Captain Furry is a Spider.<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"4.4\" id=\"calibre_link-158\">\n<h2 data-number=\"4.4\" class=\"calibre5\">Understanding iteration statements<\/h2>\n<p class=\"rights\">Iteration statements repeat a block of statements either while a condition is <code class=\"calibre9\">true<\/code> (<code class=\"calibre9\">while<\/code> and <code class=\"calibre9\">for<\/code> statements) or for each item in a collection (<code class=\"calibre9\">foreach<\/code> statement). The choice of&nbsp;which statement to use is based on a combination of ease of understanding to solve the logic problem and personal preference.<\/p>\n<section data-number=\"4.4.1\" id=\"calibre_link-159\">\n<h3 data-number=\"4.4.1\" class=\"calibre8\">Looping with the while statement<\/h3>\n<p class=\"rights\">The&nbsp;<code class=\"calibre9\">while<\/code>&nbsp;statement&nbsp;evaluates a Boolean expression and continues to loop while it is true. Let's explore iteration statements:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new&nbsp;<strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named&nbsp;<code class=\"calibre9\">IterationStatements<\/code> to the&nbsp;<code class=\"calibre9\">Chapter03<\/code>&nbsp;solution.<\/li>\n<li class=\"calibre3\">In&nbsp;<code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then add statements to define a&nbsp;<code class=\"calibre9\">while<\/code>&nbsp;statement that loops while an integer variable has a value less than 10, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int x = 0;\nwhile (x &lt; 10)\n{\n  WriteLine(x);\n  x++;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the results, which should be the numbers 0 to 9, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">0\n1\n2\n3\n4\n5\n6\n7\n8\n9<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.4.2\" id=\"calibre_link-160\">\n<h3 data-number=\"4.4.2\" class=\"calibre8\">Looping with the do statement<\/h3>\n<p class=\"rights\">The&nbsp;<code class=\"calibre9\">do<\/code>&nbsp;statement is like&nbsp;<code class=\"calibre9\">while<\/code>, except the Boolean expression is checked at the bottom of the block instead of the top, which&nbsp;means that the block always executes at least once, as the following shows:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type statements to define a&nbsp;<code class=\"calibre9\">do<\/code>&nbsp;loop, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string? actualPassword = \"Pa$$w0rd\";\nstring? password;\ndo\n{\n  Write(\"Enter your password: \"); \n  password = ReadLine();\n}\nwhile (password != actualPassword);\nWriteLine(\"Correct!\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, and note that you are prompted to enter your password repeatedly until you enter it correctly, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter your password: password \nEnter your password: 12345678 \nEnter your password: ninja\nEnter your password: correct horse battery staple \nEnter your password: Pa$$w0rd\nCorrect!<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">As an optional challenge, add statements so that the user can only make three attempts before an error message is displayed.<\/li>\n<li class=\"calibre3\">At this point, you might want to comment out the code for this section so you do not have to keep entering a password every time you run the console app!<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"4.4.3\" id=\"calibre_link-161\">\n<h3 data-number=\"4.4.3\" class=\"calibre8\">Looping with the for statement<\/h3>\n<p class=\"rights\">The&nbsp;<code class=\"calibre9\">for<\/code>&nbsp;statement is&nbsp;like&nbsp;<code class=\"calibre9\">while<\/code>, except that it is more succinct. It combines:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">An optional&nbsp;<strong class=\"calibre2\">initializer expression<\/strong>, which executes once at the start of the loop.<\/li>\n<li class=\"calibre3\">An&nbsp;optional&nbsp;<strong class=\"calibre2\">conditional expression<\/strong>, which executes on every iteration at the start of the loop to check whether the looping should continue. If the expression returns <code class=\"calibre9\">true<\/code> or it is missing, the loop will execute again.<\/li>\n<li class=\"calibre3\">An&nbsp;optional <strong class=\"calibre2\">iterator expression<\/strong>, which executes on every loop at the bottom of the statement. This is often used to increment a counter variable.<\/li>\n<\/ul>\n<p class=\"rights\">The&nbsp;<code class=\"calibre9\">for<\/code>&nbsp;statement is commonly used with an integer counter. Let's explore some code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type a&nbsp;<code class=\"calibre9\">for<\/code>&nbsp;statement to output the numbers 1 to 10, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">for (int y = 1; y &lt;= 10; y++)\n{\n  WriteLine(y);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code to view the result, which should be the numbers 1 to 10.<\/li>\n<li class=\"calibre3\">Add another&nbsp;<code class=\"calibre9\">for<\/code>&nbsp;statement to output the numbers 0 to 10, incrementing by 3, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">for (int y = 0; y &lt;= 10; y += 3)\n{\n  WriteLine(y);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code to view the result, which should be the numbers 0, 3, 6, and 9.<\/li>\n<li class=\"calibre3\">Optionally, experiment with changing the initializer expression, conditional expression, or iterator expression to see their effects. Only change one thing at a time so that you can clearly see the effect produced.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"4.4.4\" id=\"calibre_link-162\">\n<h3 data-number=\"4.4.4\" class=\"calibre8\">Looping with the foreach statement<\/h3>\n<p class=\"rights\">The&nbsp;<code class=\"calibre9\">foreach<\/code>&nbsp;statement is a bit&nbsp;different from the previous three iteration statements.It is used to perform a block of statements on each item in a sequence, for example, an array or collection. Each item is usually read-only, and if the sequence structure is modified during iteration, for example, by adding or removing an item, then an exception will be thrown.Try the following example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type statements to&nbsp;create an array of string variables and then output the length of each one, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string[] names = { \"Adam\", \"Barry\", \"Charlie\" };\nforeach (string name in names)\n{\n  WriteLine($\"{name} has {name.Length} characters.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Adam has 4 characters. \nBarry has 5 characters. \nCharlie has 7 characters. <\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.4.5\" id=\"calibre_link-163\">\n<h3 data-number=\"4.4.5\" class=\"calibre8\">Understanding how foreach works internally<\/h3>\n<p class=\"rights\">A developer who defines a type that represents multiple items, like an array or collection, should make sure that a programmer can use the&nbsp;<code class=\"calibre9\">foreach<\/code>&nbsp;statement to enumerate through the type's items.Technically, the&nbsp;<code class=\"calibre9\">foreach<\/code>&nbsp;statement will work on any type that follows these rules:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The type must have a method named&nbsp;<code class=\"calibre9\">GetEnumerator<\/code>&nbsp;that returns an object.<\/li>\n<li class=\"calibre3\">The returned object must have a property named&nbsp;<code class=\"calibre9\">Current<\/code>&nbsp;and a method named&nbsp;<code class=\"calibre9\">MoveNext<\/code>.<\/li>\n<li class=\"calibre3\">The&nbsp;<code class=\"calibre9\">MoveNext<\/code>&nbsp;method must change the value of&nbsp;<code class=\"calibre9\">Current<\/code>&nbsp;and return&nbsp;<code class=\"calibre9\">true<\/code>&nbsp;if there are more items to enumerate through or return&nbsp;<code class=\"calibre9\">false<\/code>&nbsp;if there are no more items.<\/li>\n<\/ul>\n<p class=\"rights\">There are interfaces named&nbsp;<code class=\"calibre9\">IEnumerable<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code>&nbsp;that formally define these rules, but technically the compiler does&nbsp;not require the type to implement these interfaces.The compiler turns the&nbsp;<code class=\"calibre9\">foreach<\/code>&nbsp;statement in the preceding example into something like the following pseudocode:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">IEnumerator e = names.GetEnumerator();\nwhile (e.MoveNext())\n{\n  string name = (string)e.Current; \/\/ Current is read-only!\n  WriteLine($\"{name} has {name.Length} characters.\");\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Due to the use of an iterator and its read-only <code class=\"calibre9\">Current<\/code> property, the variable declared in a&nbsp;<code class=\"calibre9\">foreach<\/code>&nbsp;statement cannot be used to modify the value of the current item.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"4.5\" id=\"calibre_link-164\">\n<h2 data-number=\"4.5\" class=\"calibre5\">Storing multiple values in an array<\/h2>\n<p class=\"rights\">When you need to store multiple values of the same type, you can declare an <strong class=\"calibre2\">array<\/strong>. For example, you may do this when you need to store four names in a <code class=\"calibre9\">string<\/code> array.<\/p>\n<section data-number=\"4.5.1\" id=\"calibre_link-165\">\n<h3 data-number=\"4.5.1\" class=\"calibre8\">Working with single-dimensional arrays<\/h3>\n<p class=\"rights\">The code that you will write next will allocate memory for an array for storing four <code class=\"calibre9\">string<\/code> values. It will then store <code class=\"calibre9\">string<\/code> values at index positions 0 to 3 (arrays usually have a lower bound of zero, so the index of the last item is one less than the length of the array).We could visualize the array like this:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">0<\/td>\n<td class=\"calibre21\">1<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">3<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Kate<\/td>\n<td class=\"calibre21\">Jack<\/td>\n<td class=\"calibre21\">Rebecca<\/td>\n<td class=\"calibre21\">Tom<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 3.1: Visualization of an array of four string values<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Do not assume that all arrays count from zero. The most common type of array in .NET is an <strong class=\"calibre2\">szArray<\/strong>, a single-dimension zero-indexed array, and these use the normal <code class=\"calibre9\">[]<\/code> syntax. But .NET also has <strong class=\"calibre2\">mdArray<\/strong>, a multi-dimensional array, and they do not have to have a lower bound of zero. These are rarely used, but you should know they exist.<\/p>\n<\/blockquote>\n<p class=\"rights\">Finally, it will loop through each item in the array using a <code class=\"calibre9\">for<\/code> statement.Let's look at how to use an array:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">Arrays<\/code> to the <code class=\"calibre9\">Chapter03<\/code> solution.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then type statements to declare and use an array of <code class=\"calibre9\">string<\/code> values, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string[] names; \/\/ This can reference any size array of strings.\n\/\/ Allocate memory for four strings in an array.\nnames = new string[4];\n\/\/ Store items at these index positions.\nnames[0] = \"Kate\";\nnames[1] = \"Jack\"; \nnames[2] = \"Rebecca\"; \nnames[3] = \"Tom\";\n\/\/ Loop through the names.\nfor (int i = 0; i &lt; names.Length; i++)\n{\n  \/\/ Output the item at index position i.\n  WriteLine($\"{names[i]} is at position {i}.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Kate is at position 0.\nJack is at position 1.\nRebecca is at position 2.\nTom is at position 3.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Arrays are always of a fixed size at the time of memory allocation, so you need to decide how many items you want to store before instantiating them.An alternative to defining the array in three steps as above is to use array initializer syntax:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Before the <code class=\"calibre9\">for<\/code> loop, add a statement to declare, allocate memory, and instantiate the values of a similar array, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Alternative syntax for creating and initializing an array.\nstring[] names2 = { \"Kate\", \"Jack\", \"Rebecca\", \"Tom\" };<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Change the <code class=\"calibre9\">for<\/code> loop to use <code class=\"calibre9\">names2<\/code>, run the console app, and note that the results are the same.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"4.5.2\" id=\"calibre_link-166\">\n<h3 data-number=\"4.5.2\" class=\"calibre8\">Working with multi-dimensional arrays<\/h3>\n<p class=\"rights\">Instead of a single-dimension array for storing a row of string values (or any other data type), what if we want to store a grid of values? Or a cube? Or even higher dimensions?We could visualize a two-dimensional array, aka grid, of <code class=\"calibre9\">string<\/code> values like this:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\">0<\/td>\n<td class=\"calibre21\">1<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">3<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">0<\/td>\n<td class=\"calibre21\">Alpha<\/td>\n<td class=\"calibre21\">Beta<\/td>\n<td class=\"calibre21\">Gamma<\/td>\n<td class=\"calibre21\">Delta<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">1<\/td>\n<td class=\"calibre21\">Anne<\/td>\n<td class=\"calibre21\">Ben<\/td>\n<td class=\"calibre21\">Charlie<\/td>\n<td class=\"calibre21\">Doug<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">Aardvark<\/td>\n<td class=\"calibre21\">Bear<\/td>\n<td class=\"calibre21\">Cat<\/td>\n<td class=\"calibre21\">Dog<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 3.2: Visualization of a two-dimensional array<\/p>\n<p class=\"rights\">Let's look at how to use multi-dimensional arrays:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of <code class=\"calibre9\">Program.cs<\/code>, add statements to declare and instantiate a two-dimensional array of <code class=\"calibre9\">string<\/code> values, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string[,] grid1 = \/\/ Two dimensional array.\n{\n  { \"Alpha\", \"Beta\", \"Gamma\", \"Delta\" },\n  { \"Anne\", \"Ben\", \"Charlie\", \"Doug\" },\n  { \"Aardvark\", \"Bear\", \"Cat\", \"Dog\" }\n};<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">We can discover the lower and upper bounds of this array using helpful methods, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine($\"1st dimension, lower bound: {grid1.GetLowerBound(0)}\");\nWriteLine($\"1st dimension, upper bound: {grid1.GetUpperBound(0)}\");\nWriteLine($\"2nd dimension, lower bound: {grid1.GetLowerBound(1)}\");\nWriteLine($\"2nd dimension, upper bound: {grid1.GetUpperBound(1)}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">1st dimension, lower bound: 0\n1st dimension, upper bound: 2\n2nd dimension, lower bound: 0\n2nd dimension, upper bound: 3<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">We can then use these values in nested <code class=\"calibre9\">for<\/code> statements to loop through the <code class=\"calibre9\">string<\/code> values, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">for (int row = 0; row &lt;= grid1.GetUpperBound(0); row++)\n{\n  for (int col = 0; col &lt;= grid1.GetUpperBound(1); col++)\n  {\n    WriteLine($\"Row {row}, Column {col}: {grid1[row, col]}\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Row 0, Column 0: Alpha\nRow 0, Column 1: Beta\nRow 0, Column 2: Gamma\nRow 0, Column 3: Delta\nRow 1, Column 0: Anne\nRow 1, Column 1: Ben\nRow 1, Column 2: Charlie\nRow 1, Column 3: Doug\nRow 2, Column 0: Aardvark\nRow 2, Column 1: Bear\nRow 2, Column 2: Cat\nRow 2, Column 3: Dog<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You must supply a value for every row and every column when it is instantiated, or you will get compile errors. If you need to indicate a missing <code class=\"calibre9\">string<\/code> value, then use <code class=\"calibre9\">string.Empty<\/code>. Or if you declare the array to be nullable <code class=\"calibre9\">string<\/code> values by using <code class=\"calibre9\">string?[]<\/code>, then you can also use <code class=\"calibre9\">null<\/code> for a missing value. If you cannot use the array initialization syntax, perhaps because you are loading values from a file or database, then you can separate the declaration of the array dimension and the allocation of memory from the assigning of values, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Alternative syntax for declaring and allocating memory\n\/\/ for a multi-dimensional array.\nstring[,] grid2 = new string[3,4]; \/\/ Allocate memory.\ngrid2[0, 0] = \"Alpha\"; \/\/ Assign values.\ngrid2[0, 1] = \"Beta\";\n\/\/ And so on.\ngrid2[2, 3] = \"Dog\";<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When declaring the size of the dimensions, you specify the length, not the upper bound. The expression <code class=\"calibre9\">new string[3,4]<\/code> means the array can have 3 items in its first dimension (0) with an upper bound of 2, and the array can have 4 items in its second dimension (1) with an upper bound of 3.<\/p>\n<\/section>\n<section data-number=\"4.5.3\" id=\"calibre_link-167\">\n<h3 data-number=\"4.5.3\" class=\"calibre8\">Working with jagged arrays<\/h3>\n<p class=\"rights\">If you need a multi-dimensional array but the number of items stored in each dimension is different, then you can define an array of arrays, aka a jagged array. We could visualize a jagged array as shown in <em class=\"calibre10\">Figure 3.3<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 3.3: Visualization of a jagged array\" height=\"504\" src=\"\/images\/cs12\/000047.png\" width=\"1431\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 3.3: Visualization of a jagged array<\/figcaption><\/figure>\n<p class=\"rights\">Let's look at how to use a jagged array:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of <code class=\"calibre9\">Program.cs<\/code>, add statements to declare and instantiate an array of arrays of <code class=\"calibre9\">string<\/code> values, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string[][] jagged = \/\/ An array of string arrays.\n{\n  new[] { \"Alpha\", \"Beta\", \"Gamma\" },\n  new[] { \"Anne\", \"Ben\", \"Charlie\", \"Doug\" },\n  new[] { \"Aardvark\", \"Bear\" }\n};<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">We can discover the lower and upper bounds of the array of arrays, and then each array with it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(\"Upper bound of the array of arrays is: {0}\",\n  jagged.GetUpperBound(0));\nfor (int array = 0; array &lt;= jagged.GetUpperBound(0); array++)\n{\n  WriteLine(\"Upper bound of array {0} is: {1}\",\n    arg0: array,\n    arg1: jagged[array].GetUpperBound(0));\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Upper bound of the array of arrays is: 2\nUpper bound of array 0 is: 2\nUpper bound of array 1 is: 3\nUpper bound of array 2 is: 1<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">We can then use these values in nested <code class=\"calibre9\">for<\/code> statements to loop through the <code class=\"calibre9\">string<\/code> values, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">for (int row = 0; row &lt;= jagged.GetUpperBound(0); row++)\n{\n  for (int col = 0; col &lt;= jagged[row].GetUpperBound(0); col++)\n  {\n    WriteLine($\"Row {row}, Column {col}: {jagged[row][col]}\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Row 0, Column 0: Alpha\nRow 0, Column 1: Beta\nRow 0, Column 2: Gamma\nRow 1, Column 0: Anne\nRow 1, Column 1: Ben\nRow 1, Column 2: Charlie\nRow 1, Column 3: Doug\nRow 2, Column 0: Aardvark\nRow 2, Column 1: Bear<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.5.4\" id=\"calibre_link-168\">\n<h3 data-number=\"4.5.4\" class=\"calibre8\">List pattern matching with arrays<\/h3>\n<p class=\"rights\">Earlier in this chapter, you saw how an individual object supports pattern matching against its type and properties. Pattern matching also works with arrays and collections.Introduced with C# 11, list pattern matching works with any type that has a public <code class=\"calibre9\">Length<\/code> or <code class=\"calibre9\">Count<\/code> property and has an indexer using an <code class=\"calibre9\">int<\/code> or <code class=\"calibre9\">System.Index<\/code> parameter. You will learn about indexers in <em class=\"calibre10\">Chapter 5<\/em>, <em class=\"calibre10\">Building Your Own Types with Object-Oriented Programming<\/em>.When you define multiple list patterns in the same <code class=\"calibre9\">switch<\/code> expression, you must order them so that the more specific one comes first, or the compiler will complain because a more general pattern will match all the more specific patterns too and make the more specific one unreachable.<em class=\"calibre10\">Table 3.3<\/em> shows examples of list pattern matching, assuming a list of <code class=\"calibre9\">int<\/code> values:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre19\"><\/col>\n<col class=\"calibre19\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Example<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[]<\/code><\/td>\n<td class=\"calibre21\">Matches an empty array or collection.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[..]<\/code><\/td>\n<td class=\"calibre21\">Matches an array or collection with any number of items, including zero, so <code class=\"calibre9\">[..]<\/code> must come after <code class=\"calibre9\">[]<\/code> if you need to switch on both.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[_]<\/code><\/td>\n<td class=\"calibre21\">Matches a list with any single item.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><code class=\"calibre9\">[int item1]<\/code> or<\/p>\n<p class=\"rights\"><code class=\"calibre9\">[var item1]<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">Matches a list with any single item and can use the value in the return expression by referring to <code class=\"calibre9\">item1<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[7, 2]<\/code><\/td>\n<td class=\"calibre21\">Matches exactly a list of two items with those values in that order.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[_, _]<\/code><\/td>\n<td class=\"calibre21\">Matches a list with any two items.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[var item1, var item2]<\/code><\/td>\n<td class=\"calibre21\">Matches a list with any two items and can use the values in the return expression by referring to <code class=\"calibre9\">item1<\/code> and <code class=\"calibre9\">item2<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[_, _, _]<\/code><\/td>\n<td class=\"calibre21\">Matches a list with any three items.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[var item1, ..]<\/code><\/td>\n<td class=\"calibre21\">Matches a list with one or more items. Can refer to the value of the first item in its return expression by referring to <code class=\"calibre9\">item1<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[var firstItem, .., var lastItem]<\/code><\/td>\n<td class=\"calibre21\">Matches a list with two or more items. Can refer to the value of the first and last item in its return expression by referring to <code class=\"calibre9\">firstItem<\/code> and <code class=\"calibre9\">lastItem<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[.., var lastItem]<\/code><\/td>\n<td class=\"calibre21\">Matches a list with one or more items. Can refer to the value of the last item in its return expression by referring to <code class=\"calibre9\">lastItem<\/code> .<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 3.3: Examples of list pattern matching<\/p>\n<p class=\"rights\">Let's see some examples in code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of <code class=\"calibre9\">Program.cs<\/code>, add statements to define some arrays of <code class=\"calibre9\">int<\/code> values, and then pass them to a method that returns descriptive text depending on the pattern that matches best, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int[] sequentialNumbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\nint[] oneTwoNumbers = { 1, 2 };\nint[] oneTwoTenNumbers = { 1, 2, 10 };\nint[] oneTwoThreeTenNumbers = { 1, 2, 3, 10 };\nint[] primeNumbers = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };\nint[] fibonacciNumbers = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };\nint[] emptyNumbers = { }; \/\/ Or use Array.Empty&lt;int&gt;()\nint[] threeNumbers = { 9, 7, 5 };\nint[] sixNumbers = { 9, 7, 5, 4, 2, 10 };\nWriteLine($\"{nameof(sequentialNumbers)}: {CheckSwitch(sequentialNumbers)}\");\nWriteLine($\"{nameof(oneTwoNumbers)}: {CheckSwitch(oneTwoNumbers)}\");\nWriteLine($\"{nameof(oneTwoTenNumbers)}: {CheckSwitch(oneTwoTenNumbers)}\");\nWriteLine($\"{nameof(oneTwoThreeTenNumbers)}: {CheckSwitch(oneTwoThreeTenNumbers)}\");\nWriteLine($\"{nameof(primeNumbers)}: {CheckSwitch(primeNumbers)}\");\nWriteLine($\"{nameof(fibonacciNumbers)}: {CheckSwitch(fibonacciNumbers)}\");\nWriteLine($\"{nameof(emptyNumbers)}: {CheckSwitch(emptyNumbers)}\");\nWriteLine($\"{nameof(threeNumbers)}: {CheckSwitch(threeNumbers)}\");\nWriteLine($\"{nameof(sixNumbers)}: {CheckSwitch(sixNumbers)}\");\nstatic string CheckSwitch(int[] values) =&gt; values switch\n{\n  [] =&gt; \"Empty array\",\n  [1, 2, _, 10] =&gt; \"Contains 1, 2, any single number, 10.\",\n  [1, 2, .., 10] =&gt; \"Contains 1, 2, any range including empty, 10.\",\n  [1, 2] =&gt; \"Contains 1 then 2.\",\n  [int item1, int item2, int item3] =&gt; \n    $\"Contains {item1} then {item2} then {item3}.\",\n  [0, _] =&gt; \"Starts with 0, then one other number.\",\n  [0, ..] =&gt; \"Starts with 0, then any range of numbers.\",\n  [2, .. int[] others] =&gt; $\"Starts with 2, then {others.Length} more numbers.\",\n  [..] =&gt; \"Any items in any order.\",\n};<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">sequentialNumbers: Contains 1, 2, any range including empty, 10.\noneTwoNumbers: Contains 1 then 2.\noneTwoTenNumbers: Contains 1, 2, any range including empty, 10.\noneTwoThreeTenNumbers: Contains 1, 2, any single number, 10.\nprimeNumbers: Starts with 2, then 9 more numbers.\nfibonacciNumbers: Starts with 0, then any range of numbers.\nemptyNumbers: Empty array\nthreeNumbers: Contains 9 then 7 then 5.\nsixNumbers: Any items in any order.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can learn more about list pattern matching at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/operators\/patterns#list-patterns\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/operators\/patterns#list-patterns<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.5.5\" id=\"calibre_link-169\">\n<h3 data-number=\"4.5.5\" class=\"calibre8\">Understanding inline arrays<\/h3>\n<p class=\"rights\">Inline arrays were introduced with C# 12, and they are an advanced feature used by the .NET runtime team to improve performance. You are unlikely to use them yourself unless you are a public library author, but you will automatically benefit from others use of them.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about inline arrays at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/proposals\/csharp-12.0\/inline-arrays\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/proposals\/csharp-12.0\/inline-arrays<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.5.6\" id=\"calibre_link-170\">\n<h3 data-number=\"4.5.6\" class=\"calibre8\">Summarizing arrays<\/h3>\n<p class=\"rights\">We use slightly different syntax to declare different types of arrays, as shown in <em class=\"calibre10\">Table 3.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Type of array<\/td>\n<td class=\"calibre21\">Declaration syntax<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">One dimension<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">datatype[]<\/code> , for example, <code class=\"calibre9\">string[]<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Two dimensions<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">string[,]<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Three dimensions<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">string[,,]<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Ten dimensions<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">string[,,,,,,,,,]<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Array of arrays aka two-dimensional jagged array<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">string[][]<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Array of arrays of arrays aka three-dimensional jagged array<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">string[][][]<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 3.4: Summary of array declaration syntax<\/p>\n<p class=\"rights\">Arrays are useful for temporarily storing multiple items, but collections are a more flexible option when adding and removing items dynamically. You don't need to worry about collections right now, as we will cover them in <em class=\"calibre10\">Chapter 8<\/em>, <em class=\"calibre10\">Working with Common .NET Types<\/em>.You can convert any sequence of items into an array using the <code class=\"calibre9\">ToArray<\/code> extension method, which we will cover in <em class=\"calibre10\">Chapter 11<\/em>, <em class=\"calibre10\">Querying and Manipulating Data Using LINQ<\/em>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If you do not need to dynamically add and remove items, then you should use an array instead of a collection like <code class=\"calibre9\">List&lt;T&gt;<\/code> because arrays are more efficient in memory use and the items are stored contiguously, which can improve performance.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"4.6\" id=\"calibre_link-171\">\n<h2 data-number=\"4.6\" class=\"calibre5\">Casting and converting between types<\/h2>\n<p class=\"rights\">You will often need to convert values of variables between different types. For example, data input is often entered as text in the console, so it is initially stored in a variable of the&nbsp;<code class=\"calibre9\">string<\/code>&nbsp;type, but it then needs to be converted into a date\/time, number, or some other data type, depending on how it should be stored and processed.Sometimes you will need to convert between number types, like between an integer and a floating point, before performing calculations.Converting is also known as&nbsp;<strong class=\"calibre2\">casting<\/strong>, and it has&nbsp;two varieties:&nbsp;<strong class=\"calibre2\">implicit<\/strong>&nbsp;and&nbsp;<strong class=\"calibre2\">explicit<\/strong>. Implicit casting happens automatically, and it is&nbsp;safe, meaning that you will not lose any information.Explicit casting must be performed&nbsp;manually because it may lose information, for example, the precision of a number. By explicitly casting, you are telling the C# compiler that you understand and accept the risk.<\/p>\n<section data-number=\"4.6.1\" id=\"calibre_link-172\">\n<h3 data-number=\"4.6.1\" class=\"calibre8\">Casting numbers implicitly and explicitly<\/h3>\n<p class=\"rights\">Implicitly casting an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;variable into&nbsp;a&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;variable is safe because no information&nbsp;can be lost, as the following shows:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new&nbsp;<strong class=\"calibre2\">Console App<\/strong>&nbsp;\/ <code class=\"calibre9\">console<\/code> project named&nbsp;<code class=\"calibre9\">CastingConverting<\/code> to the&nbsp;<code class=\"calibre9\">Chapter03<\/code>&nbsp;solution.<\/li>\n<li class=\"calibre3\">In&nbsp;<code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, then type statements to declare and assign an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;variable and a&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;variable, and then implicitly cast the integer's value when assigning it to the&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;variable, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int a = 10;\ndouble b = a; \/\/ An int can be safely cast into a double.\nWriteLine($\"a is {a}, b is {b}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type statements to declare and assign a&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;variable and an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;variable, and then implicitly cast the&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;value when assigning it to the&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;variable, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">double c = 9.8;\nint d = c; \/\/ Compiler gives an error if you do not explicitly cast.\nWriteLine($\"c is {c}, d is {d}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the error message, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Error: (6,9): error CS0266: Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?)<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This error message will also appear in the Visual Studio <strong class=\"calibre2\">Error List<\/strong>, Visual Studio Code <strong class=\"calibre2\">PROBLEMS<\/strong> window, or JetBrains Rider <strong class=\"calibre2\">Problems<\/strong> window.You cannot implicitly cast a&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;variable into an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;variable because it is potentially unsafe and could lose data, like the value after the decimal point. You must explicitly cast a&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;variable into an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;variable using a pair of round brackets around the type you want to cast the&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;type into. The pair of round brackets is the&nbsp;<strong class=\"calibre2\">cast operator<\/strong>. Even then, you must beware that the part after the decimal point will be trimmed off without warning because you have chosen to perform an explicit cast and therefore understand the consequences.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the assignment statement for the&nbsp;<code class=\"calibre9\">d<\/code>&nbsp;variable to explicitly cast the variable <code class=\"calibre9\">c<\/code> into an <code class=\"calibre9\">int<\/code>, and add a comment to explain what will happen, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">double c = 9.8;\nint d = (int)c; \/\/ Compiler gives an error if you do not explicitly cast.\nWriteLine($\"c is {c}, d is {d}\"); \/\/ d loses the .8 part.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code to view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">a is 10, b is 10\nc is 9.8, d is 9<\/code><\/pre>\n<\/div>\n<p class=\"rights\">We must perform a similar operation when converting values between larger integers and smaller integers. Again, beware&nbsp;that you might lose information because&nbsp;any value too big will have its bits copied and then be interpreted in ways that you might not expect!<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Enter statements to declare and assign a <code class=\"calibre9\">long<\/code> (64-bit) integer variable to an <code class=\"calibre9\">int<\/code> (32-bit) integer variable, both using a small value that will work and a too-large value that will not, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">long e = 10; \nint f = (int)e;\nWriteLine($\"e is {e:N0}, f is {f:N0}\");\ne = long.MaxValue;\nf = (int)e;\nWriteLine($\"e is {e:N0}, f is {f:N0}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code to view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">e is 10, f is 10\ne is 9,223,372,036,854,775,807, f is -1<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the value of&nbsp;<code class=\"calibre9\">e<\/code>&nbsp;to 5 billion, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">e = 5_000_000_000;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code to view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">e is 5,000,000,000, f is 705,032,704<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Five billion cannot fit into a 32-bit integer, so it overflows (wraps around) to about 705 million. It is all to do with the binary representation of integer numbers. You will see more examples of integer overflow and how to handle it later in this chapter.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.6.2\" id=\"calibre_link-173\">\n<h3 data-number=\"4.6.2\" class=\"calibre8\">How negative numbers are represented in binary<\/h3>\n<p class=\"rights\">You might have wondered why <code class=\"calibre9\">f<\/code> had the value <code class=\"calibre9\">-1<\/code> in the previous code. Negative aka signed numbers use the first bit to represent negativity. If the bit is <code class=\"calibre9\">0<\/code> (zero), then it is a positive number. If the bit is <code class=\"calibre9\">1<\/code> (one), then it is a negative number.Let's write some code to illustrate this:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Enter statements to output the maximum value for an <code class=\"calibre9\">int<\/code> in decimal and binary number formats, then output the values 8 to -8, decrementing by one, and finally output the minimum value for an <code class=\"calibre9\">int<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(\"{0,12} {1,34}\", \"Decimal\", \"Binary\");\nWriteLine(\"{0,12} {0,34:B32}\", int.MaxValue);\nfor (int i = 8; i &gt;= -8; i--)\n{\n  WriteLine(\"{0,12} {0,34:B32}\", i);\n}\nWriteLine(\"{0,12} {0,34:B32}\", int.MinValue);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note <code class=\"calibre9\">,12<\/code> and <code class=\"calibre9\">,34<\/code> mean right-align within those column widths. <code class=\"calibre9\">:B32<\/code> means format as binary padded with leading zeros to a width of 32.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code to view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">     Decimal                             Binary\n  2147483647   01111111111111111111111111111111\n           8   00000000000000000000000000001000\n           7   00000000000000000000000000000111\n           6   00000000000000000000000000000110\n           5   00000000000000000000000000000101\n           4   00000000000000000000000000000100\n           3   00000000000000000000000000000011\n           2   00000000000000000000000000000010\n           1   00000000000000000000000000000001\n           0   00000000000000000000000000000000\n          -1   11111111111111111111111111111111\n          -2   11111111111111111111111111111110\n          -3   11111111111111111111111111111101\n          -4   11111111111111111111111111111100\n          -5   11111111111111111111111111111011\n          -6   11111111111111111111111111111010\n          -7   11111111111111111111111111111001\n          -8   11111111111111111111111111111000\n -2147483648   10000000000000000000000000000000<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note that all the positive binary number representations start with <code class=\"calibre9\">0<\/code> and all the negative binary number representations start with <code class=\"calibre9\">1<\/code>. The decimal value <code class=\"calibre9\">-1<\/code> is represented by all ones in binary. That is why when you have an integer too large to fit in a 32-bit integer, it becomes <code class=\"calibre9\">-1<\/code>.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: If you are interested in learning more about how signed numbers can be represented in computer systems, then you can read the following article: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Signed_number_representations\">https:\/\/en.wikipedia.org\/wiki\/Signed_number_representations<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.6.3\" id=\"calibre_link-174\">\n<h3 data-number=\"4.6.3\" class=\"calibre8\">Converting with the System.Convert type<\/h3>\n<p class=\"rights\">You can only cast between similar types, for example, between whole numbers like <code class=\"calibre9\">byte<\/code>, <code class=\"calibre9\">int<\/code>, and <code class=\"calibre9\">long<\/code>, or between a class and its subclasses. You cannot cast a <code class=\"calibre9\">long<\/code> to a <code class=\"calibre9\">string<\/code> or a <code class=\"calibre9\">byte<\/code> to a <code class=\"calibre9\">DateTime<\/code>.An alternative to using the cast operator is to use the&nbsp;<code class=\"calibre9\">System.Convert<\/code>&nbsp;type. The&nbsp;<code class=\"calibre9\">System.Convert<\/code>&nbsp;type can convert to and&nbsp;from all the C# number types, as well as Booleans, strings, and date and time values.Let's write some code to see this in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of&nbsp;<code class=\"calibre9\">Program.cs<\/code>, statically import the&nbsp;<code class=\"calibre9\">System.Convert<\/code>&nbsp;class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using static System.Convert; \/\/ To use the ToInt32 method.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Alternatively, add an entry to <code class=\"calibre9\">CastingConverting.csproj<\/code>, as shown in the following markup: <code class=\"calibre9\">&lt;Using Include=\"System.Convert\" Static=\"true\" \/&gt;<\/code><\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of&nbsp;<code class=\"calibre9\">Program.cs<\/code>, type statements to declare and assign a value to a&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;variable, convert it into an integer, and then write both values to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">double g = 9.8;\nint h = ToInt32(g); \/\/ A method of System.Convert.\nWriteLine($\"g is {g}, h is {h}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">g is 9.8, h is 10<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">An important difference between casting&nbsp;and converting is that converting rounds the&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;value&nbsp;<code class=\"calibre9\">9.8<\/code>&nbsp;up to&nbsp;<code class=\"calibre9\">10<\/code>&nbsp;instead of trimming the part after the decimal point. Another is that casting can allow overflows while converting will throw an exception.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.6.4\" id=\"calibre_link-175\">\n<h3 data-number=\"4.6.4\" class=\"calibre8\">Rounding numbers and the default rounding rules<\/h3>\n<p class=\"rights\">You have now seen that the cast operator trims the decimal part of a real number and that the&nbsp;<code class=\"calibre9\">System.Convert<\/code>&nbsp;methods round up or down. However, what is the rule for rounding?In British primary schools for children aged 5 to 11, pupils are taught to round&nbsp;<em class=\"calibre10\">up<\/em>&nbsp;if the decimal part is .5 or higher and round&nbsp;<em class=\"calibre10\">down<\/em>&nbsp;if the decimal part is less. Of course, these terms only make sense because at that age the pupils are only dealing with positive numbers. With negative numbers, these terms become confusing and those terms should be avoided. This is why the .NET API uses the <code class=\"calibre9\">enum<\/code> values <code class=\"calibre9\">AwayFromZero<\/code>, <code class=\"calibre9\">ToZero<\/code>, <code class=\"calibre9\">ToEven<\/code>, <code class=\"calibre9\">ToPositiveInfinity<\/code>, and <code class=\"calibre9\">ToNegativeInfinity<\/code> for improved clarity.Let's explore if C# follows the&nbsp;same primary school rule:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type statements to declare and assign an array of&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;values, convert each of them into an integer, and then write the result to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">double[,] doubles = {\n  { 9.49, 9.5, 9.51 },\n  { 10.49, 10.5, 10.51 },\n  { 11.49, 11.5, 11.51 },\n  { 12.49, 12.5, 12.51 } ,\n  { -12.49, -12.5, -12.51 },\n  { -11.49, -11.5, -11.51 },\n  { -10.49, -10.5, -10.51 },\n  { -9.49, -9.5, -9.51 }\n};\nWriteLine($\"| double | ToInt32 | double | ToInt32 | double | ToInt32 |\");\nfor (int x = 0; x &lt; 8; x++)\n{\n  for (int y = 0; y &lt; 3; y++)\n  {\n    Write($\"| {doubles[x, y],6} | {ToInt32(doubles[x, y]),7} \");\n  }\n  WriteLine(\"|\");\n}\nWriteLine();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">| double | ToInt32 | double | ToInt32 | double | ToInt32 |\n|   9.49 |       9 |    9.5 |      10 |   9.51 |      10 |\n|  10.49 |      10 |   10.5 |      10 |  10.51 |      11 |\n|  11.49 |      11 |   11.5 |      12 |  11.51 |      12 |\n|  12.49 |      12 |   12.5 |      12 |  12.51 |      13 |\n| -12.49 |     -12 |  -12.5 |     -12 | -12.51 |     -13 |\n| -11.49 |     -11 |  -11.5 |     -12 | -11.51 |     -12 |\n| -10.49 |     -10 |  -10.5 |     -10 | -10.51 |     -11 |\n|  -9.49 |      -9 |   -9.5 |     -10 |  -9.51 |     -10 |<\/code><\/pre>\n<\/div>\n<p class=\"rights\">We have shown that the rule for rounding in C# is subtly different from the primary school rule:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">It always rounds&nbsp;<em class=\"calibre10\">toward zero<\/em>&nbsp;if the decimal part is less than the midpoint .5.<\/li>\n<li class=\"calibre3\">It always rounds&nbsp;<em class=\"calibre10\">away from zero<\/em>&nbsp;if the decimal part is more than the midpoint .5.<\/li>\n<li class=\"calibre3\">It will round&nbsp;<em class=\"calibre10\">away from zero<\/em>&nbsp;if the decimal part is the midpoint .5 and the non-decimal part is&nbsp;<em class=\"calibre10\">odd<\/em>, but it will round&nbsp;<em class=\"calibre10\">toward zero<\/em>&nbsp;if the non-decimal part is&nbsp;<em class=\"calibre10\">even<\/em>.<\/li>\n<\/ul>\n<p class=\"rights\">This rule is known as&nbsp;<strong class=\"calibre2\">Banker's rounding<\/strong>, and it is preferred because it reduces bias by alternating when it rounds toward or away from zero. Sadly, other languages such as JavaScript use the primary school rule.<\/p>\n<\/section>\n<section data-number=\"4.6.5\" id=\"calibre_link-176\">\n<h3 data-number=\"4.6.5\" class=\"calibre8\">Taking control of rounding rules<\/h3>\n<p class=\"rights\">You can take control of the rounding rules by using the&nbsp;<code class=\"calibre9\">Round<\/code>&nbsp;method of the&nbsp;<code class=\"calibre9\">Math<\/code>&nbsp;class:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type statements to&nbsp;round each of the&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;values using the \"away from zero\" rounding rule, also known as rounding \"up,\" and then write the result to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">foreach (double n in doubles)\n{\n  WriteLine(format:\n    \"Math.Round({0}, 0, MidpointRounding.AwayFromZero) is {1}\",\n    arg0: n,\n    arg1: Math.Round(value: n, digits: 0,\n            mode: MidpointRounding.AwayFromZero));\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can use a <code class=\"calibre9\">foreach<\/code> statement to enumerate all the items in a multi-dimensional array.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and&nbsp;view the result, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Math.Round(9.49, 0, MidpointRounding.AwayFromZero) is 9\nMath.Round(9.5, 0, MidpointRounding.AwayFromZero) is 10\nMath.Round(9.51, 0, MidpointRounding.AwayFromZero) is 10\nMath.Round(10.49, 0, MidpointRounding.AwayFromZero) is 10\nMath.Round(10.5, 0, MidpointRounding.AwayFromZero) is 11\nMath.Round(10.51, 0, MidpointRounding.AwayFromZero) is 11\n...<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: For every programming language that you use, check its rounding rules. They may not work the way you expect! You can read more about <code class=\"calibre9\">Math.Round<\/code> at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.math.round\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.math.round<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.6.6\" id=\"calibre_link-177\">\n<h3 data-number=\"4.6.6\" class=\"calibre8\">Converting from any type to a string<\/h3>\n<p class=\"rights\">The most common conversion is from any type into a&nbsp;<code class=\"calibre9\">string<\/code>&nbsp;variable for outputting as human-readable text, so all types&nbsp;have a method named&nbsp;<code class=\"calibre9\">ToString<\/code>&nbsp;that they inherit from the&nbsp;<code class=\"calibre9\">System.Object<\/code>&nbsp;class.The&nbsp;<code class=\"calibre9\">ToString<\/code>&nbsp;method converts&nbsp;the current value of any variable into a textual representation. Some types can't be sensibly represented as text, so they return their namespace and type name instead.Let's convert some types into a&nbsp;<code class=\"calibre9\">string<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type statements to declare some variables, convert them to their&nbsp;<code class=\"calibre9\">string<\/code>&nbsp;representation, and write them to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int number = 12; \nWriteLine(number.ToString());\nbool boolean = true; \nWriteLine(boolean.ToString());\nDateTime now = DateTime.Now; \nWriteLine(now.ToString());\nobject me = new(); \nWriteLine(me.ToString());<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">12\nTrue\n08\/28\/2024 17:33:54\nSystem.Object<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Passing any object to the <code class=\"calibre9\">WriteLine<\/code> method implicitly converts it into a <code class=\"calibre9\">string<\/code>, so it is not necessary to explicitly call <code class=\"calibre9\">ToString<\/code>. We are doing so here just to emphasize what is happening. Explicitly calling <code class=\"calibre9\">ToString<\/code> does avoid a boxing operation, so if you are developing games with Unity then that can help you avoid memory garbage collection issues.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.6.7\" id=\"calibre_link-178\">\n<h3 data-number=\"4.6.7\" class=\"calibre8\">Converting from a binary object to a string<\/h3>\n<p class=\"rights\">When you have a binary object like an image or video that you want to either store or transmit, you sometimes do not want to send the raw bits because you do not know how those bits could be misinterpreted, for example, by the network protocol transmitting them or another operating system that is reading the stored binary object.The safest thing to do is to&nbsp;convert the binary object into a&nbsp;<code class=\"calibre9\">string<\/code>&nbsp;of safe characters. Programmers call this&nbsp;<strong class=\"calibre2\">Base64<\/strong>&nbsp;encoding.The&nbsp;<code class=\"calibre9\">Convert<\/code>&nbsp;type has&nbsp;a pair of methods,&nbsp;<code class=\"calibre9\">ToBase64String<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">FromBase64String<\/code>, that&nbsp;perform this conversion for you. Let's see them in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type statements to create an array of bytes randomly populated with byte values, write each byte nicely formatted to the console, and then write the same bytes converted into Base64 to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Allocate an array of 128 bytes.\nbyte[] binaryObject = new byte[128];\n\/\/ Populate the array with random bytes.\nRandom.Shared.NextBytes(binaryObject); \nWriteLine(\"Binary Object as bytes:\");\nfor (int index = 0; index &lt; binaryObject.Length; index++)\n{\n  Write($\"{binaryObject[index]:X2} \");\n}\nWriteLine();\n\/\/ Convert the array to Base64 string and output as text.\nstring encoded = ToBase64String(binaryObject);\nWriteLine($\"Binary Object as Base64: {encoded}\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">By default, an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;value would output assuming decimal notation, that is, Base10. You can use format codes such as&nbsp;<code class=\"calibre9\">:X2<\/code>&nbsp;to format the value using hexadecimal notation.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Binary Object as bytes:\nEB 53 8B 11 9D 83 E6 4D 45 85 F4 68 F8 18 55 E5 B8 33 C9 B6 F4 00 10 7F CB 59 23 7B 26 18 16 30 00 23 E6 8F A9 10 B0 A9 E6 EC 54 FB 4D 33 E1 68 50 46 C4 1D 5F B1 57 A1 DB D0 60 34 D2 16 93 39 3E FA 0B 08 08 E9 96 5D 64 CF E5 CD C5 64 33 DD 48 4F E8 B0 B4 19 51 CA 03 6F F4 18 E3 E5 C7 0C 11 C7 93 BE 03 35 44 D1 6F AA B0 2F A9 CE D5 03 A8 00 AC 28 8F A5 12 8B 2E BE 40 C4 31 A8 A4 1A\nBinary Object as Base64: 61OLEZ2D5k1FhfRo+BhV5bgzybb0ABB\/y1kjeyYYFjAAI+aPqRCwqebsVPtNM+FoUEbEHV+xV6Hb0GA00haTOT76CwgI6ZZdZM\/lzcVkM91IT+iwtBlRygNv9Bjj5ccMEceTvgM1RNFvqrAvqc7VA6gArCiPpRKLLr5AxDGopBo=<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.6.8\" id=\"calibre_link-179\">\n<h3 data-number=\"4.6.8\" class=\"calibre8\">Parsing from strings to numbers or dates and times<\/h3>\n<p class=\"rights\">The second most common conversion is from strings to numbers or date and time values.The opposite of&nbsp;<code class=\"calibre9\">ToString<\/code>&nbsp;is&nbsp;<code class=\"calibre9\">Parse<\/code>. Only a few types have a&nbsp;<code class=\"calibre9\">Parse<\/code>&nbsp;method, including all the number types and&nbsp;<code class=\"calibre9\">DateTime<\/code>.Let's see&nbsp;<code class=\"calibre9\">Parse<\/code>&nbsp;in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.cs<\/code>, import the namespace for working with cultures, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Globalization; \/\/ To use CultureInfo.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of <code class=\"calibre9\">Program.cs<\/code>, add statements to parse an integer and a date and time value from strings and then write the result to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Set the current culture to make sure date parsing works.\nCultureInfo.CurrentCulture = CultureInfo.GetCultureInfo(\"en-US\");\nint friends = int.Parse(\"27\");\nDateTime birthday = DateTime.Parse(\"4 June 1980\");\nWriteLine($\"I have {friends} friends to invite to my party.\"); \nWriteLine($\"My birthday is {birthday}.\"); \nWriteLine($\"My birthday is {birthday:D}.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">I have 27 friends to invite to my party.\nMy birthday is 6\/4\/1980 12:00:00 AM.\nMy birthday is Wednesday, June 4, 1980.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">By default, a date and time value outputs with the short date and time format. You can use format codes such as&nbsp;<code class=\"calibre9\">D<\/code>&nbsp;to output only the date part using the long date format.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Use the standard date and time format specifiers, as shown at the following link:&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/base-types\/standard-date-and-time-format-strings#table-of-format-specifiers\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/base-types\/standard-date-and-time-format-strings#table-of-format-specifiers<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.6.9\" id=\"calibre_link-180\">\n<h3 data-number=\"4.6.9\" class=\"calibre8\">Avoiding Parse exceptions by using the TryParse method<\/h3>\n<p class=\"rights\">One problem with the&nbsp;<code class=\"calibre9\">Parse<\/code>&nbsp;method is that it gives errors if the&nbsp;<code class=\"calibre9\">string<\/code>&nbsp;cannot be converted:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type a statement to attempt&nbsp;to parse a string containing letters into an integer variable, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int count = int.Parse(\"abc\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Unhandled Exception: System.FormatException: Input string was not in a correct format.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">As well as the preceding exception message, you will see a stack trace. I have not included stack traces in this book because they take up too much space.To avoid errors, you can&nbsp;use the&nbsp;<code class=\"calibre9\">TryParse<\/code>&nbsp;method instead.&nbsp;<code class=\"calibre9\">TryParse<\/code>&nbsp;attempts to convert the input&nbsp;<code class=\"calibre9\">string<\/code>&nbsp;and returns&nbsp;<code class=\"calibre9\">true<\/code>&nbsp;if it can convert it and&nbsp;<code class=\"calibre9\">false<\/code>&nbsp;if it cannot. Exceptions are a relatively expensive operation so they should be avoided when you can.The&nbsp;<code class=\"calibre9\">out<\/code>&nbsp;keyword is required to allow the&nbsp;<code class=\"calibre9\">TryParse<\/code>&nbsp;method to set the count variable when the conversion works.Let's see&nbsp;<code class=\"calibre9\">TryParse<\/code>&nbsp;in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Replace the&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;<code class=\"calibre9\">count<\/code>&nbsp;declaration with statements to use the&nbsp;<code class=\"calibre9\">TryParse<\/code>&nbsp;method and ask the user to input a count for a&nbsp;number of eggs, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Write(\"How many eggs are there? \"); \nstring? input = ReadLine();\nif (int.TryParse(input, out int count))\n{\n  WriteLine($\"There are {count} eggs.\");\n}\nelse\n{\n  WriteLine(\"I could not parse the input.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter&nbsp;<code class=\"calibre9\">12<\/code>, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">How many eggs are there? 12\nThere are 12 eggs.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter&nbsp;<code class=\"calibre9\">twelve<\/code>, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">How many eggs are there? twelve\nI could not parse the input.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You can also use methods of the&nbsp;<code class=\"calibre9\">System.Convert<\/code>&nbsp;type to convert&nbsp;<code class=\"calibre9\">string<\/code>&nbsp;values into other types; however, like the&nbsp;<code class=\"calibre9\">Parse<\/code>&nbsp;method, it gives an error if it cannot convert.<\/p>\n<\/section>\n<section data-number=\"4.6.10\" id=\"calibre_link-181\">\n<h3 data-number=\"4.6.10\" class=\"calibre8\">Understanding the Try method naming convention<\/h3>\n<p class=\"rights\">.NET uses a standard signature for all methods that follow the <code class=\"calibre9\">Try<\/code> naming convention. For any method named <code class=\"calibre9\">Something<\/code> that returns a value of a specific type, its matching <code class=\"calibre9\">TrySomething<\/code> method must return a <code class=\"calibre9\">bool<\/code> to indicate success or failure and use an <code class=\"calibre9\">out<\/code> parameter in place of the return value. For example:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ A method that might throw an exception.\nint number = int.Parse(\"123\");\n\/\/ The Try equivalent of the method.\nbool success = int.TryParse(\"123\", out int number);\n\/\/ Trying to create a Uri for a Web API.\nbool success = Uri.TryCreate(\"https:\/\/localhost:5000\/api\/customers\", \n  UriKind.Absolute, out Uri serviceUrl);<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"4.7\" id=\"calibre_link-182\">\n<h2 data-number=\"4.7\" class=\"calibre5\">Handling exceptions<\/h2>\n<p class=\"rights\">You've seen several scenarios where errors have occurred when converting types. Some languages return error codes when&nbsp;something goes wrong. .NET uses exceptions that are richer and designed only for failure reporting. When this happens, we say <em class=\"calibre10\">a&nbsp;runtime exception has been thrown<\/em>.Other systems might use return values that could have multiple uses. For example, if the return value is a positive number, it might represent the count of rows in a table, or if the return value is a negative number, it might represent some error code. When an exception is thrown, the thread is suspended and if the calling code has defined a&nbsp;<code class=\"calibre9\">try-catch<\/code>&nbsp;statement, then it is given a chance to handle the exception. If the current method does not handle it, then its calling method is given a chance, and so on up the call stack.As you have seen, the default behavior of a console app is to output a message about the exception, including a stack trace, and then stop running the code. The application is terminated. This is better than allowing the code to continue executing in a potentially corrupt state. Your code should only catch and handle exceptions that it understands and can properly fix.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Avoid writing code that will throw an exception whenever possible, perhaps by performing&nbsp;<code class=\"calibre9\">if<\/code>&nbsp;statement checks. Sometimes you can't, and sometimes it is best to allow the exception to be caught by a higher-level component that is calling your code. You will learn how to do this in&nbsp;<em class=\"calibre10\">Chapter 4<\/em>,&nbsp;<em class=\"calibre10\">Writing, Debugging, and Testing Functions<\/em>.<\/p>\n<\/blockquote>\n<section data-number=\"4.7.1\" id=\"calibre_link-183\">\n<h3 data-number=\"4.7.1\" class=\"calibre8\">Wrapping error-prone code in a try block<\/h3>\n<p class=\"rights\">When you know that a statement can cause an error, you should wrap that statement in a&nbsp;<code class=\"calibre9\">try<\/code>&nbsp;block. For example, parsing&nbsp;from text to a number can cause an error. Any statements in the&nbsp;<code class=\"calibre9\">catch<\/code>&nbsp;block will be executed only if an exception is thrown by a statement in the&nbsp;<code class=\"calibre9\">try<\/code>&nbsp;block.We don't have to do anything inside the&nbsp;<code class=\"calibre9\">catch<\/code>&nbsp;block. Let's see this in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new&nbsp;<strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named&nbsp;<code class=\"calibre9\">HandlingExceptions<\/code> to the&nbsp;<code class=\"calibre9\">Chapter03<\/code>&nbsp;solution.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete any existing statements and then type statements to prompt the user to enter their age and then write their age to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(\"Before parsing\"); \nWrite(\"What is your age? \"); \nstring? input = ReadLine();\ntry\n{\n  int age = int.Parse(input); \n  WriteLine($\"You are {age} years old.\");\n}\ncatch\n{\n}\nWriteLine(\"After parsing\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You will see the following compiler message:&nbsp;<code class=\"calibre9\">Warning CS8604 Possible null reference argument for parameter 's' in 'int int.Parse(string s)'<\/code>.&nbsp;By default, in .NET 6 or later projects, Microsoft enables nullable reference types, so you will see many more compiler warnings like this. In production code, you should add code to check for&nbsp;<code class=\"calibre9\">null<\/code>&nbsp;and handle that possibility appropriately, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (input is null)\n{\n  WriteLine(\"You did not enter a value so the app has ended.\");\n  return; \/\/ Exit the app.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">In this book, I will not give instructions to add these&nbsp;<code class=\"calibre9\">null<\/code>&nbsp;checks every time because the code samples are not designed to be production-quality, and having&nbsp;<code class=\"calibre9\">null<\/code>&nbsp;checks everywhere will clutter the code and use up valuable pages. You will probably see hundreds more examples of potentially&nbsp;<code class=\"calibre9\">null<\/code>&nbsp;variables throughout the code samples in this book. Those warnings are safe to ignore for the book code examples. You only need to pay attention to similar warnings when you write your own production code. You will see more about null handling in&nbsp;<em class=\"calibre10\">Chapter 6<\/em>,<em class=\"calibre10\">&nbsp;Implementing Interfaces and Inheriting Classes<\/em>.In this case, it is impossible for&nbsp;<code class=\"calibre9\">input<\/code>&nbsp;to be&nbsp;<code class=\"calibre9\">null<\/code>&nbsp;because the user must press&nbsp;<span>Enter<\/span>&nbsp;for&nbsp;<code class=\"calibre9\">ReadLine<\/code>&nbsp;to return, and if they have not typed any characters at that point then the <code class=\"calibre9\">ReadLine<\/code> method will return an empty&nbsp;<code class=\"calibre9\">string<\/code>. Let's tell the compiler that it does not need to show us this warning:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">To disable the compiler warning, change <code class=\"calibre9\">input<\/code> to <code class=\"calibre9\">input!<\/code>, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int age = int.Parse(input!);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">An exclamation mark <code class=\"calibre9\">!<\/code> after an expression is called the <strong class=\"calibre2\">null-forgiving operator<\/strong> and it disables the compiler warning. The <strong class=\"calibre2\">null-forgiving operator<\/strong> has no effect at runtime. If the expression could evaluate to <code class=\"calibre9\">null<\/code> at runtime, perhaps because we assigned it in another way, then an exception would be thrown.<\/p>\n<\/blockquote>\n<p class=\"rights\">This code includes two messages to indicate&nbsp;<em class=\"calibre10\">before<\/em>&nbsp;parsing and&nbsp;<em class=\"calibre10\">after<\/em>&nbsp;parsing to make the flow through the code clearer. These will be especially useful as the example code grows more complex.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter&nbsp;<code class=\"calibre9\">49<\/code>, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Before parsing\nWhat is your age? 49\nYou are 49 years old. \nAfter parsing<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter&nbsp;<code class=\"calibre9\">Kermit<\/code>, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Before parsing\nWhat is your age? Kermit\nAfter parsing<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When the code was executed, the error exception was caught, the default message and stack trace were not output, and&nbsp;the console app continued running. This is better than the default behavior, but it might be useful to see the type of error that occurred.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You should never use an empty&nbsp;<code class=\"calibre9\">catch<\/code>&nbsp;statement like this in production code because it \"swallows\" exceptions and hides potential problems. You should at least log the exception if you cannot or do not want to handle it properly, or rethrow it so that higher-level code can decide instead. You will learn about logging in&nbsp;<em class=\"calibre10\">Chapter 4<\/em>,<em class=\"calibre10\">&nbsp;Writing, Debugging, and Testing Functions<\/em>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.7.2\" id=\"calibre_link-184\">\n<h3 data-number=\"4.7.2\" class=\"calibre8\">Catching all exceptions<\/h3>\n<p class=\"rights\">To get information about&nbsp;any type of exception that might occur, you can declare a variable of type&nbsp;<code class=\"calibre9\">System.Exception<\/code>&nbsp;to the&nbsp;<code class=\"calibre9\">catch<\/code>&nbsp;block:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add an exception variable declaration to the&nbsp;<code class=\"calibre9\">catch<\/code>&nbsp;block and use it to write information about the exception to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">catch (Exception ex)\n{\n  WriteLine($\"{ex.GetType()} says {ex.Message}\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter&nbsp;<code class=\"calibre9\">Kermit<\/code>&nbsp;again, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Before parsing\nWhat is your age? Kermit\nSystem.FormatException says Input string was not in a correct format. \nAfter parsing<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.7.3\" id=\"calibre_link-185\">\n<h3 data-number=\"4.7.3\" class=\"calibre8\">Catching specific exceptions<\/h3>\n<p class=\"rights\">Now that we know which specific type of exception occurred, we can improve our code by catching just that type of exception and customizing the message that we display to the user. You can think of this as a form of testing:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Leave the existing&nbsp;<code class=\"calibre9\">catch<\/code>&nbsp;block, and above it, add a new&nbsp;<code class=\"calibre9\">catch<\/code>&nbsp;block for the format exception type, as shown in the following highlighted code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">catch (FormatException)\n{\n  WriteLine(\"The age you entered is not a valid number format.\");\n}\ncatch (Exception ex)\n{\n  WriteLine($\"{ex.GetType()} says {ex.Message}\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter&nbsp;<code class=\"calibre9\">Kermit<\/code>&nbsp;again, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Before parsing\nWhat is your age? Kermit\nThe age you entered is not a valid number format. \nAfter parsing<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The reason we want to leave the more general <code class=\"calibre9\">catch<\/code> below is that there might be other types of exceptions&nbsp;that can occur.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter&nbsp;<code class=\"calibre9\">9876543210<\/code>, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Before parsing\nWhat is your age? 9876543210\nSystem.OverflowException says Value was either too large or too small for an Int32.\nAfter parsing<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Let's add another&nbsp;<code class=\"calibre9\">catch<\/code>&nbsp;block for this type of exception.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Leave the existing&nbsp;<code class=\"calibre9\">catch<\/code>&nbsp;blocks, and add a new&nbsp;<code class=\"calibre9\">catch<\/code>&nbsp;block for the overflow exception type, as shown in the following highlighted code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">catch (OverflowException)\n{\n  WriteLine(\"Your age is a valid number format but it is either too big or small.\");\n}\ncatch (FormatException)\n{\n  WriteLine(\"The age you entered is not a valid number format.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter&nbsp;<code class=\"calibre9\">9876543210<\/code>, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Before parsing\nWhat is your age? 9876543210\nYour age is a valid number format but it is either too big or small. \nAfter parsing<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The order in which you catch exceptions is important. The correct order is related to the inheritance hierarchy of the exception types. You will learn about inheritance in&nbsp;<em class=\"calibre10\">Chapter 5<\/em>,<em class=\"calibre10\">&nbsp;Building Your Own Types with Object-Oriented Programming<\/em>. However, don't worry too much about this&mdash;the compiler will give you build errors if you get exceptions in the wrong order anyway.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Avoid over-catching exceptions. They should often be allowed to propagate up the call stack to be handled at a level where more information is known about the circumstances that could change the logic of how they should be handled. You will learn about this in&nbsp;<em class=\"calibre10\">Chapter 4<\/em>,<em class=\"calibre10\">&nbsp;Writing, Debugging, and Testing Functions<\/em>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"4.7.4\" id=\"calibre_link-186\">\n<h3 data-number=\"4.7.4\" class=\"calibre8\">Catching with filters<\/h3>\n<p class=\"rights\">You can also add filters to a <code class=\"calibre9\">catch<\/code>&nbsp;statement using the&nbsp;<code class=\"calibre9\">when<\/code>&nbsp;keyword, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Write(\"Enter an amount: \");\nstring amount = ReadLine()!;\nif (string.IsNullOrEmpty(amount)) return;\ntry\n{\n  decimal amountValue = decimal.Parse(amount);\n  WriteLine($\"Amount formatted as currency: {amountValue:C}\");\n}\ncatch (FormatException) when (amount.Contains(\"$\"))\n{\n  WriteLine(\"Amounts cannot use the dollar sign!\");\n}\ncatch (FormatException)\n{\n  WriteLine(\"Amounts must only contain digits!\");\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"4.8\" id=\"calibre_link-187\">\n<h2 data-number=\"4.8\" class=\"calibre5\">Checking for overflow<\/h2>\n<p class=\"rights\">Earlier, we saw that when casting between number types, it was possible to lose information, for example, when casting from a&nbsp;<code class=\"calibre9\">long<\/code>&nbsp;variable to an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;variable. If the value stored in a type is too big, it will overflow.<\/p>\n<section data-number=\"4.8.1\" id=\"calibre_link-188\">\n<h3 data-number=\"4.8.1\" class=\"calibre8\">Throwing overflow exceptions with the checked statement<\/h3>\n<p class=\"rights\">The&nbsp;<code class=\"calibre9\">checked<\/code>&nbsp;statement tells .NET to throw an exception when an overflow happens instead of allowing it to&nbsp;happen silently, which is done by default for performance reasons.We will set the&nbsp;initial value of an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;variable to its maximum value minus one. Then, we will increment it several times, outputting its value each time. Once it&nbsp;gets above its maximum value, it overflows to its minimum value and continues incrementing from there.Let's see this in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In&nbsp;<code class=\"calibre9\">Program.cs<\/code>, type statements to declare and assign an integer to one less than its maximum possible value, and then increment it and write its value to the console three times, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int x = int.MaxValue - 1; \nWriteLine($\"Initial value: {x}\"); \nx++;\nWriteLine($\"After incrementing: {x}\"); \nx++;\nWriteLine($\"After incrementing: {x}\"); \nx++;\nWriteLine($\"After incrementing: {x}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result that shows the value overflowing silently and wrapping around to large negative values, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Initial value: 2147483646\nAfter incrementing: 2147483647\nAfter incrementing: -2147483648\nAfter incrementing: -2147483647<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Now, let's get the compiler to warn us about the overflow by wrapping the statements using a&nbsp;<code class=\"calibre9\">checked<\/code>&nbsp;statement block, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">checked\n{\n  int x = int.MaxValue - 1; \n  WriteLine($\"Initial value: {x}\"); \n  x++;\n  WriteLine($\"After incrementing: {x}\"); \n  x++;\n  WriteLine($\"After incrementing: {x}\"); \n  x++;\n  WriteLine($\"After incrementing: {x}\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result that shows the overflow being checked and causing an exception to be&nbsp;thrown, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Initial value: 2147483646\nAfter incrementing: 2147483647\nUnhandled Exception: System.OverflowException: Arithmetic operation resulted in an overflow.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Just like any other exception, we should wrap these statements in a&nbsp;<code class=\"calibre9\">try<\/code>&nbsp;statement block and display a nicer&nbsp;error message for the user, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">try\n{\n  \/\/ previous code goes here\n}\ncatch (OverflowException)\n{\n  WriteLine(\"The code overflowed but I caught the exception.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Initial value: 2147483646\nAfter incrementing: 2147483647\nThe code overflowed but I caught the exception.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.8.2\" id=\"calibre_link-189\">\n<h3 data-number=\"4.8.2\" class=\"calibre8\">Disabling compiler overflow checks with the unchecked statement<\/h3>\n<p class=\"rights\">The previous section was about the default overflow behavior at&nbsp;<em class=\"calibre10\">runtime<\/em>&nbsp;and how to use the&nbsp;<code class=\"calibre9\">checked<\/code>&nbsp;statement to&nbsp;change that behavior. This section is about&nbsp;<em class=\"calibre10\">compile-time<\/em>&nbsp;overflow behavior and how to use the&nbsp;<code class=\"calibre9\">unchecked<\/code>&nbsp;statement to&nbsp;change that behavior.A related keyword is&nbsp;<code class=\"calibre9\">unchecked<\/code>. This keyword switches off overflow checks performed by the compiler within a block of code. Let's see how to do this:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Type the following statement at the end of the previous statements. The compiler will not compile this statement because it knows it would overflow:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int y = int.MaxValue + 1;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Hover your mouse pointer over the error, and note that a compile-time check is shown as an error message, as shown in&nbsp;<em class=\"calibre10\">Figure 3.4<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 3.4: A compile-time check for integer overflow\" height=\"550\" src=\"\/images\/cs12\/000140.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 3.4: A compile-time check for integer overflow<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">To disable compile-time&nbsp;checks, wrap the statement in an&nbsp;<code class=\"calibre9\">unchecked<\/code>&nbsp;block, write the value of&nbsp;<code class=\"calibre9\">y<\/code>&nbsp;to the console, decrement&nbsp;it, and repeat, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">unchecked\n{\n  int y = int.MaxValue + 1; \n  WriteLine($\"Initial value: {y}\"); \n  y--;\n  WriteLine($\"After decrementing: {y}\"); \n  y--;\n  WriteLine($\"After decrementing: {y}\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Initial value: -2147483648\nAfter decrementing: 2147483647\nAfter decrementing: 2147483646<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Of course, it would be rare that you would want to explicitly switch off a check like this because it allows an overflow to occur. But perhaps you can think of a scenario where you might want that behavior.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"4.9\" id=\"calibre_link-190\">\n<h2 data-number=\"4.9\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring this chapter's topics with deeper research.<\/p>\n<section data-number=\"4.9.1\" id=\"calibre_link-191\">\n<h3 data-number=\"4.9.1\" class=\"calibre8\">Exercise 3.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What happens when you divide an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;variable by&nbsp;<code class=\"calibre9\">0<\/code>?<\/li>\n<li class=\"calibre3\">What happens when you divide a&nbsp;<code class=\"calibre9\">double<\/code>&nbsp;variable by&nbsp;<code class=\"calibre9\">0<\/code>?<\/li>\n<li class=\"calibre3\">What happens when you overflow an&nbsp;<code class=\"calibre9\">int<\/code>&nbsp;variable, that is, set it to a value beyond its range?<\/li>\n<li class=\"calibre3\">What is the difference between&nbsp;<code class=\"calibre9\">x = y++;<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">x = ++y;<\/code>?<\/li>\n<li class=\"calibre3\">What is the difference between&nbsp;<code class=\"calibre9\">break<\/code>,&nbsp;<code class=\"calibre9\">continue<\/code>, and&nbsp;<code class=\"calibre9\">return<\/code>&nbsp;when used inside a loop statement?<\/li>\n<li class=\"calibre3\">What are the three parts of a&nbsp;<code class=\"calibre9\">for<\/code>&nbsp;statement and which of them are required?<\/li>\n<li class=\"calibre3\">What is the difference between the&nbsp;<code class=\"calibre9\">=<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">==<\/code>&nbsp;operators?<\/li>\n<li class=\"calibre3\">Does the following statement compile?<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">for ( ; ; ) ;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does the underscore&nbsp;<code class=\"calibre9\">_<\/code>&nbsp;represent in a&nbsp;<code class=\"calibre9\">switch<\/code>&nbsp;expression?<\/li>\n<li class=\"calibre3\">What interface must an object \"implement\" to be enumerated over by using the&nbsp;<code class=\"calibre9\">foreach<\/code>&nbsp;statement?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"4.9.2\" id=\"calibre_link-192\">\n<h3 data-number=\"4.9.2\" class=\"calibre8\">Exercise 3.2 &ndash; Explore loops and overflow<\/h3>\n<p class=\"rights\">What will happen if this code executes?<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int max = 500;\nfor (byte i = 0; i &lt; max; i++)\n{\n  WriteLine(i);\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Create a console app in&nbsp;<code class=\"calibre9\">Chapter03<\/code>&nbsp;named&nbsp;<code class=\"calibre9\">Ch03Ex02LoopsAndOverflow<\/code>&nbsp;and enter the preceding code. Run the console app and view the output. What happens?What code could you add (don't change any of the preceding code) to warn us about the problem?<\/p>\n<\/section>\n<section data-number=\"4.9.3\" id=\"calibre_link-193\">\n<h3 data-number=\"4.9.3\" class=\"calibre8\">Exercise 3.3 &ndash; Test your knowledge of operators<\/h3>\n<p class=\"rights\">What are the values of&nbsp;<code class=\"calibre9\">x<\/code>&nbsp;and&nbsp;<code class=\"calibre9\">y<\/code>&nbsp;after the following statements execute? Create a console app in&nbsp;<code class=\"calibre9\">Chapter03<\/code>&nbsp;named&nbsp;<code class=\"calibre9\">Ch03Ex03Operators<\/code>&nbsp;to test your assumptions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Increment and addition operators:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">x = 3;\ny = 2 + ++x;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Binary shift operators:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">x = 3 &lt;&lt; 2;\ny = 10 &gt;&gt; 1;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Bitwise operators:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">x = 10 &amp; 8;\ny = 10 | 7;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.9.4\" id=\"calibre_link-194\">\n<h3 data-number=\"4.9.4\" class=\"calibre8\">Exercise 3.4 &ndash; Practice loops and operators<\/h3>\n<p class=\"rights\">FizzBuzz&nbsp;is a group game for children to teach them about division. Players take turns to count incrementally, replacing any number divisible by 3 with the word&nbsp;<em class=\"calibre10\">fizz<\/em>, any number divisible by 5 with the word&nbsp;<em class=\"calibre10\">buzz<\/em>, and any number divisible by both with&nbsp;<em class=\"calibre10\">fizzbuzz<\/em>.Create a console app in&nbsp;<code class=\"calibre9\">Chapter03<\/code>&nbsp;named&nbsp;<code class=\"calibre9\">Ch03Ex04FizzBuzz<\/code>&nbsp;that outputs a simulated FizzBuzz game that counts up to 100. The output should look something like&nbsp;<em class=\"calibre10\">Figure 3.5<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 3.5: A simulated FizzBuzz game output\" height=\"527\" src=\"\/images\/cs12\/000156.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 3.5: A simulated FizzBuzz game output<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"4.9.5\" id=\"calibre_link-195\">\n<h3 data-number=\"4.9.5\" class=\"calibre8\">Exercise 3.5 &ndash; Practice exception handling<\/h3>\n<p class=\"rights\">Create a console app in&nbsp;<code class=\"calibre9\">Chapter03<\/code>&nbsp;named&nbsp;<code class=\"calibre9\">Ch03Ex05Exceptions<\/code>&nbsp;that asks the user for two numbers in the range 0-255 and then divides the first number by the second:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter a number between 0 and 255: 100\nEnter another number between 0 and 255: 8\n100 divided by 8 is 12<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Write exception handlers to catch any thrown errors, as shown in the following output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter a number between 0 and 255: apples\nEnter another number between 0 and 255: bananas \nFormatException: Input string was not in a correct format.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"4.9.6\" id=\"calibre_link-196\">\n<h3 data-number=\"4.9.6\" class=\"calibre8\">Exercise 3.6 &ndash; Explore C# 101 notebooks<\/h3>\n<p class=\"rights\">Use the links to notebooks and videos on the following page to see interactive examples of C# using Polyglot Notebooks, as shown in <em class=\"calibre10\">Figure 3.6<\/em>:<a href=\"https:\/\/github.com\/dotnet\/csharp-notebooks#c-101\">https:\/\/github.com\/dotnet\/csharp-notebooks#c-101<\/a><\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 3.6: An example C# 101 notebook titled What Are Loops?\" height=\"725\" src=\"\/images\/cs12\/000174.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 3.6: An example C# 101 notebook titled What Are Loops?<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"4.9.7\" id=\"calibre_link-197\">\n<h3 data-number=\"4.9.7\" class=\"calibre8\">Exercise 3.7 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn about the topics covered in this chapter in more detail:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-3---controlling-flow-converting-types-and-handling-exceptions\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-3---controlling-flow-converting-types-and-handling-exceptions<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"4.10\" id=\"calibre_link-198\">\n<h2 data-number=\"4.10\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned how to:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Use operators to perform simple tasks.<\/li>\n<li class=\"calibre3\">Use branch and loop statements to implement logic.<\/li>\n<li class=\"calibre3\">Work with single- and multi-dimensional arrays.<\/li>\n<li class=\"calibre3\">Convert between types.<\/li>\n<li class=\"calibre3\">Catch exceptions and handle integer overflow.<\/li>\n<\/ul>\n<p class=\"rights\">You are now ready to learn how to reuse blocks of code by defining functions, how to pass values into them and get values back, and how to track down bugs in your code and squash them using debugging and testing tools!<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-9\">\n<div id=\"calibre_link-1919\" class=\"calibre1\">\n<section data-number=\"5\" id=\"calibre_link-199\">\n<h1 data-number=\"5\" class=\"title\">4 Writing, Debugging, and Testing Functions<\/h1>\n<section data-number=\"5.1\" id=\"calibre_link-200\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"5.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000071.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about writing functions to reuse code, debugging logic errors during development, logging exceptions during runtime, unit testing your code to remove bugs, and improving stability and reliability.This chapter covers the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Writing functions<\/li>\n<li class=\"calibre3\">Debugging during development<\/li>\n<li class=\"calibre3\">Hot reloading during development<\/li>\n<li class=\"calibre3\">Logging during development and runtime<\/li>\n<li class=\"calibre3\">Unit testing<\/li>\n<li class=\"calibre3\">Throwing and catching exceptions in functions<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"5.2\" id=\"calibre_link-201\">\n<h2 data-number=\"5.2\" class=\"calibre5\">Writing functions<\/h2>\n<p class=\"rights\">A fundamental principle of programming is <strong class=\"calibre2\">Don't Repeat Yourself<\/strong> (<strong class=\"calibre2\">DRY<\/strong>).While programming, if you find yourself writing the same statements over and over again, then turn those statements into a <strong class=\"calibre2\">function<\/strong>. Functions are like tiny programs that complete one small task. For example, you might write a function to calculate sales tax and then reuse that function in many places in a financial application.Like programs, functions usually have inputs and outputs. They are sometimes described as black boxes, where you feed some raw materials in at one end and a manufactured item emerges at the other. Once created and thoroughly debugged and tested, you don't need to think about how they work.<\/p>\n<section data-number=\"5.2.1\" id=\"calibre_link-202\">\n<h3 data-number=\"5.2.1\" class=\"calibre8\">Exploring top-level programs, functions, and namespaces<\/h3>\n<p class=\"rights\">In <em class=\"calibre10\">Chapter 1<\/em>, <em class=\"calibre10\">Hello, C#! Welcome, .NET!<\/em>, we learned that since C# 10 and .NET 6, the default project template for console apps uses the top-level program feature introduced with C# 9.Once you start writing functions, it is important to understand how they work with the automatically generated <code class=\"calibre9\">Program<\/code> class and its <code class=\"calibre9\">&lt;Main&gt;$<\/code> method.Let's explore how the top-level program feature works when you define functions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to create a new solution and project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">TopLevelFunctions<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter04<\/code><\/li>\n<li class=\"calibre3\">Do not use top-level statements: Cleared.<\/li>\n<li class=\"calibre3\">Enable native AOT publish: Cleared.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, define a local function at the bottom of the file, and call it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using static System.Console;\nWriteLine(\"* Top-level functions example\");\nWhatsMyNamespace(); \/\/ Call the function.\nvoid WhatsMyNamespace() \/\/ Define a local function.\n{\n  WriteLine(\"Namespace of Program class: {0}\", \n    arg0: typeof(Program).Namespace ?? \"null\");\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Functions do not need to be at the bottom of the file, but it is good practice rather than mixing them up with other top-level statements. Types like classes <em class=\"calibre10\">must<\/em> be declared at the bottom of the <code class=\"calibre9\">Program.cs<\/code> file rather than in the middle of the file or you will see compiler error <code class=\"calibre9\">CS8803<\/code>, as shown at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/compiler-messages\/cs8803\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/compiler-messages\/cs8803<\/a>. It would be better to define types like classes in a separate file.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app and note that the namespace for the <code class=\"calibre9\">Program<\/code> class is <code class=\"calibre9\">null<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">* Top-level functions example\nNamespace of Program class: null<\/code><\/pre>\n<\/div>\n<section data-number=\"5.2.1.1\" id=\"calibre_link-1920\">\n<h4 data-number=\"5.2.1.1\" class=\"calibre15\">What is automatically generated for a local function?<\/h4>\n<p class=\"rights\">The compiler automatically generates a <code class=\"calibre9\">Program<\/code> class with a <code class=\"calibre9\">&lt;Main&gt;$<\/code> function, then moves your statements and function inside the <code class=\"calibre9\">&lt;Main&gt;$<\/code> method, which makes the function local, and renames the function, as shown highlighted in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using static System.Console;\npartial class Program\n{\n  static void &lt;Main&gt;$(String[] args)\n  {\n    WriteLine(\"* Top-level functions example\");\n    &lt;&lt;Main&gt;$&gt;g__WhatsMyNamespace|0_0(); \/\/ Call the function.\n    void &lt;&lt;Main&gt;$&gt;g__WhatsMyNamespace|0_0() \/\/ Define a local function.\n    {\n      WriteLine(\"Namespace of Program class: {0}\", \n        arg0: typeof(Program).Namespace ?? \"null\");\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">For the compiler to know what statements need to go where, you must follow some rules:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Import statements (<code class=\"calibre9\">using<\/code>) must go at the top of the <code class=\"calibre9\">Program.cs<\/code> file.<\/li>\n<li class=\"calibre3\">Statements that will go in the <code class=\"calibre9\">&lt;Main&gt;$<\/code> function can be mixed with functions in the middle of the <code class=\"calibre9\">Program.cs<\/code> file. Any functions will become <strong class=\"calibre2\">local functions<\/strong> in the <code class=\"calibre9\">&lt;Main&gt;$<\/code> method.<\/li>\n<\/ul>\n<p class=\"rights\">The last point is important because local functions have limitations, like they cannot have XML comments to document them.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You are about to see some C# keywords like <code class=\"calibre9\">static<\/code> and <code class=\"calibre9\">partial<\/code>, which will be formally introduced in <em class=\"calibre10\">Chapter 5<\/em>, <em class=\"calibre10\">Building Your Own Types with Object-Oriented Programming<\/em>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"5.2.2\" id=\"calibre_link-203\">\n<h3 data-number=\"5.2.2\" class=\"calibre8\">Defining a partial Program class with a static function<\/h3>\n<p class=\"rights\">A better approach is to write any functions in a separate file and define them as <code class=\"calibre9\">static<\/code> members of the <code class=\"calibre9\">Program<\/code> class:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Program.Functions.cs<\/code>. The name of this file does not actually matter but using this naming convention is sensible. You could name the file <code class=\"calibre9\">Gibberish.cs<\/code> and it would have the same behavior.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, delete any existing statements and then add statements to define a <code class=\"calibre9\">partial Program<\/code> class. Cut and paste the <code class=\"calibre9\">WhatsMyNamespace<\/code> function to move it from <code class=\"calibre9\">Program.cs<\/code> into <code class=\"calibre9\">Program.Functions.cs<\/code>, and then add the <code class=\"calibre9\">static<\/code> keyword to the function, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using static System.Console;\n\/\/ Do not define a namespace so this class goes in the default empty namespace\n\/\/ just like the auto-generated partial Program class.\npartial class Program\n{\n  static void WhatsMyNamespace() \/\/ Define a static function.\n  {\n    WriteLine(\"Namespace of Program class: {0}\",\n      arg0: typeof(Program).Namespace ?? \"null\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, confirm that its entire content is now just three statements, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using static System.Console;\nWriteLine(\"* Top-level functions example\");\nWhatsMyNamespace(); \/\/ Call the function.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app and note that it has the same behavior as before.<\/li>\n<\/ol>\n<section data-number=\"5.2.2.1\" id=\"calibre_link-1921\">\n<h4 data-number=\"5.2.2.1\" class=\"calibre15\">What is automatically generated for a static function?<\/h4>\n<p class=\"rights\">When you use a separate file to define a <code class=\"calibre9\">partial Program<\/code> class with <code class=\"calibre9\">static<\/code> functions, the compiler defines a <code class=\"calibre9\">Program<\/code> class with a <code class=\"calibre9\">&lt;Main&gt;$<\/code> function, and merges your function as a member of the <code class=\"calibre9\">Program<\/code> class, as shown in the following highlighted code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using static System.Console;\npartial class Program\n{\n  static void &lt;Main&gt;$(String[] args)\n  {\n    WriteLine(\"* Top-level functions example\");\n    WhatsMyNamespace(); \/\/ Call the function.\n  }\n  static void WhatsMyNamespace() \/\/ Define a static function.\n  {\n    WriteLine(\"Namespace of Program class: {0}\",\n      arg0: typeof(Program).Namespace ?? \"null\");\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><strong class=\"calibre2\">Solution Explorer<\/strong> shows that your <code class=\"calibre9\">Program.Functions.cs<\/code> class file merges its <code class=\"calibre9\">partial Program<\/code> with the auto-generated <code class=\"calibre9\">partial Program<\/code> class, as shown in <em class=\"calibre10\">Figure 4.1<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.1: Solution Explorer showing the merged partial Program class\" height=\"695\" src=\"\/images\/cs12\/000105.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.1: Solution Explorer showing the merged partial Program class<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Create any functions that you will call in <code class=\"calibre9\">Program.cs<\/code> in a separate file and manually define them inside a <code class=\"calibre9\">partial Program<\/code> class. This will merge them into the automatically generated <code class=\"calibre9\">Program<\/code> class <em class=\"calibre10\">at the same level<\/em> as the <code class=\"calibre9\">&lt;Main&gt;$<\/code> method, instead of as local functions <em class=\"calibre10\">inside<\/em> the <code class=\"calibre9\">&lt;Main&gt;$<\/code> method.<\/p>\n<\/blockquote>\n<p class=\"rights\">It is important to note the lack of namespace declarations. Both the automatically generated <code class=\"calibre9\">Program<\/code> class and the explicitly defined <code class=\"calibre9\">Program<\/code> class are in the default <code class=\"calibre9\">null<\/code> namespace.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Do not define a namespace for your <code class=\"calibre9\">partial Program<\/code> class. If you do, it will be in a different namespace and therefore will not merge with the auto-generated <code class=\"calibre9\">partial Program<\/code> class.<\/p>\n<\/blockquote>\n<p class=\"rights\">Optionally, all the <code class=\"calibre9\">static<\/code> methods in the <code class=\"calibre9\">Program<\/code> class could be explicitly declared as <code class=\"calibre9\">private<\/code> but this is the default anyway. Since all the functions will be called within the <code class=\"calibre9\">Program<\/code> class itself the access modifier is not important.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"5.2.3\" id=\"calibre_link-204\">\n<h3 data-number=\"5.2.3\" class=\"calibre8\">Times table example<\/h3>\n<p class=\"rights\">Let's say that you want to help your child learn their times tables, so you want to make it easy to generate a times table for a number, such as the 7 times table:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">1 x 7 = 7\n2 x 7 = 14\n3 x 7 = 21\n...\n10 x 7 = 70\n11 x 7 = 77\n12 x 7 = 84<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Most times tables have either 10, 12, or 20 rows, depending on how advanced the child is.You learned about the <code class=\"calibre9\">for<\/code> statement earlier in this book, so you know that it can be used to generate repeated lines of output when there is a regular pattern, such as a 7 times table with 12 rows, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">for (int row = 1; row &lt;= 12; row++)\n{\n  Console.WriteLine($\"{row} x 7 = {row * 7}\");\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">However, instead of always outputting the 7 times table with 12 rows, we want to make this more flexible so it can output any size times table for any number. We can do this by creating a function.Let's explore functions by creating one to output any times table for numbers 0 to 255 of any size up to 255 rows (but it defaults to 12 rows):<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to create a new project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">WritingFunctions<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter04<\/code><\/li>\n<li class=\"calibre3\">In Visual Studio 2022, set the startup project for the solution to the current selection.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">WritingFunctions.csproj<\/code>, after the <code class=\"calibre9\">&lt;PropertyGroup&gt;<\/code> section, add a new <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> section to statically import <code class=\"calibre9\">System.Console<\/code> for all C# files using the <code class=\"calibre9\">implicit usings<\/code> .NET SDK feature, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a new class file to the project named <code class=\"calibre9\">Program.Functions.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, replace any existing code with new statements to define a function named <code class=\"calibre9\">TimesTable<\/code> in the partial <code class=\"calibre9\">Program<\/code> class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">partial class Program\n{\n  static void TimesTable(byte number, byte size = 12)\n  {\n    WriteLine($\"This is the {number} times table with {size} rows:\");\n    WriteLine();\n    for (int row = 1; row &lt;= size; row++)\n    {\n      WriteLine($\"{row} x {number} = {row * number}\");\n    }\n    WriteLine();\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">In the preceding code, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">TimesTable<\/code> must have a <code class=\"calibre9\">byte<\/code> value passed to it as a parameter named <code class=\"calibre9\">number<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">TimesTable<\/code> can optionally have a <code class=\"calibre9\">byte<\/code> value passed to it as a parameter named <code class=\"calibre9\">size<\/code>. If a value is not passed, it defaults to <code class=\"calibre9\">12<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">TimesTable<\/code> is a <code class=\"calibre9\">static<\/code> method because it will be called by the <code class=\"calibre9\">static<\/code> method <code class=\"calibre9\">&lt;Main&gt;$<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">TimesTable<\/code> does not return a value to the caller, so it is declared with the <code class=\"calibre9\">void<\/code> keyword before its name.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">TimesTable<\/code> uses a <code class=\"calibre9\">for<\/code> statement to output the times table for the <code class=\"calibre9\">number<\/code> passed to it with its number of rows equal to <code class=\"calibre9\">size<\/code>.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then call the function. Pass in a <code class=\"calibre9\">byte<\/code> value for the <code class=\"calibre9\">number<\/code> parameter, for example, <code class=\"calibre9\">7<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">TimesTable(7);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and then view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">This is the 7 times table with 12 rows:\n1 x 7 = 7\n2 x 7 = 14\n3 x 7 = 21\n4 x 7 = 28\n5 x 7 = 35\n6 x 7 = 42\n7 x 7 = 49\n8 x 7 = 56\n9 x 7 = 63\n10 x 7 = 70\n11 x 7 = 77\n12 x 7 = 84<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Set the <code class=\"calibre9\">size<\/code> parameter to <code class=\"calibre9\">20<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">TimesTable(7, 20);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Run the console app and confirm that the times table now has twenty rows.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If a function has one or more parameters where just passing the values may not provide enough meaning, then you can optionally specify the name of the parameter as well as its value, as shown in the following code: <code class=\"calibre9\">TimesTable(number: 7, size: 10)<\/code>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Change the number passed into the <code class=\"calibre9\">TimesTable<\/code> function to other <code class=\"calibre9\">byte<\/code> values between <code class=\"calibre9\">0<\/code> and <code class=\"calibre9\">255<\/code> and confirm that the output times tables are correct.<\/li>\n<li class=\"calibre3\">Note that if you try to pass a non-<code class=\"calibre9\">byte<\/code> number, for example, an <code class=\"calibre9\">int<\/code>, <code class=\"calibre9\">double<\/code>, or <code class=\"calibre9\">string<\/code>, an error is returned, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Error: (1,12): error CS1503: Argument 1: cannot convert from 'int' to 'byte'<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"5.2.4\" id=\"calibre_link-205\">\n<h3 data-number=\"5.2.4\" class=\"calibre8\">A brief aside about arguments and parameters<\/h3>\n<p class=\"rights\">In daily usage, most developers will use the terms <strong class=\"calibre2\">argument<\/strong> and <strong class=\"calibre2\">parameter<\/strong> interchangeably. Strictly speaking, the two terms have specific and subtly different meanings. But just like a person can be both a parent and a doctor, the two terms often apply to the same thing.A <em class=\"calibre10\">parameter<\/em> is a variable in a function definition. For example, <code class=\"calibre9\">startDate<\/code> is a parameter of the <code class=\"calibre9\">Hire<\/code> function, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">void Hire(DateTime startDate)\n{\n  \/\/ Function implementation.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When a method is called, an <em class=\"calibre10\">argument<\/em> is the data you pass into the method's parameters. For example, <code class=\"calibre9\">when<\/code> is a variable passed as an argument to the <code class=\"calibre9\">Hire<\/code> function, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">DateTime when = new(year: 2024, month: 11, day: 5);\nHire(when);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You might prefer to specify the parameter name when passing the argument, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">DateTime when = new(year: 2024, month: 11, day: 5);\nHire(startDate: when);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When talking about the call to the <code class=\"calibre9\">Hire<\/code> function, <code class=\"calibre9\">startDate<\/code> is the parameter, and <code class=\"calibre9\">when<\/code> is the argument.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you read the official Microsoft documentation, they use the phrases <strong class=\"calibre2\">named and optional arguments<\/strong> and <strong class=\"calibre2\">named and optional parameters<\/strong> interchangeably, as shown at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/classes-and-structs\/named-and-optional-arguments\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/classes-and-structs\/named-and-optional-arguments<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">It gets complicated because a single object can act as both a parameter and an argument, depending on context. For example, within the <code class=\"calibre9\">Hire<\/code> function implementation, the <code class=\"calibre9\">startDate<\/code> parameter could be passed as an argument to another function like <code class=\"calibre9\">SaveToDatabase<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">void Hire(DateTime startDate)\n{\n  ...\n  SaveToDatabase(startDate, employeeRecord);\n  ...\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Naming things is one of the hardest parts of computing. A classic example is the parameter to the most important function in C#, <code class=\"calibre9\">Main<\/code>. It defines a parameter named <code class=\"calibre9\">args<\/code>, short for arguments, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void Main(String[] args)\n{\n  ...\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To summarize, parameters define inputs to a function, arguments are passed to a function when calling the function.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Try to use the correct term depending on the context, but do not get pedantic with other developers if they \"misuse\" a term. I must have used the terms <strong class=\"calibre2\">parameter<\/strong> and <strong class=\"calibre2\">argument<\/strong> thousands of times in this book. I'm sure some of those times I've been imprecise. Please do not @ me about it.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"5.2.5\" id=\"calibre_link-206\">\n<h3 data-number=\"5.2.5\" class=\"calibre8\">Writing a function that returns a value<\/h3>\n<p class=\"rights\">The previous function performed actions (looping and writing to the console), but it did not return a value. Let's say that you need to calculate sales or <strong class=\"calibre2\">value-added tax<\/strong> (<strong class=\"calibre2\">VAT<\/strong>). In Europe, VAT rates can range from 8% in Switzerland to 27% in Hungary. In the United States, state sales taxes can range from 0% in Oregon to 8.25% in California.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Tax rates change all the time, and they vary based on many factors. The values used in this example do not need to be accurate.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's implement a function to calculate taxes in various regions around the world:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, in the <code class=\"calibre9\">Program<\/code> class, write a function named <code class=\"calibre9\">CalculateTax<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static decimal CalculateTax(\n  decimal amount, string twoLetterRegionCode)\n{\n  decimal rate = twoLetterRegionCode switch\n  {\n    \"CH\" =&gt; 0.08M, \/\/ Switzerland\n    \"DK\" or \"NO\" =&gt; 0.25M, \/\/ Denmark, Norway  \n    \"GB\" or \"FR\" =&gt; 0.2M, \/\/ UK, France\n    \"HU\" =&gt; 0.27M, \/\/ Hungary\n    \"OR\" or \"AK\" or \"MT\" =&gt; 0.0M, \/\/ Oregon, Alaska, Montana\n    \"ND\" or \"WI\" or \"ME\" or \"VA\" =&gt; 0.05M,\n    \"CA\" =&gt; 0.0825M, \/\/ California\n    _ =&gt; 0.06M \/\/ Most other states.\n  };\n  return amount * rate;\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">In the preceding code, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">CalculateTax<\/code> has two inputs: a parameter named <code class=\"calibre9\">amount<\/code>, which will be the amount of money spent, and a parameter named <code class=\"calibre9\">twoLetterRegionCode<\/code>, which will be the region the amount is spent in.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">CalculateTax<\/code> will perform a calculation using a <code class=\"calibre9\">switch<\/code> expression and then return the sales tax or VAT owed on the amount as a <code class=\"calibre9\">decimal<\/code> value; so, before the name of the function, we have declared the data type of the return value to be <code class=\"calibre9\">decimal<\/code>.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.Functions.cs<\/code>, import the namespace to work with cultures, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Globalization; \/\/ To use CultureInfo.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, in the <code class=\"calibre9\">Program<\/code> class, write a function named <code class=\"calibre9\">ConfigureConsole<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void ConfigureConsole(string culture = \"en-US\",\n  bool useComputerCulture = false)\n{\n  \/\/ To enable Unicode characters like Euro symbol in the console.\n  OutputEncoding = System.Text.Encoding.UTF8;\n  if (!useComputerCulture)\n  {\n    CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo(culture);\n  }\n  WriteLine($\"CurrentCulture: {CultureInfo.CurrentCulture.DisplayName}\");\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">This function enables UTF-8 encoding for the console output. This is necessary to output some special symbols like the Euro currency symbol. This function also controls the current culture used to format dates, times, and currency values.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out any <code class=\"calibre9\">TimesTable<\/code> method calls, and then call the <code class=\"calibre9\">ConfigureConsole<\/code> method and the <code class=\"calibre9\">CalculateTax<\/code> method, passing values for the amount such as <code class=\"calibre9\">149<\/code> and a valid region code such as <code class=\"calibre9\">FR<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ TimesTable(number: 7, size: 10);\nConfigureConsole();\ndecimal taxToPay = CalculateTax(amount: 149, twoLetterRegionCode: \"FR\");\nWriteLine($\"You must pay {taxToPay:C} in tax.\");\n\/\/ Alternatively, call the function in the interpolated string.\n\/\/ WriteLine($\"You must pay {CalculateTax(amount: 149,\n\/\/   twoLetterRegionCode: \"FR\"):C} in tax.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that it uses US English culture, meaning US dollars for the currency, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CurrentCulture: English (United States)\nYou must pay $29.80 in tax.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, change the <code class=\"calibre9\">ConfigureConsole<\/code> method to use your local computer culture, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ConfigureConsole(useComputerCulture: true);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that the currency should now show your local currency. For example, for me in the UK, I would see <code class=\"calibre9\">\u00a329.80<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CurrentCulture: English (United Kingdom)\nYou must pay \u00a329.80 in tax.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, change the <code class=\"calibre9\">ConfigureConsole<\/code> method to use French culture, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ConfigureConsole(culture: \"fr-FR\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that the currency should now show Euros as used in France, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CurrentCulture: French (France)\nYou must pay 29,80 \u20ac in tax.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Can you think of any problems with the <code class=\"calibre9\">CalculateTax<\/code> function as written? What would happen if the user entered a code such as <code class=\"calibre9\">fr<\/code> or <code class=\"calibre9\">UK<\/code>? How could you rewrite the function to improve it? Would using a <code class=\"calibre9\">switch<\/code> <em class=\"calibre10\">statement<\/em> instead of a <code class=\"calibre9\">switch<\/code> <em class=\"calibre10\">expression<\/em> be clearer?<\/p>\n<\/section>\n<section data-number=\"5.2.6\" id=\"calibre_link-207\">\n<h3 data-number=\"5.2.6\" class=\"calibre8\">Converting numbers from cardinal to ordinal<\/h3>\n<p class=\"rights\">Numbers that are used to count are called <strong class=\"calibre2\">cardinal<\/strong> numbers, for example, 1, 2, and 3, whereas numbers used to order are <strong class=\"calibre2\">ordinal<\/strong> numbers, for example, 1st, 2nd, and 3rd. Let's create a function to convert cardinals to ordinals:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, write a function named <code class=\"calibre9\">CardinalToOrdinal<\/code> that converts a cardinal <code class=\"calibre9\">uint<\/code> value into an ordinal <code class=\"calibre9\">string<\/code> value; for example, it converts <code class=\"calibre9\">1<\/code> into <code class=\"calibre9\">\"1st\"<\/code>, <code class=\"calibre9\">2<\/code> into <code class=\"calibre9\">\"2nd\"<\/code>, and so on, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static string CardinalToOrdinal(uint number)\n{\n  uint lastTwoDigits = number % 100;\n  switch (lastTwoDigits)\n  {\n    case 11: \/\/ Special cases for 11th to 13th.\n    case 12:\n    case 13:\n      return $\"{number:N0}th\";\n    default:\n      uint lastDigit = number % 10;\n      string suffix = lastDigit switch\n      {\n        1 =&gt; \"st\",\n        2 =&gt; \"nd\",\n        3 =&gt; \"rd\",\n        _ =&gt; \"th\"\n      };\n      return $\"{number:N0}{suffix}\";\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">From the preceding code, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">CardinalToOrdinal<\/code> has one input, a parameter of the <code class=\"calibre9\">uint<\/code> type named <code class=\"calibre9\">number<\/code> because we do not want to allow negative numbers, and one output: a return value of the <code class=\"calibre9\">string<\/code> type.<\/li>\n<li class=\"calibre3\">A <code class=\"calibre9\">switch<\/code> <em class=\"calibre10\">statement<\/em> is used to handle the special cases of 11, 12, and 13.<\/li>\n<li class=\"calibre3\">A <code class=\"calibre9\">switch<\/code> <em class=\"calibre10\">expression<\/em> then handles all other cases: if the last digit is 1, then use <code class=\"calibre9\">st<\/code> as the suffix; if the last digit is 2, then use <code class=\"calibre9\">nd<\/code> as the suffix; if the last digit is 3, then use <code class=\"calibre9\">rd<\/code> as the suffix; and if the last digit is anything else, then use <code class=\"calibre9\">th<\/code> as the suffix.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, write a function named <code class=\"calibre9\">RunCardinalToOrdinal<\/code> that uses a <code class=\"calibre9\">for<\/code> statement to loop from 1 to 150, calling the <code class=\"calibre9\">CardinalToOrdinal<\/code> function for each number and writing the returned <code class=\"calibre9\">string<\/code> to the console, separated by a space character, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void RunCardinalToOrdinal()\n{\n  for (uint number = 1; number &lt;= 150; number++)\n  {\n    Write($\"{CardinalToOrdinal(number)} \");\n  }\n  WriteLine();\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the <code class=\"calibre9\">CalculateTax<\/code> statements, and call the <code class=\"calibre9\">RunCardinalToOrdinal<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">RunCardinalToOrdinal();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app and view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th 47th 48th 49th 50th 51st 52nd 53rd 54th 55th 56th 57th 58th 59th 60th 61st 62nd 63rd 64th 65th 66th 67th 68th 69th 70th 71st 72nd 73rd 74th 75th 76th 77th 78th 79th 80th 81st 82nd 83rd 84th 85th 86th 87th 88th 89th 90th 91st 92nd 93rd 94th 95th 96th 97th 98th 99th 100th 101st 102nd 103rd 104th 105th 106th 107th 108th 109th 110th 111th 112th 113th 114th 115th 116th 117th 118th 119th 120th 121st 122nd 123rd 124th 125th 126th 127th 128th 129th 130th 131st 132nd 133rd 134th 135th 136th 137th 138th 139th 140th 141st 142nd 143rd 144th 145th 146th 147th 148th 149th 150th<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">RunCardinalToOrdinal<\/code> function, change the maximum number to <code class=\"calibre9\">1500<\/code>.<\/li>\n<li class=\"calibre3\">Run the console app and view the results, as shown partially in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">1,480th 1,481st 1,482nd 1,483rd 1,484th 1,485th 1,486th 1,487th 1,488th 1,489th 1,490th 1,491st 1,492nd 1,493rd 1,494th 1,495th 1,496th 1,497th 1,498th 1,499th 1,500th<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"5.2.7\" id=\"calibre_link-208\">\n<h3 data-number=\"5.2.7\" class=\"calibre8\">Calculating factorials with recursion<\/h3>\n<p class=\"rights\">The factorial of 5 is 120 because factorials are calculated by multiplying the starting number by one less than itself, and then by one less again, and so on until the number is reduced to 1. An example can be seen here: 5 x 4 x 3 x 2 x 1 = 120.The factorial function is defined for non-negative integers only, i.e., for 0, 1, 2, 3, and so on, and it is defined as:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">0! = 1 \nn! = n \u00d7 (n \u2212 1)!, for n \u2208 { 1, 2, 3, ... }<\/code><\/pre>\n<\/div>\n<p class=\"rights\">We could leave it to the compiler to reject negative numbers by declaring the input parameter as <code class=\"calibre9\">uint<\/code> as we did for the <code class=\"calibre9\">CardinalToOrdinal<\/code> function, but this time let's see an alternative way to handle that: throwing an argument exception.Factorials are written like this: <code class=\"calibre9\">5!<\/code>, where the exclamation mark is read as \u201cbang,\u201d so 5! = 120, or <em class=\"calibre10\">five bang equals one hundred and twenty<\/em>. Bang is a good term to use in the context of factorials because they increase in size very rapidly, just like an explosion.We will write a function named <code class=\"calibre9\">Factorial<\/code>; this will calculate the factorial for an <code class=\"calibre9\">int<\/code> passed to it as a parameter. We will use a clever technique called <strong class=\"calibre2\">recursion<\/strong>, which means a function that calls itself within its implementation, either directly or indirectly:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, write a function named <code class=\"calibre9\">Factorial<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static int Factorial(int number)\n{\n  if (number &lt; 0)\n  {\n     throw new ArgumentOutOfRangeException(message: \n       $\"The factorial function is defined for non-negative integers only. Input: {number}\", \n       paramName: nameof(number));\n  }\n  else if (number == 0)\n  {\n    return 1;\n  }\n  else\n  {\n    return number * Factorial(number - 1);\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">As before, there are several noteworthy elements in the preceding code, including the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">If the input parameter <code class=\"calibre9\">number<\/code> is negative, <code class=\"calibre9\">Factorial<\/code> throws an exception.<\/li>\n<li class=\"calibre3\">If the input parameter <code class=\"calibre9\">number<\/code> is zero, <code class=\"calibre9\">Factorial<\/code> returns <code class=\"calibre9\">1<\/code>.<\/li>\n<li class=\"calibre3\">If the input parameter <code class=\"calibre9\">number<\/code> is more than <code class=\"calibre9\">0<\/code> (which it will be in all other cases), <code class=\"calibre9\">Factorial<\/code> multiplies the number by the result of calling itself and passing one less than <code class=\"calibre9\">number<\/code>. This makes the function recursive.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: Recursion is clever, but it can lead to problems, such as a stack overflow due to too many function calls because memory is used to store data on every function call, and it eventually uses too much. Iteration is a more practical, if less succinct, solution in languages such as C#. You can read more about this at the following link: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Recursion_(computer_science)#Recursion_versus_iteration\">https:\/\/en.wikipedia.org\/wiki\/Recursion_(computer_science)#Recursion_versus_iteration<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, write a function named <code class=\"calibre9\">RunFactorial<\/code> that uses a <code class=\"calibre9\">for<\/code> statement to output the factorials of numbers from 1 to 15, calls the <code class=\"calibre9\">Factorial<\/code> function inside its loop, and then outputs the result, formatted using the code <code class=\"calibre9\">N0<\/code>, which means number format using thousand separators with zero decimal places, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void RunFactorial()\n{\n  for (int i = 1; i &lt;= 15; i++)\n  {\n    WriteLine($\"{i}! = {Factorial(i):N0}\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Comment out the <code class=\"calibre9\">RunCardinalToOrdinal<\/code> method call and call the <code class=\"calibre9\">RunFactorial<\/code> method.<\/li>\n<li class=\"calibre3\">Run the project and view the results, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">1! = 1\n2! = 2\n3! = 6\n4! = 24\n...\n12! = 479,001,600\n13! = 1,932,053,504\n14! = 1,278,945,280\n15! = 2,004,310,016<\/code><\/pre>\n<\/div>\n<p class=\"rights\">It is not immediately obvious in the previous output, but factorials of 13 and higher overflow the <code class=\"calibre9\">int<\/code> type because they are so big. <code class=\"calibre9\">12!<\/code> is 479,001,600, which is about half a billion. The maximum positive value that can be stored in an <code class=\"calibre9\">int<\/code> variable is about two billion. <code class=\"calibre9\">13!<\/code> is 6,227,020,800, which is about six billion, and when stored in a 32-bit integer, it overflows silently without showing any problems.What should you do to get notified when an overflow happens? Of course, we could solve the problem for <code class=\"calibre9\">13!<\/code> and <code class=\"calibre9\">14!<\/code> by using a <code class=\"calibre9\">long<\/code> (64-bit integer) instead of an <code class=\"calibre9\">int<\/code> (32-bit integer), but we will quickly hit the overflow limit again.The point of this section is to understand and show you that numbers can overflow, and not specifically how to calculate factorials higher than <code class=\"calibre9\">12!<\/code>. Let\u2019s take a look:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the <code class=\"calibre9\">Factorial<\/code> function to check for overflows in the statement that calls itself, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">checked \/\/ for overflow\n{\n  return number * Factorial(number - 1);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the <code class=\"calibre9\">RunFactorial<\/code> function to change the starting number to <code class=\"calibre9\">-2<\/code> and to handle overflow and other exceptions when calling the <code class=\"calibre9\">Factorial<\/code> function, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void RunFactorial()\n{\n  for (int i = -2; i &lt;= 15; i++)\n  {\n    try\n    {\n      WriteLine($\"{i}! = {Factorial(i):N0}\");\n    }\n    catch (OverflowException)\n    {\n      WriteLine($\"{i}! is too big for a 32-bit integer.\");\n    }\n    catch (Exception ex)\n    {\n      WriteLine($\"{i}! throws {ex.GetType()}: {ex.Message}\");\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the results, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">-2! throws System.ArgumentOutOfRangeException: The factorial function is defined for non-negative integers only. Input: -2 (Parameter 'number')\n-1! throws System.ArgumentOutOfRangeException: The factorial function is defined for non-negative integers only. Input: -1 (Parameter 'number')\n0! = 1\n1! = 1\n2! = 2\n...\n12! = 479,001,600\n13! is too big for a 32-bit integer.\n14! is too big for a 32-bit integer.\n15! is too big for a 32-bit integer.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"5.2.8\" id=\"calibre_link-209\">\n<h3 data-number=\"5.2.8\" class=\"calibre8\">Documenting functions with XML comments<\/h3>\n<p class=\"rights\">By default, when calling a function such as <code class=\"calibre9\">CardinalToOrdinal<\/code>, code editors will show a tooltip with basic information.Let's improve the tooltip by adding extra information:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you are using Visual Studio Code with the <strong class=\"calibre2\">C#<\/strong> extension, you should navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Command Palette<\/strong> | <strong class=\"calibre2\">Preferences: Open Settings (UI)<\/strong>, and then search for <code class=\"calibre9\">formatOnType<\/code> and make sure that it is enabled. C# XML documentation comments are a built-in feature of Visual Studio 2022 and JetBrains Rider, so you do not need to do anything to use them.<\/li>\n<li class=\"calibre3\">On the line above the <code class=\"calibre9\">CardinalToOrdinal<\/code> function, type three forward slashes <code class=\"calibre9\">\/\/\/<\/code>, and note that they are expanded into an XML comment that recognizes that the function has a single parameter named <code class=\"calibre9\">number<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/\/ &lt;summary&gt;\n\/\/\/ \n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=\"number\"&gt;&lt;\/param&gt;\n\/\/\/ &lt;returns&gt;&lt;\/returns&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Enter suitable information for the XML documentation comment for the <code class=\"calibre9\">CardinalToOrdinal<\/code> function. Add a summary, and describe the input parameter and the return value, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/\/ &lt;summary&gt;\n\/\/\/ Pass a 32-bit unsigned integer and it will be converted into its ordinal equivalent.\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=\"number\"&gt;Number as a cardinal value e.g. 1, 2, 3, and so on.&lt;\/param&gt;\n\/\/\/ &lt;returns&gt;Number as an ordinal value e.g. 1st, 2nd, 3rd, and so on.&lt;\/returns&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Now, when calling the function, you will see more details, as shown in <em class=\"calibre10\">Figure 4.2<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.2: A tooltip showing the more detailed method signature\" height=\"641\" src=\"\/images\/cs12\/000123.png\" width=\"2161\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.2: A tooltip showing the more detailed method signature<\/figcaption><\/figure>\n<p class=\"rights\">It is worth emphasizing that this feature is primarily designed to be used with a tool that converts the comments into documentation, like Sandcastle, which you can read more about at the following link: <a href=\"https:\/\/github.com\/EWSoftware\/SHFB\">https:\/\/github.com\/EWSoftware\/SHFB<\/a>. The tooltips that appear while entering code or hovering over the function name are a secondary feature.Local functions do not support XML comments because local functions cannot be used outside the member in which they are declared, so it makes no sense to generate documentation from them. Sadly, this also means no tooltip, which would still be useful, but neither Visual Studio 2022 nor Visual Studio Code recognize that.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Add XML documentation comments to all your functions except local functions.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"5.2.9\" id=\"calibre_link-210\">\n<h3 data-number=\"5.2.9\" class=\"calibre8\">Using lambdas in function implementations<\/h3>\n<p class=\"rights\"><strong class=\"calibre2\">F#<\/strong> is Microsoft's strongly typed functional-first programming language that, like C#, compiles to Intermediate Language (IL) to be executed by .NET. Functional languages evolved from lambda calculus, a computational system based only on functions. The code looks more like mathematical functions than steps in a recipe.Some of the important attributes of functional languages are defined in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Modularity<\/strong>: The same benefit of defining functions in C# applies to functional languages. Breaks up a large complex code base into smaller pieces.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Immutability<\/strong>: Variables in the C# sense do not exist. Any data value inside a function cannot change. Instead, a new data value can be created from an existing one. This reduces bugs.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Maintainability<\/strong>: Code is cleaner and clearer (for mathematically-inclined programmers!).<\/li>\n<\/ul>\n<p class=\"rights\">Since C# 6, Microsoft has worked to add features to the language to support a more functional approach, for example, adding <strong class=\"calibre2\">tuples<\/strong> and <strong class=\"calibre2\">pattern matching<\/strong> in C# 7, <strong class=\"calibre2\">non-null reference types<\/strong> in C# 8, and improving pattern matching and adding records, that is, potentially <strong class=\"calibre2\">immutable objects<\/strong>, in C# 9.In C# 6, Microsoft added support for <strong class=\"calibre2\">expression-bodied function members<\/strong>. We will look at an example of this now. In C#, lambdas are the use of the <code class=\"calibre9\">=&gt;<\/code> character to indicate a return value from a function.The <strong class=\"calibre2\">Fibonacci sequence<\/strong> of numbers always starts with 0 and 1. Then the rest of the sequence is generated using the rule of adding together the previous two numbers, as shown in the following sequence of numbers:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">0 1 1 2 3 5 8 13 21 34 55 ...<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The next term in the sequence would be 34 + 55, which is 89.We will use the Fibonacci sequence to illustrate the difference between an imperative and declarative function implementation:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, write a function named <code class=\"calibre9\">FibImperative<\/code>, which will be written in an imperative style, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static int FibImperative(uint term)\n{\n  if (term == 0)\n  {\n    throw new ArgumentOutOfRangeException();\n  }\n  else if (term == 1)\n  {\n    return 0;\n  }\n  else if (term == 2)\n  {\n    return 1;\n  }\n  else\n  {\n    return FibImperative(term - 1) + FibImperative(term - 2);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, write a function named <code class=\"calibre9\">RunFibImperative<\/code> that calls <code class=\"calibre9\">FibImperative<\/code> inside a <code class=\"calibre9\">for<\/code> statement that loops from 1 to 30, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void RunFibImperative()\n{\n  for (uint i = 1; i &lt;= 30; i++)\n  {\n    WriteLine(\"The {0} term of the Fibonacci sequence is {1:N0}.\",\n      arg0: CardinalToOrdinal(i),\n      arg1: FibImperative(term: i));\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the other method calls, and call the <code class=\"calibre9\">RunFibImperative<\/code> method.<\/li>\n<li class=\"calibre3\">Run the console app and view the results, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">The 1st term of the Fibonacci sequence is 0.\nThe 2nd term of the Fibonacci sequence is 1.\nThe 3rd term of the Fibonacci sequence is 1.\nThe 4th term of the Fibonacci sequence is 2.\nThe 5th term of the Fibonacci sequence is 3.\n...\nThe 29th term of the Fibonacci sequence is 317,811.\nThe 30th term of the Fibonacci sequence is 514,229.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, write a function named <code class=\"calibre9\">FibFunctional<\/code> written in a declarative style, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static int FibFunctional(uint term) =&gt; term switch\n  {\n    0 =&gt; throw new ArgumentOutOfRangeException(),\n    1 =&gt; 0,\n    2 =&gt; 1,\n    _ =&gt; FibFunctional(term - 1) + FibFunctional(term - 2)\n  };<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, write a function to call it inside a <code class=\"calibre9\">for<\/code> statement that loops from 1 to 30, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void RunFibFunctional()\n{\n  for (uint i = 1; i &lt;= 30; i++)\n  {\n    WriteLine(\"The {0} term of the Fibonacci sequence is {1:N0}.\",\n      arg0: CardinalToOrdinal(i),\n      arg1: FibFunctional(term: i));\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the <code class=\"calibre9\">RunFibImperative<\/code> method call, and call the <code class=\"calibre9\">RunFibFunctional<\/code> method.<\/li>\n<li class=\"calibre3\">Run the code and view the results (which will be the same as before).<\/li>\n<\/ol>\n<p class=\"rights\">Now that you have seen some examples of functions, let's see how you can fix them when they have bugs.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"5.3\" id=\"calibre_link-211\">\n<h2 data-number=\"5.3\" class=\"calibre5\">Debugging during development<\/h2>\n<p class=\"rights\">In this section, you will learn how to debug problems at development time. You must use a code editor that has debugging tools, such as Visual Studio 2022 or Visual Studio Code.<\/p>\n<section data-number=\"5.3.1\" id=\"calibre_link-212\">\n<h3 data-number=\"5.3.1\" class=\"calibre8\">Creating code with a deliberate bug<\/h3>\n<p class=\"rights\">Let's explore debugging by creating a console app with a deliberate bug, which we will then use the debugger tools in your code editor to track down and fix:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">Debugging<\/code> to the <code class=\"calibre9\">Chapter04<\/code> solution.<\/li>\n<li class=\"calibre3\">Modify <code class=\"calibre9\">Debugging.csproj<\/code> to statically import <code class=\"calibre9\">System.Console<\/code> for all code files.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete any existing statements and then, at the bottom of the file, add a function with a deliberate bug, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">double Add(double a, double b)\n{\n  return a * b; \/\/ Deliberate bug!\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Above the <code class=\"calibre9\">Add<\/code> function, write statements to declare and set some variables and then add them together using the buggy function, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">double a = 4.5;\ndouble b = 2.5;\ndouble answer = Add(a, b);\nWriteLine($\"{a} + {b} = {answer}\");\nWriteLine(\"Press Enter to end the app.\");\nReadLine(); \/\/ Wait for user to press Enter.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console application and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">4.5 + 2.5 = 11.25\nPress Enter to end the app.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">But wait, there's a bug! 4.5 added to 2.5 should be 7, not 11.25!We will use the debugging tools to hunt for and squish the bug.<\/p>\n<\/section>\n<section data-number=\"5.3.2\" id=\"calibre_link-213\">\n<h3 data-number=\"5.3.2\" class=\"calibre8\">Setting a breakpoint and starting debugging<\/h3>\n<p class=\"rights\">Breakpoints allow us to mark a line of code that we want to pause at to inspect the program state and find bugs.<\/p>\n<section data-number=\"5.3.2.1\" id=\"calibre_link-1922\">\n<h4 data-number=\"5.3.2.1\" class=\"calibre15\">Using Visual Studio 2022<\/h4>\n<p class=\"rights\">Let's set a breakpoint and then start debugging using Visual Studio 2022:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Click in line 1, which is the statement that declares the variable named <code class=\"calibre9\">a<\/code>.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Toggle Breakpoint<\/strong> or press <span>F9<\/span>. A red circle will appear in the margin bar on the left-hand side and the statement will be highlighted in red to indicate that a breakpoint has been set, as shown in <em class=\"calibre10\">Figure 4.3<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.3: Toggling breakpoints using Visual Studio 2022\" height=\"569\" src=\"\/images\/cs12\/000023.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.3: Toggling breakpoints using Visual Studio 2022<\/figcaption><\/figure>\n<p class=\"rights\">Breakpoints can be toggled off with the same action. You can also left-click in the margin to toggle a breakpoint on and off, or right-click a breakpoint to see more options, such as delete, disable, or edit conditions or actions for an existing breakpoint.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Debugging<\/strong> or press <span>F5<\/span>. Visual Studio starts the console application and then pauses when it hits the breakpoint. This is known as <em class=\"calibre10\">break mode<\/em>. Extra windows titled <strong class=\"calibre2\">Locals<\/strong> (showing current values of local variables), <strong class=\"calibre2\">Watch 1<\/strong> (showing any watch expressions you have defined), <strong class=\"calibre2\">Call Stack<\/strong>, <strong class=\"calibre2\">Exception Settings<\/strong>, and <strong class=\"calibre2\">Immediate Window<\/strong> may appear. The <strong class=\"calibre2\">Debugging<\/strong> toolbar appears. The line that will be executed next is highlighted in yellow, and a yellow arrow points at the line from the margin bar, as shown in <em class=\"calibre10\">Figure 4.4<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.4: Break mode in Visual Studio 2022\" height=\"862\" src=\"\/images\/cs12\/000040.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.4: Break mode in Visual Studio 2022<\/figcaption><\/figure>\n<p class=\"rights\">If you do not want to see how to use Visual Studio Code to start debugging, then you can skip the <em class=\"calibre10\">Using Visual Studio Code<\/em> section and continue to the section titled <em class=\"calibre10\">Navigating with the debugging toolbar<\/em>.<\/p>\n<\/section>\n<section data-number=\"5.3.2.2\" id=\"calibre_link-1923\">\n<h4 data-number=\"5.3.2.2\" class=\"calibre15\">Using Visual Studio Code<\/h4>\n<p class=\"rights\">Let's set a breakpoint and then start debugging using Visual Studio Code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Click in line 1, which is the statement that declares the variable named <code class=\"calibre9\">a<\/code>.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Run<\/strong> | <strong class=\"calibre2\">Toggle Breakpoint<\/strong> or press <span>F9<\/span>. A red circle will appear in the margin bar on the left-hand side to indicate that a breakpoint has been set.<\/li>\n<\/ol>\n<p class=\"rights\">Breakpoints can be toggled off with the same action. You can also left-click in the margin to toggle a breakpoint on and off; right-click to see more options, such as remove, edit, or disable an existing breakpoint; or add a breakpoint, conditional breakpoint, or logpoint when a breakpoint does not yet exist.<strong class=\"calibre2\">Logpoints<\/strong>, also known as <strong class=\"calibre2\">tracepoints<\/strong>, indicate that you want to record some information without having to stop executing the code at that point.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Run<\/strong>, or in the left navigation bar, you can click the <strong class=\"calibre2\">Run and Debug<\/strong> icon (the triangle \"play\" button and \"bug\") or press <span>Ctrl<\/span> + <span>Shift<\/span> + <span>D<\/span> (on Windows).<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">At the top of the <strong class=\"calibre2\">RUN AND DEBUG<\/strong> window, click the <strong class=\"calibre2\">Run and Debug<\/strong> button, and then select the <strong class=\"calibre2\">Debugging<\/strong> project, as shown in <em class=\"calibre10\">Figure 4.5<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.5: Selecting the project to debug using Visual Studio Code\" height=\"476\" src=\"\/images\/cs12\/000089.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.5: Selecting the project to debug using Visual Studio Code<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you are first prompted to choose a debugger, select <strong class=\"calibre2\">C#<\/strong>, not .NET 5+ or .NET Core.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Visual Studio Code starts the console app and then pauses when it hits the breakpoint. This is known as <strong class=\"calibre2\">break mode<\/strong>. The line that will be executed next is highlighted in yellow, and a yellow block points at the line from the margin bar, as shown in <em class=\"calibre10\">Figure 4.6<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.6: Break mode in Visual Studio Code\" height=\"540\" src=\"\/images\/cs12\/000168.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.6: Break mode in Visual Studio Code<\/figcaption><\/figure>\n<\/section>\n<\/section>\n<section data-number=\"5.3.3\" id=\"calibre_link-214\">\n<h3 data-number=\"5.3.3\" class=\"calibre8\">Navigating with the debugging toolbar<\/h3>\n<p class=\"rights\">Visual Studio 2022 has two debug-related buttons in its <strong class=\"calibre2\">Standard<\/strong> toolbar to start or continue debugging and to hot reload changes to the running code, and a separate <strong class=\"calibre2\">Debug<\/strong> toolbar for the rest of the tools. Visual Studio Code shows a floating toolbar with buttons to make it easy to access debugging features.Both are shown in <em class=\"calibre10\">Figure 4.7<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.7: Debugging toolbars in Visual Studio 2022 and Visual Studio Code\" height=\"577\" src=\"\/images\/cs12\/000008.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.7: Debugging toolbars in Visual Studio 2022 and Visual Studio Code<\/figcaption><\/figure>\n<p class=\"rights\">The following list describes the most common buttons in the toolbars:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Start<\/strong>\/<strong class=\"calibre2\">Continue<\/strong>\/<span>F5<\/span>: This button is context-sensitive. It will either start a project running or continue running the project from the current position until it ends or hits a breakpoint.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Hot Reload<\/strong>: This button will reload compiled code changes without needing to restart the app.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Break All<\/strong>: This button will break into the next available line of code in a running app.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Stop Debugging<\/strong>\/<strong class=\"calibre2\">Stop<\/strong>\/<span>Shift<\/span> + <span>F5<\/span> (red square): This button will stop the debugging session.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Restart<\/strong>\/<span>Ctrl<\/span> or <span>Cmd<\/span> + <span>Shift<\/span> + <span>F5<\/span> (circular arrow): This button will stop and then immediately restart the program with the debugger attached again.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Show Next Statement<\/strong>: This button will move the current cursor to the next statement that will execute.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Step Into<\/strong>\/<span>F11<\/span>, <strong class=\"calibre2\">Step Over<\/strong>\/<span>F10<\/span>, and <strong class=\"calibre2\">Step Out<\/strong>\/<span>Shift<\/span> + <span>F11<\/span> (blue arrows over dots): These buttons step through the code statements in various ways, as you will see in a moment.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Show Threads in Source<\/strong>: This button allows you to examine and work with threads in the application that you're debugging.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"5.3.4\" id=\"calibre_link-215\">\n<h3 data-number=\"5.3.4\" class=\"calibre8\">Debugging windows<\/h3>\n<p class=\"rights\">While debugging, both Visual Studio 2022 and Visual Studio Code show extra windows that allow you to monitor useful information, such as variables, while you step through your code.The most useful windows are described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">VARIABLES<\/strong>, including <strong class=\"calibre2\">Locals<\/strong>, which shows the name, value, and type of any local variables automatically. Keep an eye on this window while you step through your code.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">WATCH<\/strong>, or <strong class=\"calibre2\">Watch 1<\/strong>, which shows the value of variables and expressions that you manually enter.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">CALL STACK<\/strong>, which shows the stack of function calls.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">BREAKPOINTS<\/strong>, which shows all your breakpoints and allows finer control over them.<\/li>\n<\/ul>\n<p class=\"rights\">When in break mode, there is also a useful window at the bottom of the edit area:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">DEBUG CONSOLE<\/strong> or <strong class=\"calibre2\">Immediate Window<\/strong> enables live interaction with your code. You can interrogate the program state, for example, by entering the name of a variable. For example, you can ask a question such as \"What is 1+2?\" by typing <code class=\"calibre9\">1+2<\/code> and pressing <span>Enter<\/span>.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"5.3.5\" id=\"calibre_link-216\">\n<h3 data-number=\"5.3.5\" class=\"calibre8\">Stepping through code<\/h3>\n<p class=\"rights\">Let's explore some ways to step through the code using either Visual Studio 2022 or Visual Studio Code:<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The menu commands for debugging are on the <strong class=\"calibre2\">Debug<\/strong> menu in Visual Studio 2022 or the <strong class=\"calibre2\">Run<\/strong> menu in Visual Studio Code and JetBrains Rider.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Run<\/strong> or <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Step Into<\/strong>, click on the <strong class=\"calibre2\">Step Into<\/strong> button in the toolbar, or press <span>F11<\/span>. The yellow highlight steps forward one line.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Run<\/strong> or <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Step Over<\/strong>, click on the <strong class=\"calibre2\">Step Over<\/strong> button in the toolbar, or press <span>F10<\/span>. The yellow highlight steps forward one line. At the moment, you can see that there is no difference between using <strong class=\"calibre2\">Step Into<\/strong> or <strong class=\"calibre2\">Step Over<\/strong> because we are executing single statements.<\/li>\n<li class=\"calibre3\">You should now be on the line that calls the <code class=\"calibre9\">Add<\/code> method.<\/li>\n<\/ol>\n<p class=\"rights\">The difference between <strong class=\"calibre2\">Step Into<\/strong> and <strong class=\"calibre2\">Step Over<\/strong> can be seen when you are about to execute a method call:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">If you click on <strong class=\"calibre2\">Step Into<\/strong>, the debugger steps <em class=\"calibre10\">into<\/em> the method so that you can step through every line in that method.<\/li>\n<li class=\"calibre3\">If you click on <strong class=\"calibre2\">Step Over<\/strong>, the whole method is executed in one go; it does not skip over the method without executing it.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">Click on <strong class=\"calibre2\">Step Into<\/strong> to step inside the <code class=\"calibre9\">Add<\/code> method.<\/li>\n<li class=\"calibre3\">Hover your mouse pointer over the <code class=\"calibre9\">a<\/code> or <code class=\"calibre9\">b<\/code> parameters in the code editing window and note that a tooltip appears showing their current value.<\/li>\n<li class=\"calibre3\">Select the expression <code class=\"calibre9\">a * b<\/code>, right-click the expression, and select <strong class=\"calibre2\">Add to Watch<\/strong> or <strong class=\"calibre2\">Add Watch<\/strong>. The expression is added to the <strong class=\"calibre2\">WATCH<\/strong> or <strong class=\"calibre2\">Watch 1<\/strong> window, showing that this operator is multiplying <code class=\"calibre9\">a<\/code> by <code class=\"calibre9\">b<\/code> to give the result <code class=\"calibre9\">11.25<\/code>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">WATCH<\/strong> or <strong class=\"calibre2\">Watch 1<\/strong> window, right-click the expression and choose <strong class=\"calibre2\">Remove Expression<\/strong> or <strong class=\"calibre2\">Delete Watch<\/strong>.<\/li>\n<li class=\"calibre3\">Fix the bug by changing <code class=\"calibre9\">*<\/code> to <code class=\"calibre9\">+<\/code> in the <code class=\"calibre9\">Add<\/code> function.<\/li>\n<li class=\"calibre3\">Restart debugging by clicking the circular arrow <strong class=\"calibre2\">Restart<\/strong> button or pressing <span>Ctrl<\/span> or <span>Cmd<\/span> + <span>Shift<\/span> + <span>F5<\/span>.<\/li>\n<li class=\"calibre3\">Step over the function, take a minute to note how it now calculates correctly, and click the <strong class=\"calibre2\">Continue<\/strong> button or press <span>F5<\/span>.<\/li>\n<li class=\"calibre3\">With Visual Studio Code, note that when writing to the console during debugging, the output appears in the <strong class=\"calibre2\">DEBUG CONSOLE<\/strong> window instead of the <strong class=\"calibre2\">TERMINAL<\/strong> window, as shown in <em class=\"calibre10\">Figure 4.8<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.8: Writing to the DEBUG CONSOLE during debugging\" height=\"540\" src=\"\/images\/cs12\/000022.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.8: Writing to the DEBUG CONSOLE during debugging<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"5.3.6\" id=\"calibre_link-217\">\n<h3 data-number=\"5.3.6\" class=\"calibre8\">Using the Visual Studio Code integrated terminal during debugging<\/h3>\n<p class=\"rights\">By default, the console is set to use the internal <strong class=\"calibre2\">DEBUG CONSOLE<\/strong> during debugging, which does not allow interactions like entering text from the <code class=\"calibre9\">ReadLine<\/code> method.To improve the experience, we can change a setting to use the integrated terminal instead. First, let's modify the code to require interaction with the user:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.cs<\/code>, add statements to prompt the user to enter a number and parse that as a <code class=\"calibre9\">double<\/code> into the variable <code class=\"calibre9\">a<\/code>, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Write(\"Enter a number: \");\nstring number = ReadLine()!;\ndouble a = double.Parse(number);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Set a breakpoint on line 1 that writes the prompt, <code class=\"calibre9\">Enter a number<\/code>.<\/li>\n<li class=\"calibre3\">At the top of the <strong class=\"calibre2\">RUN AND DEBUG<\/strong> window, click the <strong class=\"calibre2\">Run and Debug<\/strong> button, and then select the <strong class=\"calibre2\">Debugging<\/strong> project.<\/li>\n<li class=\"calibre3\">Note that the <code class=\"calibre9\">Enter a number<\/code> prompt is not written to either <strong class=\"calibre2\">TERMINAL<\/strong> or <strong class=\"calibre2\">DEBUG CONSOLE<\/strong> and neither window is waiting for the user to enter a number and press <span>Enter<\/span>.<\/li>\n<li class=\"calibre3\">Stop debugging.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">At the top of the <strong class=\"calibre2\">RUN AND DEBUG<\/strong> window, click the <strong class=\"calibre2\">create a launch.json file<\/strong> link, and then, when prompted for the debugger, select <strong class=\"calibre2\">C#<\/strong>, as shown in <em class=\"calibre10\">Figure 4.9<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.9: Selecting a debugger for the launch.json file\" height=\"446\" src=\"\/images\/cs12\/000117.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.9: Selecting a debugger for the launch.json file<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <code class=\"calibre9\">launch.json<\/code> file editor, click the <strong class=\"calibre2\">Add Configuration...<\/strong> button, and then select <strong class=\"calibre2\">.NET: Launch .NET Core Console App<\/strong>, as shown in <em class=\"calibre10\">Figure 4.10<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.10: Adding a launch configuration for a .NET Console App\" height=\"446\" src=\"\/images\/cs12\/000134.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.10: Adding a launch configuration for a .NET Console App<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">launch.json<\/code>, make the following additions and changes, as shown highlighted in the following configuration:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Comment out the <code class=\"calibre9\">preLaunchTask<\/code> setting.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">program<\/code> path, add the <code class=\"calibre9\">Debugging<\/code> project folder after the <code class=\"calibre9\">workspaceFolder <\/code>variable.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">program<\/code> path, change <code class=\"calibre9\">&lt;target-framework&gt;<\/code> to <code class=\"calibre9\">net8.0<\/code>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">program<\/code> path, change <code class=\"calibre9\">&lt;project-name.dll&gt;<\/code> to <code class=\"calibre9\">Debugging.dll<\/code>.<\/li>\n<li class=\"calibre3\">Change the <code class=\"calibre9\">console<\/code> setting from <code class=\"calibre9\">internalConsole<\/code> to <code class=\"calibre9\">integratedTerminal<\/code>:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \/\/ Use IntelliSense to learn about possible attributes.\n  \/\/ Hover to view descriptions of existing attributes.\n  \/\/ For more information, visit: https:\/\/go.microsoft.com\/fwlink\/?linkid=830387\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"name\": \".NET Core Launch (console)\",\n      \"type\": \"coreclr\",\n      \"request\": \"launch\",\n      \/\/\"preLaunchTask\": \"build\",\n      \"program\": \"${workspaceFolder}\/Debugging\/bin\/Debug\/net8.0\/Debugging.dll\",\n      \"args\": [],\n      \"cwd\": \"${workspaceFolder}\",\n      \"stopAtEntry\": false,\n      \"console\": \"integratedTerminal\"\n    }\n  ]\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Remember that with Visual Studio Code, we open the <code class=\"calibre9\">Chapter04<\/code> folder to process the solution file, so the workspace folder is <code class=\"calibre9\">Chapter04<\/code>, not the <code class=\"calibre9\">Debugging<\/code> project.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of the <strong class=\"calibre2\">RUN AND DEBUG<\/strong> window, note the dropdown list of launch configurations, and click the <strong class=\"calibre2\">Start Debugging<\/strong> button (green triangle), as shown in <em class=\"calibre10\">Figure 4.11<\/em>.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Terminal<\/strong> and note the <strong class=\"calibre2\">TERMINAL<\/strong> window is attached to the <strong class=\"calibre2\">Debugging.dll<\/strong>, as shown in <em class=\"calibre10\">Figure 4.11<\/em>.<\/li>\n<li class=\"calibre3\">Step over the statement that writes <code class=\"calibre9\">Enter a number:<\/code> to the console.<\/li>\n<li class=\"calibre3\">Step over the statement that calls <code class=\"calibre9\">ReadLine<\/code>.<\/li>\n<li class=\"calibre3\">Type <code class=\"calibre9\">5.5<\/code> and press <span>Enter<\/span>.<\/li>\n<li class=\"calibre3\">Continue stepping through the statements or press <span>F5<\/span> or click <strong class=\"calibre2\">Continue<\/strong>, and note the output written to the integrated terminal, as shown in <em class=\"calibre10\">Figure 4.11<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.11: A launch configuration set to use the integrated terminal for user interaction\" height=\"577\" src=\"\/images\/cs12\/000151.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.11: A launch configuration set to use the integrated terminal for user interaction<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"5.3.7\" id=\"calibre_link-218\">\n<h3 data-number=\"5.3.7\" class=\"calibre8\">Customizing breakpoints<\/h3>\n<p class=\"rights\">It is easy to make more complex breakpoints:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you are still debugging, click the <strong class=\"calibre2\">Stop<\/strong> button in the debugging toolbar, navigate to <strong class=\"calibre2\">Run<\/strong> or <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Stop Debugging<\/strong>, or press <span>Shift<\/span> + <span>F5<\/span>.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Run<\/strong> | <strong class=\"calibre2\">Remove All Breakpoints<\/strong> or <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Delete All Breakpoints<\/strong>.<\/li>\n<li class=\"calibre3\">Click on the <code class=\"calibre9\">WriteLine<\/code> statement that outputs the answer.<\/li>\n<li class=\"calibre3\">Set a breakpoint by pressing <span>F9<\/span> or navigating to <strong class=\"calibre2\">Run<\/strong> or <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Toggle Breakpoint<\/strong>.<\/li>\n<li class=\"calibre3\">Right-click the breakpoint and choose the appropriate menu for your code editor:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">In Visual Studio Code, choose <strong class=\"calibre2\">Edit Breakpoint...<\/strong>.<\/li>\n<li class=\"calibre3\">In Visual Studio 2022, choose <strong class=\"calibre2\">Conditions...<\/strong>.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Type an expression, such as the <code class=\"calibre9\">answer<\/code> variable must be greater than <code class=\"calibre9\">9<\/code>, and then press <span>Enter<\/span> to accept it, and note the expression must evaluate to <em class=\"calibre10\">true<\/em> for the breakpoint to activate, as shown in <em class=\"calibre10\">Figure 4.12<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.12: Customizing a breakpoint with an expression using Visual Studio Code\" height=\"358\" src=\"\/images\/cs12\/000067.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.12: Customizing a breakpoint with an expression using Visual Studio Code<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Start debugging and note the breakpoint is not hit.<\/li>\n<li class=\"calibre3\">Stop debugging.<\/li>\n<li class=\"calibre3\">Edit the breakpoint or its conditions and change its expression to less than <code class=\"calibre9\">9<\/code>.<\/li>\n<li class=\"calibre3\">Start debugging and note the breakpoint is hit.<\/li>\n<li class=\"calibre3\">Stop debugging.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Edit the breakpoint or its conditions (in Visual Studio 2022, click <strong class=\"calibre2\">Add condition<\/strong>), select <strong class=\"calibre2\">Hit Count<\/strong>, then enter a number such as <code class=\"calibre9\">3<\/code>, meaning that you would have to hit the breakpoint three times before it activates, as shown in <em class=\"calibre10\">Figure 4.13<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.13: Customizing a breakpoint with an expression and hot count using Visual Studio 2022\" height=\"936\" src=\"\/images\/cs12\/000084.png\" width=\"2162\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.13: Customizing a breakpoint with an expression and hot count using Visual Studio 2022<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Hover your mouse over the breakpoint's red circle to see a summary, as shown in <em class=\"calibre10\">Figure 4.14<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.14: A summary of a customized breakpoint in Visual Studio Code\" height=\"358\" src=\"\/images\/cs12\/000100.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.14: A summary of a customized breakpoint in Visual Studio Code<\/figcaption><\/figure>\n<p class=\"rights\">You have now fixed a bug using some debugging tools and seen some advanced possibilities for setting breakpoints.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"5.4\" id=\"calibre_link-219\">\n<h2 data-number=\"5.4\" class=\"calibre5\">Hot reloading during development<\/h2>\n<p class=\"rights\"><strong class=\"calibre2\">Hot Reload<\/strong> is a feature that allows a developer to apply changes to code while the app is running and immediately see the effect. This is great for fixing bugs quickly. Hot Reload is also known as <strong class=\"calibre2\">Edit and Continue<\/strong>. A list of the types of changes that you can make that support Hot Reload is found at the following link: <a href=\"https:\/\/aka.ms\/dotnet\/hot-reload\">https:\/\/aka.ms\/dotnet\/hot-reload<\/a>.Just before the release of .NET 6, a high-level Microsoft employee caused controversy by attempting to make the feature Visual Studio-only. Luckily the open-source contingent within Microsoft successfully had the decision overturned. Hot Reload remains available using the command-line tool as well.Let's see it in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">HotReloading<\/code> to the <code class=\"calibre9\">Chapter04<\/code> solution.<\/li>\n<li class=\"calibre3\">Modify <code class=\"calibre9\">HotReloading.csproj<\/code> to statically import <code class=\"calibre9\">System.Console<\/code> for all code files.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then write a message to the console every two seconds, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/* Visual Studio 2022: run the app, change the message, click Hot Reload.\n * Visual Studio Code: run the app using dotnet watch, change the message. *\/\nwhile (true)\n{\n  WriteLine(\"Hello, Hot Reload!\");\n  await Task.Delay(2000);\n}<\/code><\/pre>\n<\/div>\n<section data-number=\"5.4.1\" id=\"calibre_link-220\">\n<h3 data-number=\"5.4.1\" class=\"calibre8\">Hot reloading using Visual Studio 2022<\/h3>\n<p class=\"rights\">If you are using Visual Studio, Hot Reload is built into the user interface:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Visual Studio 2022, start the project and note that the message is output every two seconds.<\/li>\n<li class=\"calibre3\">Leave the project running.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, change <code class=\"calibre9\">Hello<\/code> to <code class=\"calibre9\">Goodbye<\/code>.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Apply Code Changes<\/strong> or click the <strong class=\"calibre2\">Hot Reload<\/strong> button in the toolbar, as shown in <em class=\"calibre10\">Figure 4.15<\/em>, and note the change is applied without needing to restart the console app.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Drop down the <strong class=\"calibre2\">Hot Reload<\/strong> button menu and select <strong class=\"calibre2\">Hot Reload on File Save<\/strong>, as shown in <em class=\"calibre10\">Figure 4.15<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.15: Changing Hot Reload options\" height=\"634\" src=\"\/images\/cs12\/000016.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.15: Changing Hot Reload options<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Change the message again, save the file, and note the console app updates automatically.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"5.4.2\" id=\"calibre_link-221\">\n<h3 data-number=\"5.4.2\" class=\"calibre8\">Hot reloading using Visual Studio Code and dotnet watch<\/h3>\n<p class=\"rights\">If you are using Visual Studio Code, you must issue a special command when starting the console app to activate Hot Reload:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Visual Studio Code, in <strong class=\"calibre2\">TERMINAL<\/strong>, start the console app using <code class=\"calibre9\">dotnet watch<\/code>, and note the output that shows that hot reload is active, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet watch \ud83d\udd25 Hot reload enabled. For a list of supported edits, see https:\/\/aka.ms\/dotnet\/hot-reload.\n  \ud83d\udca1 Press \"Ctrl + R\" to restart.\ndotnet watch \ud83d\udd27 Building...\n  Determining projects to restore...\n  All projects are up-to-date for restore.\n  HotReloading -&gt; C:\\cs12dotnet8\\Chapter04\\HotReloading\\bin\\Debug\\net8.0\\HotReloading.dll\ndotnet watch \ud83d\ude80 Started\nHello, Hot Reload!\nHello, Hot Reload!\nHello, Hot Reload!<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Visual Studio Code, change <code class=\"calibre9\">Hello<\/code> to <code class=\"calibre9\">Goodbye<\/code>, and note that, after a couple of seconds, the change is applied without needing to restart the console app, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Hello, Hot Reload!\ndotnet watch \u231a File changed: .\\Program.cs.\nHello, Hot Reload!\nHello, Hot Reload!\ndotnet watch \ud83d\udd25 Hot reload of changes succeeded.\nGoodbye, Hot Reload!\nGoodbye, Hot Reload!<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Press <span>Ctrl<\/span> + <span>C<\/span> to stop it running, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Goodbye, Hot Reload!\ndotnet watch \ud83d\uded1 Shutdown requested. Press Ctrl+C again to force exit.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Now that you've seen tools for finding and removing bugs during development, let's see how you can track down less obvious problems that might happen during development and production.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"5.5\" id=\"calibre_link-222\">\n<h2 data-number=\"5.5\" class=\"calibre5\">Logging during development and runtime<\/h2>\n<p class=\"rights\">Once you believe that all the bugs have been removed from your code, you would then compile a release version and deploy the application, so that people can use it. But no code is ever bug-free, and during runtime, unexpected errors can occur.End users are notoriously bad at remembering, admitting to, and then accurately describing what they were doing when an error occurred. You should not rely on them providing useful information to reproduce the problem so that you can understand what caused the problem and then fix it. Instead, you can <strong class=\"calibre2\">instrument your code<\/strong>, which means logging events of interest and other data like timings.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Add code throughout your application to log what is happening, especially when exceptions occur, so that you can review the logs and use them to trace the issue and fix the problem. Although we will see logging again in <em class=\"calibre10\">Chapter 10<\/em>, <em class=\"calibre10\">Working with Data Using Entity Framework Core<\/em>, and in <em class=\"calibre10\">Chapter 14<\/em>, <em class=\"calibre10\">Building Websites Using the Model-View-Controller Pattern<\/em>, logging is a huge topic, so we can only cover the basics in this book.<\/p>\n<\/blockquote>\n<section data-number=\"5.5.1\" id=\"calibre_link-223\">\n<h3 data-number=\"5.5.1\" class=\"calibre8\">Understanding logging options<\/h3>\n<p class=\"rights\">.NET includes some built-in ways to instrument your code by adding logging capabilities. We will cover the basics in this book. But logging is an area where third parties have created a rich ecosystem of powerful solutions that extend what Microsoft provides. I cannot make specific recommendations because the best logging framework depends on your needs. But I include some common ones in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Apache log4net<\/li>\n<li class=\"calibre3\">NLog<\/li>\n<li class=\"calibre3\">Serilog<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">I introduce structured logging using the third-party logging system <strong class=\"calibre2\">Serilog<\/strong> in my companion book, <em class=\"calibre10\">Apps and Services with .NET 8<\/em>, because the Serilog packages have the most downloads on <a href=\"https:\/\/www.nuget.org\">https:\/\/www.nuget.org<\/a>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: When interviewing for a developer position, the logging system used by an organization is a good thing to ask about to show that you understand the importance of logging and you know that the specifics of the implementation are likely to be different depending on the organization.<\/p>\n<\/blockquote>\n<\/blockquote>\n<\/section>\n<section data-number=\"5.5.2\" id=\"calibre_link-224\">\n<h3 data-number=\"5.5.2\" class=\"calibre8\">Instrumenting with Debug and Trace<\/h3>\n<p class=\"rights\">You have seen the use of the <code class=\"calibre9\">Console<\/code> type and its <code class=\"calibre9\">WriteLine<\/code> method writing out to the console window. There is also a pair of types named <code class=\"calibre9\">Debug<\/code> and <code class=\"calibre9\">Trace<\/code> that have more flexibility in where they write out to:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The <code class=\"calibre9\">Debug<\/code> class is used to add logging that gets written only during development.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">Trace<\/code> class is used to add logging that gets written during both development and runtime.<\/li>\n<\/ul>\n<p class=\"rights\">The <code class=\"calibre9\">Debug<\/code> and <code class=\"calibre9\">Trace<\/code> classes write to any trace listener. A trace listener is a type that can be configured to write output anywhere you like when the <code class=\"calibre9\">WriteLine<\/code> method is called. There are several trace listeners provided by .NET, including one that outputs to the console, and you can even make your own by inheriting from the <code class=\"calibre9\">TraceListener<\/code> type so you can write to anywhere you want.<\/p>\n<section data-number=\"5.5.2.1\" id=\"calibre_link-1924\">\n<h4 data-number=\"5.5.2.1\" class=\"calibre15\">Writing to the default trace listener<\/h4>\n<p class=\"rights\">One trace listener, the <code class=\"calibre9\">DefaultTraceListener<\/code> class, is configured automatically and writes to Visual Studio Code's <strong class=\"calibre2\">DEBUG CONSOLE<\/strong> window or Visual Studio's <strong class=\"calibre2\">Debug<\/strong> window. You can configure other trace listeners using code.Let's see trace listeners in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">Instrumenting<\/code> to the <code class=\"calibre9\">Chapter04<\/code> solution.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then import the <code class=\"calibre9\">System.Diagnostics<\/code> namespace, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Diagnostics; \/\/ To use Debug and Trace.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, write messages from the two classes, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Debug.WriteLine(\"Debug says, I am watching!\");\nTrace.WriteLine(\"Trace says, I am watching!\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you are using Visual Studio 2022, navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Output<\/strong> and make sure <strong class=\"calibre2\">Show output from: Debug<\/strong> is selected.<\/li>\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Instrumenting<\/code> project with debugging, and note that <strong class=\"calibre2\">DEBUG CONSOLE<\/strong> in Visual Studio Code or the <strong class=\"calibre2\">Output<\/strong> window in Visual Studio 2022 shows the two messages, mixed with other debugging information, such as loaded assembly DLLs, as shown in <em class=\"calibre10\">Figures 4.16<\/em> and <em class=\"calibre10\">4.17<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.16: Visual Studio Code DEBUG CONSOLE shows the two messages in blue\" height=\"422\" src=\"\/images\/cs12\/000035.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.16: Visual Studio Code DEBUG CONSOLE shows the two messages in blue<\/figcaption><\/figure>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.17: Visual Studio 2022 Output window shows Debug output including the two messages\" height=\"349\" src=\"\/images\/cs12\/000052.png\" width=\"852\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.17: Visual Studio 2022 Output window shows Debug output including the two messages<\/figcaption><\/figure>\n<\/section>\n<\/section>\n<section data-number=\"5.5.3\" id=\"calibre_link-225\">\n<h3 data-number=\"5.5.3\" class=\"calibre8\">Configuring trace listeners<\/h3>\n<p class=\"rights\">Now, we will configure another trace listener that will write to a text file:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Before the <code class=\"calibre9\">Debug<\/code> and <code class=\"calibre9\">Trace<\/code> calls to <code class=\"calibre9\">WriteLine<\/code>, add statements to create a new text file on the desktop and pass it into a new trace listener that knows how to write to a text file, and enable automatic flushing for its buffer during development, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string logPath = Path.Combine(Environment.GetFolderPath(\n    Environment.SpecialFolder.DesktopDirectory), \"log.txt\");\nConsole.WriteLine($\"Writing to: {logPath}\");\nTextWriterTraceListener logFile = new(File.CreateText(logPath));\nTrace.Listeners.Add(logFile);\n#if DEBUG\n\/\/ Text writer is buffered, so this option calls\n\/\/ Flush() on all listeners after writing.\nTrace.AutoFlush = true;\n#endif<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Any type that represents a file usually implements a buffer to improve performance. Instead of writing immediately to the file, data is written to an in-memory buffer, and only once the buffer is full will it be written in one chunk to the file. This behavior can be confusing while debugging because we do not immediately see the results! Enabling <code class=\"calibre9\">AutoFlush<\/code> means the <code class=\"calibre9\">Flush<\/code> method is called automatically after every write. This reduces performance, so you should only set it on during debugging and not in production.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of <code class=\"calibre9\">Program.cs<\/code>, add statements to flush and close any buffered trace listeners for <code class=\"calibre9\">Debug<\/code> and <code class=\"calibre9\">Trace<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Close the text file (also flushes) and release resources.\nDebug.Close();\nTrace.Close();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the release configuration of the console app:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">In Visual Studio Code, enter the following command in the <strong class=\"calibre2\">TERMINAL<\/strong> window for the <code class=\"calibre9\">Instrumenting<\/code> project and note that nothing will appear to have happened:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet run --configuration Release<\/code><\/pre>\n<\/div>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">In Visual Studio 2022, in the standard toolbar, select <strong class=\"calibre2\">Release<\/strong> in the <strong class=\"calibre2\">Solution Configurations<\/strong> drop-down list, note that any statements in a <code class=\"calibre9\">#if DEBUG<\/code> region are grayed out to indicate they are not compiled, as shown in <em class=\"calibre10\">Figure 4.18<\/em>, and then navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Without Debugging<\/strong>.<\/li>\n<\/ul>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.18: Selecting the Release configuration in Visual Studio\" height=\"683\" src=\"\/images\/cs12\/000146.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.18: Selecting the Release configuration in Visual Studio<\/figcaption><\/figure>\n<ol class=\"toc\">\n<li class=\"calibre3\">On your desktop, open the file named <code class=\"calibre9\">log.txt<\/code> and note that it contains the message <code class=\"calibre9\">Trace says, I am watching!<\/code>.<\/li>\n<li class=\"calibre3\">Run the debug configuration of the console app:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">In Visual Studio Code, enter the following command in the <strong class=\"calibre2\">TERMINAL<\/strong> window for the <code class=\"calibre9\">Instrumenting<\/code> project:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet run --configuration Debug<\/code><\/pre>\n<\/div>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">In Visual Studio, in the standard toolbar, select <strong class=\"calibre2\">Debug<\/strong> in the <strong class=\"calibre2\">Solution Configurations<\/strong> drop-down list and then navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Debugging<\/strong>.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">On your desktop, open the file named <code class=\"calibre9\">log.txt<\/code> and note that it contains both the message <code class=\"calibre9\">Debug says, I am watching!<\/code> and also the message <code class=\"calibre9\">Trace says, I am watching!<\/code>.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: When running with the <code class=\"calibre9\">Debug<\/code> configuration, both <code class=\"calibre9\">Debug<\/code> and <code class=\"calibre9\">Trace<\/code> are active and will write to any trace listeners. When running with the <code class=\"calibre9\">Release<\/code> configuration, only <code class=\"calibre9\">Trace<\/code> will write to any trace listeners. You can therefore use <code class=\"calibre9\">Debug.WriteLine<\/code> calls liberally throughout your code, knowing they will be stripped out automatically when you build the release version of your application and will therefore not affect performance.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"5.5.4\" id=\"calibre_link-226\">\n<h3 data-number=\"5.5.4\" class=\"calibre8\">Switching trace levels<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">Trace.WriteLine<\/code> calls are left in your code, even after release. So, it would be great to have fine control over when they are output. This is something we can do with a <strong class=\"calibre2\">trace switch<\/strong>.The value of a trace switch can be set using a number or a word. For example, the number <code class=\"calibre9\">3<\/code> can be replaced with the word <code class=\"calibre9\">Info<\/code>, as shown in <em class=\"calibre10\">Table 4.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Number<\/td>\n<td class=\"calibre21\">Word<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">0<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Off<\/code><\/td>\n<td class=\"calibre21\">This will output nothing.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">1<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Error<\/code><\/td>\n<td class=\"calibre21\">This will output only errors.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">2<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Warning<\/code><\/td>\n<td class=\"calibre21\">This will output errors and warnings.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">3<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Info<\/code><\/td>\n<td class=\"calibre21\">This will output errors, warnings, and information.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">4<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Verbose<\/code><\/td>\n<td class=\"calibre21\">This will output all levels.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 4.1: Trace levels<\/p>\n<p class=\"rights\">Let's explore using trace switches. First, we will add some NuGet packages to our project to enable loading configuration settings from a JSON <code class=\"calibre9\">appsettings<\/code> file.<\/p>\n<section data-number=\"5.5.4.1\" id=\"calibre_link-1925\">\n<h4 data-number=\"5.5.4.1\" class=\"calibre15\">Adding packages to a project in Visual Studio 2022<\/h4>\n<p class=\"rights\">Visual Studio has a graphical user interface for adding packages:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, right-click the <code class=\"calibre9\">Instrumenting<\/code> project and select <strong class=\"calibre2\">Manage NuGet Packages<\/strong>.<\/li>\n<li class=\"calibre3\">Select the <strong class=\"calibre2\">Browse<\/strong> tab.<\/li>\n<li class=\"calibre3\">Search for each of these NuGet packages and click the <strong class=\"calibre2\">Install<\/strong> button, as shown in <em class=\"calibre10\">Figure 4.19<\/em>:\n<ul class=\"calibre16\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Microsoft.Extensions.Configuration.Binder<\/strong><\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Microsoft.Extensions.Configuration.Json<\/strong><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.19: Installing NuGet packages using Visual Studio 2022\" height=\"942\" src=\"\/images\/cs12\/000162.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.19: Installing NuGet packages using Visual Studio 2022<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: To use preview packages, for example, back in June 2023 for .NET 8 or during most of 2024 for .NET 9, you must select the <strong class=\"calibre2\">Include prerelease<\/strong> checkbox as shown in <em class=\"calibre10\">Figure 4.19<\/em>. There are also packages for loading configuration from XML files, INI files, environment variables, and the command line. Use the most appropriate technique for setting configuration in your projects.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"5.5.4.2\" id=\"calibre_link-1926\">\n<h4 data-number=\"5.5.4.2\" class=\"calibre15\">Adding packages to a project in Visual Studio Code<\/h4>\n<p class=\"rights\">Visual Studio Code does not have a mechanism to add NuGet packages to a project, so we will use the command-line tool:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to the <strong class=\"calibre2\">TERMINAL<\/strong> window for the <code class=\"calibre9\">Instrumenting<\/code> project.<\/li>\n<li class=\"calibre3\">Enter the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet add package Microsoft.Extensions.Configuration.Binder<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Enter the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet add package Microsoft.Extensions.Configuration.Json<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">dotnet add package<\/code> adds a reference to a NuGet package to your project file. It will be downloaded during the build process. <code class=\"calibre9\">dotnet add reference<\/code> adds a project-to-project reference to your project file. The referenced project will be compiled if needed during the build process.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"5.5.4.3\" id=\"calibre_link-1927\">\n<h4 data-number=\"5.5.4.3\" class=\"calibre15\">Reviewing project packages for working with configuration<\/h4>\n<p class=\"rights\">After adding the NuGet packages, we can see the references in the project file. Package references are case-insensitive, so you do not need to worry if they are not an exact case match. Let's review the package references:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Open <code class=\"calibre9\">Instrumenting.csproj<\/code> and note the <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> section with the added NuGet packages, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n  &lt;\/PropertyGroup&gt;\n  &lt;ItemGroup&gt;\n    &lt;PackageReference\n      Include=\"Microsoft.Extensions.Configuration.Binder\" \n      Version=\"8.0.0\" \/&gt;\n    &lt;PackageReference\n      Include=\"Microsoft.Extensions.Configuration.Json\" \n      Version=\"8.0.0\" \/&gt;\n  &lt;\/ItemGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">After the final release of .NET 7, Microsoft fixed a bug in <code class=\"calibre9\">Microsoft.Extensions.Configuration.Binder<\/code> package version 7.0.3. This caused an exception to be thrown due to the way the previous edition read a setting. This is known as a bug-fix regression. Good unit tests should detect fixes that then cascade to cause other problems. It is also an example of unexpected issues with future package versions. If you have unexpected issues with a package, try an earlier version.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a file named <code class=\"calibre9\">appsettings.json<\/code> to the <code class=\"calibre9\">Instrumenting<\/code> project folder.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">appsettings.json<\/code>, define a setting named <code class=\"calibre9\">PacktSwitch<\/code> with a <code class=\"calibre9\">Value<\/code> of <code class=\"calibre9\">Info<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"PacktSwitch\": {\n    \"Value\": \"Info\"\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Until <code class=\"calibre9\">Microsoft.Extensions.Configuration.Binder<\/code> package version 7.0.3, you could set the <code class=\"calibre9\">Level<\/code> property. For example: <code class=\"calibre9\">\"Level\": \"Info\"<\/code>. After the bug fix, this now causes an exception to be thrown. Instead, we must set the <code class=\"calibre9\">Value<\/code> property, or both. This is due to an internal class needing the <code class=\"calibre9\">Value<\/code> to be set, as explained at the following link: <a href=\"https:\/\/github.com\/dotnet\/runtime\/issues\/82998\">https:\/\/github.com\/dotnet\/runtime\/issues\/82998<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Visual Studio 2022 and JetBrains Rider, in <strong class=\"calibre2\">Solution Explorer<\/strong>, right-click <code class=\"calibre9\">appsettings.json<\/code>, select <strong class=\"calibre2\">Properties<\/strong>, and then in the <strong class=\"calibre2\">Properties<\/strong> window, change <strong class=\"calibre2\">Copy to Output Directory<\/strong> to <strong class=\"calibre2\">Copy always<\/strong>. This is necessary because unlike Visual Studio Code, which runs the console app in the project folder, Visual Studio runs the console app in <code class=\"calibre9\">Instrumenting\\bin\\Debug\\net8.0<\/code> or <code class=\"calibre9\">Instrumenting\\bin\\Release\\net8.0<\/code>. To confirm this is done correctly, review the element that was added to the project file, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;None Update=\"appsettings.json\"&gt;\n    &lt;CopyToOutputDirectory&gt;Always&lt;\/CopyToOutputDirectory&gt;\n  &lt;\/None&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <strong class=\"calibre2\">Copy to Output Directory<\/strong> property can be unreliable. In our code, we will read and output this file so we can see exactly what is being processed to catch any issues with changes not being copied correctly.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.cs<\/code>, import the <code class=\"calibre9\">Microsoft.Extensions.Configuration<\/code> namespace, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.Extensions.Configuration; \/\/ To use ConfigurationBuilder.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Before the statements that close <code class=\"calibre9\">Debug<\/code> and <code class=\"calibre9\">Trace<\/code>, add some statements to create a configuration builder that looks in the current folder for a file named <code class=\"calibre9\">appsettings.json<\/code>, build the configuration, create a trace switch, set its level by binding to the configuration, and then output the four trace switch levels, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string settingsFile = \"appsettings.json\";\nstring settingsPath = Path.Combine(\n  Directory.GetCurrentDirectory(), settingsFile);\nConsole.WriteLine(\"Processing: {0}\", settingsPath);\nConsole.WriteLine(\"--{0} contents--\", settingsFile);\nConsole.WriteLine(File.ReadAllText(settingsPath));\nConsole.WriteLine(\"----\");\nConfigurationBuilder builder = new();\nbuilder.SetBasePath(Directory.GetCurrentDirectory());\n\/\/ Add the settings file to the processed configuration and make it\n\/\/ mandatory so an exception will be thrown if the file is not found.\nbuilder.AddJsonFile(settingsFile,\n  optional: false, reloadOnChange: true);\nIConfigurationRoot configuration = builder.Build(); \nTraceSwitch ts = new(\n  displayName: \"PacktSwitch\",\n  description: \"This switch is set via a JSON config.\"); \nconfiguration.GetSection(\"PacktSwitch\").Bind(ts);\nConsole.WriteLine($\"Trace switch value: {ts.Value}\");\nConsole.WriteLine($\"Trace switch level: {ts.Level}\");\nTrace.WriteLineIf(ts.TraceError, \"Trace error\"); \nTrace.WriteLineIf(ts.TraceWarning, \"Trace warning\"); \nTrace.WriteLineIf(ts.TraceInfo, \"Trace information\"); \nTrace.WriteLineIf(ts.TraceVerbose, \"Trace verbose\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If the <code class=\"calibre9\">appsettings.json<\/code> file is not found, then the following exception will be thrown: <code class=\"calibre9\">System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional. The expected physical path was 'C:\\cs12dotnet8\\Chapter04\\Instrumenting\\bin\\Debug\\net8.0\\appsettings.json'<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">After the statements that close <code class=\"calibre9\">Debug<\/code> and <code class=\"calibre9\">Trace<\/code>, add some statements to prompt the user to press <span>Enter<\/span> to exit the console app, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Close the text file (also flushes) and release resources.\nDebug.Close();\nTrace.Close();\nConsole.WriteLine(\"Press enter to exit.\");\nConsole.ReadLine();<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice:<\/strong> Be careful not to close <code class=\"calibre9\">Debug<\/code> or <code class=\"calibre9\">Trace<\/code> before you are done using them. If you close them and then write to them, nothing will happen!<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Set a breakpoint on the <code class=\"calibre9\">Bind<\/code> statement.<\/li>\n<li class=\"calibre3\">Start debugging the <code class=\"calibre9\">Instrumenting<\/code> console app project.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <strong class=\"calibre2\">VARIABLES<\/strong> or <strong class=\"calibre2\">Locals<\/strong> window, expand the <code class=\"calibre9\">ts<\/code> variable expression, and note that its <code class=\"calibre9\">Level<\/code> is <code class=\"calibre9\">Off<\/code> and its <code class=\"calibre9\">TraceError<\/code>, <code class=\"calibre9\">TraceWarning<\/code>, and so on are all <code class=\"calibre9\">false<\/code>, as shown in <em class=\"calibre10\">Figure 4.20<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.20: Watching the trace switch variable properties in Visual Studio 2022\" height=\"1069\" src=\"\/images\/cs12\/000003.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.20: Watching the trace switch variable properties in Visual Studio 2022<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Step into the call to the <code class=\"calibre9\">Bind<\/code> method by clicking the <strong class=\"calibre2\">Step Into<\/strong> or <strong class=\"calibre2\">Step Over<\/strong> buttons or pressing <span>F11<\/span> or <span>F10<\/span>, and note the <code class=\"calibre9\">ts<\/code> variable watch expression <code class=\"calibre9\">SwitchSetting<\/code>, <code class=\"calibre9\">Value<\/code>, and <code class=\"calibre9\">Level<\/code> properties update to the <code class=\"calibre9\">Info<\/code> level (<code class=\"calibre9\">3<\/code>), and three of the four <code class=\"calibre9\">TraceX<\/code> properties change to <code class=\"calibre9\">true<\/code>, as shown in <em class=\"calibre10\">Figure 4.21<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.21: Info trace level enables all but TraceVerbose\" height=\"1069\" src=\"\/images\/cs12\/000094.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.21: Info trace level enables all but TraceVerbose<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Step into or over the four calls to <code class=\"calibre9\">Trace.WriteLineIf<\/code> and note that all levels up to <code class=\"calibre9\">Info<\/code> are written to the <strong class=\"calibre2\">DEBUG CONSOLE<\/strong> or <strong class=\"calibre2\">Output - Debug<\/strong> window, but not <code class=\"calibre9\">Verbose<\/code>.<\/li>\n<li class=\"calibre3\">Stop debugging.<\/li>\n<li class=\"calibre3\">Modify <code class=\"calibre9\">appsettings.json<\/code> to set a level value of <code class=\"calibre9\">2<\/code>, which is the equivalent of <code class=\"calibre9\">Warning<\/code>, as shown in the following JSON file:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"PacktSwitch\": { \n    \"Value\": \"2\"\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Save the changes.<\/li>\n<li class=\"calibre3\">In Visual Studio Code, run the console application by entering the following command in the <strong class=\"calibre2\">TERMINAL<\/strong> window for the <code class=\"calibre9\">Instrumenting<\/code> project:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet run --configuration Release<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Visual Studio 2022, in the standard toolbar, select <strong class=\"calibre2\">Release<\/strong> in the <strong class=\"calibre2\">Solution Configurations<\/strong> drop-down list and then run the console app by navigating to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Without Debugging<\/strong>.<\/li>\n<li class=\"calibre3\">Open the file named <code class=\"calibre9\">log.txt<\/code> and note that, this time, only trace error and warning levels are the output of the four potential trace levels, as shown in the following text file:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Trace says, I am watching! \nTrace error\nTrace warning<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If no <code class=\"calibre9\">--configuration<\/code> argument is passed, the default trace switch level is <code class=\"calibre9\">Off<\/code> (<code class=\"calibre9\">0<\/code>), so none of the switch levels are output.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"5.5.5\" id=\"calibre_link-227\">\n<h3 data-number=\"5.5.5\" class=\"calibre8\">Logging information about your source code<\/h3>\n<p class=\"rights\">When you write to a log, you will often want to include the name of the source code file, the name of the method, and the line number. In C# 10 and later, you can even get any expressions passed as an argument to a function as a <code class=\"calibre9\">string<\/code> value so you can log them.You can get all this information from the compiler by decorating function parameters with special attributes, as shown in <em class=\"calibre10\">Table 4.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre19\"><\/col>\n<col class=\"calibre19\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Parameter example<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[CallerMemberName] string member = \"\"<\/code><\/td>\n<td class=\"calibre21\">Sets the <code class=\"calibre9\">string<\/code> parameter named <code class=\"calibre9\">member<\/code> to the name of the method or property that is executing the method that defines this parameter.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[CallerFilePath] string filepath = \"\"<\/code><\/td>\n<td class=\"calibre21\">Sets the <code class=\"calibre9\">string<\/code> parameter named <code class=\"calibre9\">filepath<\/code> to the name of the source code file that contains the statement that is executing the method that defines this parameter.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[CallerLineNumber] int line = 0<\/code><\/td>\n<td class=\"calibre21\">Sets the <code class=\"calibre9\">int<\/code> parameter named <code class=\"calibre9\">line<\/code> to the line number in the source code file of the statement that is executing the method that defines this parameter.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><code class=\"calibre9\">[CallerArgumentExpression(<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">nameof(argumentExpression))] <\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">string expression = \"\"<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">Sets the <code class=\"calibre9\">string<\/code> parameter named <code class=\"calibre9\">expression<\/code> to the expression that has been passed to the parameter named <code class=\"calibre9\">argumentExpression<\/code> .<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 4.2: Attributes to get information about the method caller<\/p>\n<p class=\"rights\">You must make these parameters optional by assigning default values to them.Let's see some code in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Instrumenting<\/code> project, add a class file named <code class=\"calibre9\">Program.Functions.cs<\/code>.<\/li>\n<li class=\"calibre3\">Delete any existing statements and then add statements to define a function named <code class=\"calibre9\">LogSourceDetails<\/code> that uses the four special attributes to log information about the calling code, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Diagnostics; \/\/ To use Trace.\nusing System.Runtime.CompilerServices; \/\/ To use [CallerX] attributes\npartial class Program\n{\n  static void LogSourceDetails(\n    bool condition,\n    [CallerMemberName] string member = \"\",\n    [CallerFilePath] string filepath = \"\", \n    [CallerLineNumber] int line = 0,\n    [CallerArgumentExpression(nameof(condition))] string expression = \"\")\n  {\n    Trace.WriteLine(string.Format(\n      \"[{0}]\\n  {1} on line {2}. Expression: {3}\",\n      filepath, member, line, expression));\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, at the bottom of the file, before the calls to close <code class=\"calibre9\">Debug<\/code> and <code class=\"calibre9\">Trace<\/code>, add statements to declare and set a variable that will be used in an expression that is passed to the function named <code class=\"calibre9\">LogSourceDetails<\/code>, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int unitsInStock = 12;\nLogSourceDetails(unitsInStock &gt; 10);\n\/\/ Close the text file (also flushes) and release resources.\nDebug.Close();\nTrace.Close();<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">We are just making up an expression in this scenario. In a real project, this might be an expression that is dynamically generated by the user making user interface selections to query a database or so on.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app without debugging, press <span>Enter<\/span> and close the console app, and then open the <code class=\"calibre9\">log.txt<\/code> file and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[C:\\cs12dotnet8\\Chapter04\\Instrumenting\\Program.cs]\n  &lt;Main&gt;$ on line 44. Expression: unitsInStock &gt; 10<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"5.6\" id=\"calibre_link-228\">\n<h2 data-number=\"5.6\" class=\"calibre5\">Unit testing<\/h2>\n<p class=\"rights\">Fixing bugs in code is expensive. The earlier that a bug is discovered in the development process, the less expensive it will be to fix.Unit testing is a good way to find bugs early in the development process because they test a small unit before they are integrated together or are seen by user acceptance testers. Some developers even follow the principle that programmers should create unit tests before they write code, and this is called <strong class=\"calibre2\">Test-Driven Development<\/strong> (<strong class=\"calibre2\">TDD<\/strong>).Microsoft has a proprietary unit testing framework known as <strong class=\"calibre2\">MSTest<\/strong>. There is also a framework named <strong class=\"calibre2\">NUnit<\/strong>. However, we will use the free and open-source third-party framework <strong class=\"calibre2\">xUnit.net<\/strong>. All three do basically the same thing. xUnit was created by the same team that built NUnit, but they fixed the mistakes they felt they made previously. xUnit is more extensible and has better community support.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you are curious about the pros and cons of the various testing systems, then there are hundreds of articles written by proponents of each. Just Google them: <a href=\"https:\/\/www.google.com\/search?q=xunit+vs+nunit\">https:\/\/www.google.com\/search?q=xunit+vs+nunit<\/a>.<\/p>\n<\/blockquote>\n<section data-number=\"5.6.1\" id=\"calibre_link-229\">\n<h3 data-number=\"5.6.1\" class=\"calibre8\">Understanding types of testing<\/h3>\n<p class=\"rights\">Unit testing is just one of many types of testing, as described in <em class=\"calibre10\">Table 4.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Type<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Unit<\/td>\n<td class=\"calibre21\">Tests the smallest unit of code, typically a method or function. Unit testing is performed on a unit of code isolated from its dependencies by mocking them if needed. Each unit should have multiple tests: some with typical inputs and expected outputs, some with extreme input values to test boundaries, and some with deliberately wrong inputs to test exception handling.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Integration<\/td>\n<td class=\"calibre21\">Tests if the smaller units and larger components work together as a single piece of software. Sometimes involves integrating with external components for which you do not have source code.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">System<\/td>\n<td class=\"calibre21\">Tests the whole system environment in which your software will run.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Performance<\/td>\n<td class=\"calibre21\">Tests the performance of your software; for example, your code must return a web page full of data to a visitor in under 20 milliseconds.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Load<\/td>\n<td class=\"calibre21\">Tests how many requests your software can handle simultaneously while maintaining required performance, for example, 10,000 concurrent visitors to a website.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">User Acceptance<\/td>\n<td class=\"calibre21\">Tests if users can happily complete their work using your software.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 4.3: Types of testing<br \/>\n<\/section>\n<section data-number=\"5.6.2\" id=\"calibre_link-230\">\n<h3 data-number=\"5.6.2\" class=\"calibre8\">Creating a class library that needs testing<\/h3>\n<p class=\"rights\">First, we will create a function that needs testing. We will create it in a class library project separate from a console app project. A class library is a package of code that can be distributed and referenced by other .NET applications:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new <strong class=\"calibre2\">Class Library<\/strong> \/ <code class=\"calibre9\">classlib<\/code> project named <code class=\"calibre9\">CalculatorLib<\/code> to the <code class=\"calibre9\">Chapter04<\/code> solution.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">At this point, you will have created about a dozen new console app projects and added them to a solution. The only difference when adding a <strong class=\"calibre2\">Class Library<\/strong> \/ <code class=\"calibre9\">classlib<\/code> is to select a different project template. The rest of the steps are the same as adding a <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project.<\/p>\n<\/blockquote>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">If you are using Visual Studio 2022:<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">File<\/strong> | <strong class=\"calibre2\">Add<\/strong> | <strong class=\"calibre2\">New Project<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Add a new project<\/strong> dialog, search for and select <strong class=\"calibre2\">Class Library [C#]<\/strong> and then click <strong class=\"calibre2\">Next<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Configure your new project<\/strong> dialog, for the <strong class=\"calibre2\">Project name<\/strong>, enter <code class=\"calibre9\">CalculatorLib<\/code>, leave the location as <code class=\"calibre9\">C:\\cs12dotnet8\\Chapter04<\/code>, and then click <strong class=\"calibre2\">Next<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Additional information<\/strong> dialog, select <strong class=\"calibre2\">.NET 8.0 (Long Term Support)<\/strong>, and then click <strong class=\"calibre2\">Create<\/strong>.<\/li>\n<\/ol>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">If you are using Visual Studio Code:<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">TERMINAL<\/strong>, switch to a terminal in the <code class=\"calibre9\">Chapter04<\/code> folder.<\/li>\n<li class=\"calibre3\">Use the <code class=\"calibre9\">dotnet<\/code> CLI to create a new class library project named <code class=\"calibre9\">CalculatorLib<\/code>, as shown in the following command: <code class=\"calibre9\">dotnet new classlib -o CalculatorLib<\/code><\/li>\n<li class=\"calibre3\">Use the <code class=\"calibre9\">dotnet<\/code> CLI to add the new project folder to the solution, as shown in the following command: <code class=\"calibre9\">dotnet sln add CalculatorLib<\/code><\/li>\n<li class=\"calibre3\">Note the results, as shown in the following output: <code class=\"calibre9\">Project `CalculatorLib\\CalculatorLib.csproj` added to the solution.<\/code><\/li>\n<\/ol>\n<ol class=\"toc\">\n<li class=\"calibre3\">For all code editors, in the <code class=\"calibre9\">CalculatorLib<\/code> project, rename the file named <code class=\"calibre9\">Class1.cs<\/code> to <code class=\"calibre9\">Calculator.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Calculator.cs<\/code>, modify the file to define a <code class=\"calibre9\">Calculator<\/code> class (with a deliberate bug!), as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace CalculatorLib;\npublic class Calculator\n{\n  public double Add(double a, double b)\n  {\n    return a * b;\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Compile your class library project:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">In Visual Studio 2022, navigate to <strong class=\"calibre2\">Build<\/strong> | <strong class=\"calibre2\">Build CalculatorLib<\/strong>.<\/li>\n<li class=\"calibre3\">In Visual Studio Code, in a <strong class=\"calibre2\">TERMINAL<\/strong> window for the <code class=\"calibre9\">CalculatorLib<\/code> folder, enter the command <code class=\"calibre9\">dotnet build<\/code>. (You could also run this command in the <code class=\"calibre9\">Chapter04<\/code> folder but that would build the whole solution, which is unnecessary in this scenario.)<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Use your preferred coding tool to add a new <strong class=\"calibre2\">xUnit Test Project [C#]<\/strong> \/ <code class=\"calibre9\">xunit<\/code> project named <code class=\"calibre9\">CalculatorLibUnitTests<\/code> to the <code class=\"calibre9\">Chapter04<\/code> solution. For example, at the command prompt or terminal in the <code class=\"calibre9\">Chapter04<\/code> folder, enter the following commands:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new xunit -o CalculatorLibUnitTests\ndotnet sln add CalculatorLibUnitTests<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">CalculatorLibUnitTests<\/code> project, add a project reference to the <code class=\"calibre9\">CalculatorLib<\/code> project:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">If you are using Visual Studio 2022, in <strong class=\"calibre2\">Solution Explorer<\/strong>, select the <code class=\"calibre9\">CalculatorLibUnitTests<\/code> project, navigate to <strong class=\"calibre2\">Project<\/strong> | <strong class=\"calibre2\">Add Project Reference\u2026<\/strong>, check the box to select the <code class=\"calibre9\">CalculatorLib<\/code> project, and then click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<li class=\"calibre3\">If you are using Visual Studio Code, use the <code class=\"calibre9\">dotnet add reference<\/code> command, or in the file named <code class=\"calibre9\">CalculatorLibUnitTests.csproj<\/code>, modify the configuration to add an item group with a project reference to the <code class=\"calibre9\">CalculatorLib<\/code> project, as shown highlighted in the following markup:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;ProjectReference\n    Include=\"..\\CalculatorLib\\CalculatorLib.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The path for a project reference can use either forward <code class=\"calibre9\">\/<\/code> or back slashes <code class=\"calibre9\">\\<\/code> because the paths are processed by the .NET SDK and changed if necessary for the current operating system.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">CalculatorLibUnitTests<\/code> project.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"5.6.3\" id=\"calibre_link-231\">\n<h3 data-number=\"5.6.3\" class=\"calibre8\">Writing unit tests<\/h3>\n<p class=\"rights\">A well-written unit test will have three parts:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Arrange<\/strong>: This part will declare and instantiate variables for input and output.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Act<\/strong>: This part will execute the unit that you are testing. In our case, that means calling the method that we want to test.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Assert<\/strong>: This part will make one or more assertions about the output. An assertion is a belief that, if not true, indicates a failed test. For example, when adding 2 and 2, we would expect the result to be 4.<\/li>\n<\/ul>\n<p class=\"rights\">Now, we will write some unit tests for the <code class=\"calibre9\">Calculator<\/code> class:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Rename the file <code class=\"calibre9\">UnitTest1.cs<\/code> to <code class=\"calibre9\">CalculatorUnitTests.cs<\/code> and then open it.<\/li>\n<li class=\"calibre3\">In Visual Studio Code, rename the class to <code class=\"calibre9\">CalculatorUnitTests<\/code>. (Visual Studio prompts you to rename the class when you rename the file.)<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">CalculatorUnitTests<\/code>, import the <code class=\"calibre9\">CalculatorLib<\/code> namespace, and then modify the <code class=\"calibre9\">CalculatorUnitTests<\/code> class to have two test methods, one for adding 2 and 2, and another for adding 2 and 3, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using CalculatorLib; \/\/ To use Calculator.\nnamespace CalculatorLibUnitTests;\npublic class CalculatorUnitTests\n{\n  [Fact]\n  public void TestAdding2And2()\n  {\n    \/\/ Arrange: Set up the inputs and the unit under test.\n    double a = 2; \n    double b = 2;\n    double expected = 4;\n    Calculator calc = new();\n    \/\/ Act: Execute the function to test.\n    double actual = calc.Add(a, b);\n    \/\/ Assert: Make assertions to compare expected to actual results.\n    Assert.Equal(expected, actual);\n  }\n  [Fact]\n  public void TestAdding2And3()\n  {\n    double a = 2; \n    double b = 3;\n    double expected = 5;\n    Calculator calc = new();\n    double actual = calc.Add(a, b);\n    Assert.Equal(expected, actual);\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Visual Studio 2022 still uses an older project item template that uses a nested namespace. The preceding code shows the modern project item template used by <code class=\"calibre9\">dotnet new<\/code> and JetBrains Rider that uses a file-scoped namespace.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">CalculatorLibUnitTests<\/code> project.<\/li>\n<\/ol>\n<section data-number=\"5.6.3.1\" id=\"calibre_link-1928\">\n<h4 data-number=\"5.6.3.1\" class=\"calibre15\">Running unit tests using Visual Studio 2022<\/h4>\n<p class=\"rights\">Now we are ready to run the unit tests and see the results:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Visual Studio, navigate to <strong class=\"calibre2\">Test<\/strong> | <strong class=\"calibre2\">Run All Tests<\/strong>.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">Test Explorer<\/strong>, note that the results indicate that two tests ran, one test passed, and one test failed, as shown in <em class=\"calibre10\">Figure 4.22<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.22: The unit test results in Visual Studio 2022&apos;s Test Explorer\" height=\"535\" src=\"\/images\/cs12\/000112.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.22: The unit test results in Visual Studio 2022's Test Explorer<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"5.6.3.2\" id=\"calibre_link-1929\">\n<h4 data-number=\"5.6.3.2\" class=\"calibre15\">Running unit tests using Visual Studio Code<\/h4>\n<p class=\"rights\">Now we are ready to run the unit tests and see the results:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you have not recently built the test project, then build the <code class=\"calibre9\">CalculatorLibUnitTests<\/code> project to make sure that the new testing feature in the C# Dev Kit extension recognizes the unit tests that you have written.<\/li>\n<li class=\"calibre3\">In Visual Studio Code, navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Testing<\/strong>, and note the <strong class=\"calibre2\">TESTING<\/strong> window has a mini toolbar with buttons to <strong class=\"calibre2\">Refresh Tests<\/strong>, <strong class=\"calibre2\">Run Tests<\/strong>, <strong class=\"calibre2\">Debug Tests<\/strong>, and so on.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">TESTING<\/strong> window, expand the <strong class=\"calibre2\">CalculatorLibUnitTests<\/strong> project to show the two tests.<\/li>\n<li class=\"calibre3\">Hover your mouse pointer over <strong class=\"calibre2\">CalculatorUnitTests<\/strong> and then click the <strong class=\"calibre2\">Run Tests<\/strong> button (black triangle icon) defined in that class.<\/li>\n<li class=\"calibre3\">Click the <strong class=\"calibre2\">TEST RESULTS<\/strong> tab and note that the results indicate that two tests ran, one test passed, and one test failed, as shown in <em class=\"calibre10\">Figure 4.23<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.23: The unit test results in Visual Studio Code&apos;s TERMINAL\" height=\"680\" src=\"\/images\/cs12\/000129.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.23: The unit test results in Visual Studio Code's TERMINAL<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"5.6.3.3\" id=\"calibre_link-1930\">\n<h4 data-number=\"5.6.3.3\" class=\"calibre15\">Fixing the bug<\/h4>\n<p class=\"rights\">Now you can fix the bug:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Fix the bug in the <code class=\"calibre9\">Add<\/code> method.<\/li>\n<li class=\"calibre3\">Run the unit tests again to see that the bug has now been fixed and both tests have passed.<\/li>\n<\/ol>\n<p class=\"rights\">Now that we've written, debugged, logged, and unit-tested functions, let's finish this chapter by looking at how to throw and catch exceptions in functions.<\/p>\n<\/section>\n<\/section>\n<\/section>\n<section data-number=\"5.7\" id=\"calibre_link-232\">\n<h2 data-number=\"5.7\" class=\"calibre5\">Throwing and catching exceptions in functions<\/h2>\n<p class=\"rights\">In <em class=\"calibre10\">Chapter 3<\/em>, <em class=\"calibre10\">Controlling Flow, Converting Types, and Handling Exceptions<\/em>, you were introduced to exceptions and how to use a <code class=\"calibre9\">try-catch<\/code> statement to handle them. But you should only catch and handle an exception if you have enough information to mitigate the issue. If you do not, then you should allow the exception to pass up through the call stack to a higher level.<\/p>\n<section data-number=\"5.7.1\" id=\"calibre_link-233\">\n<h3 data-number=\"5.7.1\" class=\"calibre8\">Understanding usage errors and execution errors<\/h3>\n<p class=\"rights\"><strong class=\"calibre2\">Usage errors<\/strong> are when a programmer misuses a function, typically by passing invalid values as parameters. They could be avoided by that programmer changing their code to pass valid values. When some programmers first learn C# and .NET, they sometimes think exceptions can always be avoided because they assume all errors are usage errors. Usage errors should all be fixed before production runtime.<strong class=\"calibre2\">Execution errors<\/strong> are when something happens at runtime that cannot be fixed by writing \"better\" code. Execution errors can be split into <strong class=\"calibre2\">program errors<\/strong> and <strong class=\"calibre2\">system errors<\/strong>. If you attempt to access a network resource but the network is down, you need to be able to handle that system error by logging an exception, and possibly backing off for a time and trying again. But some system errors, such as running out of memory, simply cannot be handled. If you attempt to open a file that does not exist, you might be able to catch that error and handle it programmatically by creating a new file. Program errors can be programmatically fixed by writing smart code. System errors often cannot be fixed programmatically.<\/p>\n<\/section>\n<section data-number=\"5.7.2\" id=\"calibre_link-234\">\n<h3 data-number=\"5.7.2\" class=\"calibre8\">Commonly thrown exceptions in functions<\/h3>\n<p class=\"rights\">Very rarely should you define new types of exceptions to indicate usage errors. .NET already defines many that you should use.When defining your own functions with parameters, your code should check the parameter values and throw exceptions if they have values that will prevent your function from properly functioning.For example, if a parameter to a function should not be <code class=\"calibre9\">null<\/code>, throw <code class=\"calibre9\">ArgumentNullException<\/code>. For other problems, throw <code class=\"calibre9\">ArgumentException<\/code>, <code class=\"calibre9\">NotSupportedException<\/code>, or <code class=\"calibre9\">InvalidOperationException<\/code>. For any exception, include a message that describes the problem for whoever will have to read it (typically a developer audience for class libraries and functions, or end users if it is at the highest level of a GUI app), as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void Withdraw(string accountName, decimal amount)\n{\n  if (string.IsNullOrWhiteSpace(accountName))\n  {\n    throw new ArgumentException(paramName: nameof(accountName));\n  }\n  if (amount &lt;= 0)\n  {\n    throw new ArgumentOutOfRangeException(paramName: nameof(amount),\n      message: $\"{nameof(amount)} cannot be negative or zero.\");\n  }\n  \/\/ process parameters\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If a function cannot successfully perform its operation, you should consider it a function failure and report it by throwing an exception.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"5.7.3\" id=\"calibre_link-235\">\n<h3 data-number=\"5.7.3\" class=\"calibre8\">Throwing exceptions using guard clauses<\/h3>\n<p class=\"rights\">Instead of instantiating an exception using <code class=\"calibre9\">new<\/code>, you can use static methods on the exception itself. When used in a function implementation to check argument values, they are known as <strong class=\"calibre2\">guard clauses<\/strong>. Some were introduced with .NET 6, and more were added in .NET 8.Common guard clauses are shown in <em class=\"calibre10\">Table 4.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Exception<\/td>\n<td class=\"calibre21\">Guard clause methods<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ArgumentException<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">ThrowIfNullOrEmpty<\/code> , <code class=\"calibre9\">ThrowIfNullOrWhiteSpace<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ArgumentNullException<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">ThrowIfNull<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ArgumentOutOfRangeException<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">ThrowIfEqual<\/code> , <code class=\"calibre9\">ThrowIfGreaterThan<\/code> , <code class=\"calibre9\">ThrowIfGreaterThanOrEqual<\/code> , <code class=\"calibre9\">ThrowIfLessThan<\/code> , <code class=\"calibre9\">ThrowIfLessThanOrEqual<\/code> , <code class=\"calibre9\">ThrowIfNegative<\/code> , <code class=\"calibre9\">ThrowIfNegativeOrZero<\/code> , <code class=\"calibre9\">ThrowIfNotEqual<\/code> , <code class=\"calibre9\">ThrowIfZero<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 4.4: Common guard clauses<\/p>\n<p class=\"rights\">Instead of writing an <code class=\"calibre9\">if<\/code> statement and then throwing a <code class=\"calibre9\">new<\/code> exception, we can simplify the previous example, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void Withdraw(string accountName, decimal amount)\n{\n  ArgumentException.ThrowIfNullOrWhiteSpace(accountName,\n    paramName: nameof(accountName));\n  ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount,\n    paramName: nameof(amount));\n  \/\/ process parameters\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"5.7.4\" id=\"calibre_link-236\">\n<h3 data-number=\"5.7.4\" class=\"calibre8\">Understanding the call stack<\/h3>\n<p class=\"rights\">The entry point for a .NET console application is the <code class=\"calibre9\">Main<\/code> method (if you have explicitly defined this class) or <code class=\"calibre9\">&lt;Main&gt;$<\/code> (if it was created for you by the top-level program feature) in the <code class=\"calibre9\">Program<\/code> class.The <code class=\"calibre9\">Main<\/code> method will call other methods, which call other methods, and so on, and these methods could be in the current project or referenced projects and NuGet packages, as shown in <em class=\"calibre10\">Figure 4.24<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 4.24: A chain of method calls that create a call stack\" height=\"250\" src=\"\/images\/cs12\/000046.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 4.24: A chain of method calls that create a call stack<\/figcaption><\/figure>\n<p class=\"rights\">Let's create a similar chain of methods to explore where we could catch and handle exceptions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new <strong class=\"calibre2\">Class Library<\/strong> \/ <code class=\"calibre9\">classlib<\/code> project named <code class=\"calibre9\">CallStackExceptionHandlingLib<\/code> to the <code class=\"calibre9\">Chapter04<\/code> solution.<\/li>\n<li class=\"calibre3\">Rename the <code class=\"calibre9\">Class1.cs<\/code> file to <code class=\"calibre9\">Processor.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Processor.cs<\/code>, modify its contents, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using static System.Console;\nnamespace CallStackExceptionHandlingLib;\npublic class Processor\n{\n  public static void Gamma() \/\/ public so it can be called from outside.\n  {\n    WriteLine(\"In Gamma\");\n    Delta();\n  }\n  private static void Delta() \/\/ private so it can only be called internally.\n  {\n    WriteLine(\"In Delta\");\n    File.OpenText(\"bad file path\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">CallStackExceptionHandling<\/code> to the <code class=\"calibre9\">Chapter04<\/code> solution.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">CallStackExceptionHandling<\/code> console app project, add a reference to the <code class=\"calibre9\">CallStackExceptionHandlingLib<\/code> class library project, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;ProjectReference Include=\"..\\CallStackExceptionHandlingLib\\\nCallStackExceptionHandlingLib.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">CallStackExceptionHandling<\/code> console app project to make sure dependent projects are compiled and copied to the local <code class=\"calibre9\">bin<\/code> folder.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, and then add statements to define two methods and chain calls to them and the methods in the class library, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using CallStackExceptionHandlingLib; \/\/ To use Processor.\nusing static System.Console;\nWriteLine(\"In Main\");\nAlpha();\nvoid Alpha()\n{\n  WriteLine(\"In Alpha\");\n  Beta();\n}\nvoid Beta()\n{\n  WriteLine(\"In Beta\");\n  Processor.Gamma();\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app <em class=\"calibre10\">without<\/em> the debugger attached, and note the results, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">In Main\nIn Alpha\nIn Beta\nIn Gamma\nIn Delta\nUnhandled exception. System.IO.FileNotFoundException: Could not find file 'C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandling\\bin\\Debug\\net8.0\\bad file path'.\nFile name: 'C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandling\\bin\\Debug\\net8.0\\bad file path'\n   at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)\n   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)\n   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)\n   at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)\n   at System.IO.StreamReader.ValidateArgsAndOpenPath(String path, Encoding encoding, Int32 bufferSize)\n   at System.IO.File.OpenText(String path)\n   at CallStackExceptionHandlingLib.Calculator.Delta() in C:\\cs11dotnet8\\Chapter04\\CallStackExceptionHandlingLib\\Processor.cs:line 16\n   at CallStackExceptionHandlingLib.Calculator.Gamma() in C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandlingLib\\Processor.cs:line 10\n   at Program.&lt;&lt;Main&gt;$&gt;g__Beta|0_1() in C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandling\\Program.cs:line 16\n   at Program.&lt;&lt;Main&gt;$&gt;g__Alpha|0_0() in C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandling\\Program.cs:line 10\n   at Program.&lt;Main&gt;$(String[] args) in C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandling\\Program.cs:line 5<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note that the call stack is upside-down. Starting from the bottom, you see:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The first call is to the <code class=\"calibre9\">&lt;Main&gt;$<\/code> entry point function in the auto-generated <code class=\"calibre9\">Program<\/code> class. This is where arguments are passed in as a <code class=\"calibre9\">String<\/code> array.<\/li>\n<li class=\"calibre3\">The second call is to the <code class=\"calibre9\">&lt;&lt;Main&gt;$&gt;g__Alpha|0_0<\/code> function. (The C# compiler renames it from <code class=\"calibre9\">Alpha<\/code> when it adds it as a local function.)<\/li>\n<li class=\"calibre3\">The third call is to the <code class=\"calibre9\">Beta<\/code> function.<\/li>\n<li class=\"calibre3\">The fourth call is to the <code class=\"calibre9\">Gamma<\/code> function.<\/li>\n<li class=\"calibre3\">The fifth call is to the <code class=\"calibre9\">Delta<\/code> function. This function attempts to open a file by passing a bad file path. This causes an exception to be thrown. Any function with a <code class=\"calibre9\">try-catch<\/code> statement could catch this exception. If it does not, the exception is automatically passed up the call stack until it reaches the top, where .NET outputs the exception (and the details of this call stack).<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Unless you need to step through your code to debug it, you should always run your code without the debugger attached. In this case, it is especially important not to attach the debugger because, if you do, it will catch the exception and show it in a GUI dialog box instead of outputting it as shown in the book.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"5.7.5\" id=\"calibre_link-237\">\n<h3 data-number=\"5.7.5\" class=\"calibre8\">Where to catch exceptions<\/h3>\n<p class=\"rights\">Programmers can decide if they want to catch an exception near the failure point or centralized higher up the call stack. This allows your code to be simplified and standardized. You might know that calling an exception could throw one or more types of exception, but you do not need to handle any of them at the current point in the call stack.<\/p>\n<\/section>\n<section data-number=\"5.7.6\" id=\"calibre_link-238\">\n<h3 data-number=\"5.7.6\" class=\"calibre8\">Rethrowing exceptions<\/h3>\n<p class=\"rights\">Sometimes you want to catch an exception, log it, and then rethrow it. For example, if you are writing a low-level class library that will be called from an application, your code may not have enough information to programmatically fix the error in a smart way, but the calling application might have more information and be able to. Your code should log the error in case the calling application does not, and then rethrow it up the call stack in case the calling application chooses to handle it better. There are three ways to rethrow an exception inside a <code class=\"calibre9\">catch<\/code> block, as shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">To throw the caught exception with its original call stack, call <code class=\"calibre9\">throw<\/code>.<\/li>\n<li class=\"calibre3\">To throw the caught exception as if it was thrown at the current level in the call stack, call <code class=\"calibre9\">throw<\/code> with the caught exception, for example, <code class=\"calibre9\">throw ex<\/code>. This is usually poor practice because you have lost some potentially useful information for debugging but can be useful when you want to deliberately remove that information when it contains sensitive data.<\/li>\n<li class=\"calibre3\">To wrap the caught exception in another exception that can include more information in a message that might help the caller understand the problem, throw a new exception, and pass the caught exception as the <code class=\"calibre9\">innerException<\/code> parameter.<\/li>\n<\/ul>\n<p class=\"rights\">If an error could occur when we call the <code class=\"calibre9\">Gamma<\/code> function, then we could catch the exception and perform one of the three techniques of rethrowing an exception, as shown in the following code:<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">This code is just illustrative. You would never use all three techniques in the same <code class=\"calibre9\">catch<\/code> block!<\/p>\n<\/blockquote>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">try\n{\n  Gamma();\n}\ncatch (IOException ex)\n{\n  LogException(ex);\n  \/\/ Throw the caught exception as if it happened here\n  \/\/ this will lose the original call stack.\n  throw ex;\n  \/\/ Rethrow the caught exception and retain its original call stack.\n  throw;\n  \/\/ Throw a new exception with the caught exception nested within it.\n  throw new InvalidOperationException(\n    message: \"Calculation had invalid values. See inner exception for why.\",\n    innerException: ex);\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Let's see this in action with our call stack example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">CallStackExceptionHandling<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, in the <code class=\"calibre9\">Beta<\/code> function, add a <code class=\"calibre9\">try-catch<\/code> statement around the call to the <code class=\"calibre9\">Gamma<\/code> function, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">void Beta()\n{\n  WriteLine(\"In Beta\");\n  try\n  {\n    Processor.Gamma();\n  }\n  catch (Exception ex)\n  {\n    WriteLine($\"Caught this: {ex.Message}\");\n    throw ex;\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note your code editor will show a squiggle under the <code class=\"calibre9\">throw ex<\/code> to warn you that you will lose call stack information, as described in the following code analyzer message, <code class=\"calibre9\">Re-throwing caught exception changes stack information<\/code>, with more details found at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/fundamentals\/code-analysis\/quality-rules\/ca2200\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/fundamentals\/code-analysis\/quality-rules\/ca2200<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app and note that the output excludes some details of the call stack, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Caught this: Could not find file 'C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandling\\bin\\Debug\\net8.0\\bad file path'.\nUnhandled exception. System.IO.FileNotFoundException: Could not find file 'C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandling\\bin\\Debug\\net8.0\\bad file path'.\nFile name: 'C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandling\\bin\\Debug\\net8.0\\bad file path'\n   at Program.&lt;&lt;Main&gt;$&gt;g__Beta|0_1() in C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandling\\Program.cs:line 23\n   at Program.&lt;&lt;Main&gt;$&gt;g__Alpha|0_0() in C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandling\\Program.cs:line 10\n   at Program.&lt;Main&gt;$(String[] args) in C:\\cs12dotnet8\\Chapter04\\CallStackExceptionHandling\\Program.cs:line 5<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Remove the <code class=\"calibre9\">ex<\/code> by replacing the statement <code class=\"calibre9\">throw ex;<\/code> with <code class=\"calibre9\">throw;<\/code>.<\/li>\n<li class=\"calibre3\">Run the console app and note that the output includes all the details of the call stack.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"5.7.7\" id=\"calibre_link-239\">\n<h3 data-number=\"5.7.7\" class=\"calibre8\">Implementing the tester-doer and try patterns<\/h3>\n<p class=\"rights\">The <strong class=\"calibre2\">tester-doer pattern<\/strong> can avoid some thrown exceptions (but not eliminate them completely). This pattern uses pairs of functions: one to perform a test and the other to perform an action that would fail if the test was not passed..NET implements this pattern itself. For example, before adding an item to a collection by calling the <code class=\"calibre9\">Add<\/code> method, you can test to see if it is read-only, which would cause <code class=\"calibre9\">Add<\/code> to fail and, therefore, throw an exception.For example, before withdrawing money from a bank account, you might test that the account is not overdrawn, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (!bankAccount.IsOverdrawn())\n{\n  bankAccount.Withdraw(amount);\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The tester-doer pattern can add performance overhead, so you can also implement the <strong class=\"calibre2\">try pattern<\/strong>, which, in effect, combines the <code class=\"calibre9\">test<\/code> and <code class=\"calibre9\">do<\/code> parts into a single function, as we saw with <code class=\"calibre9\">TryParse<\/code>.Another problem with the tester-doer pattern occurs when you are using multiple threads. In this scenario, one thread calls the test function and it returns a value that indicates that it is okay to proceed. But then another thread executes, which changes the state. Then the original thread continues executing, assuming that everything is fine, but it is not fine. This is called a <em class=\"calibre10\">race condition<\/em>. This topic is too advanced to cover how to handle it in this book.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Use the try pattern in preference to the tester-doer pattern.<\/p>\n<\/blockquote>\n<p class=\"rights\">If you implement your own <code class=\"calibre9\">try<\/code> pattern function and it fails, remember to set the <code class=\"calibre9\">out<\/code> parameter to the default value of its type and then return <code class=\"calibre9\">false<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static bool TryParse(string? input, out Person value)\n{\n  if (someFailure)\n  {\n    value = default(Person);\n    return false;\n  }\n  \/\/ Successfully parsed the string into a Person.\n  value = new Person() { ... };\n  return true;\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: Now that you've been introduced to the basics of exceptions, you can learn more about the details by reading the official documentation at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/exceptions\/\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/exceptions\/<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"5.8\" id=\"calibre_link-240\">\n<h2 data-number=\"5.8\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring, with deeper research, the topics covered in this chapter.<\/p>\n<section data-number=\"5.8.1\" id=\"calibre_link-241\">\n<h3 data-number=\"5.8.1\" class=\"calibre8\">Exercise 4.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions. If you get stuck, try googling the answers, if necessary, while remembering that if you get totally stuck, the answers are in the Appendix:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does the C# keyword <code class=\"calibre9\">void<\/code> mean?<\/li>\n<li class=\"calibre3\">What are some differences between imperative and functional programming styles?<\/li>\n<li class=\"calibre3\">In Visual Studio Code or Visual Studio, what is the difference between pressing <span>F5<\/span>, <span>Ctrl <\/span>or <span>Cmd<\/span> + <span>F5<\/span>, <span>Shift<\/span> + <span>F5<\/span>, and <span>Ctrl<\/span> or <span>Cmd<\/span> + <span>Shift<\/span> + <span>F5<\/span>?<\/li>\n<li class=\"calibre3\">Where does the <code class=\"calibre9\">Trace.WriteLine<\/code> method write its output to?<\/li>\n<li class=\"calibre3\">What are the five trace levels?<\/li>\n<li class=\"calibre3\">What is the difference between the <code class=\"calibre9\">Debug<\/code> and <code class=\"calibre9\">Trace<\/code> classes?<\/li>\n<li class=\"calibre3\">When writing a unit test, what are the three \"A\"s?<\/li>\n<li class=\"calibre3\">When writing a unit test using xUnit, which attribute must you decorate the test methods with?<\/li>\n<li class=\"calibre3\">What <code class=\"calibre9\">dotnet<\/code> command executes xUnit tests?<\/li>\n<li class=\"calibre3\">What statement should you use to rethrow a caught exception named <code class=\"calibre9\">ex<\/code> without losing the stack trace?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"5.8.2\" id=\"calibre_link-242\">\n<h3 data-number=\"5.8.2\" class=\"calibre8\">Exercise 4.2 &ndash; Practice writing functions with debugging and unit testing<\/h3>\n<p class=\"rights\">Prime factors are the combination of the smallest prime numbers that, when multiplied together, will produce the original number. Consider the following examples:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Prime factors of 4 are 2 x 2<\/li>\n<li class=\"calibre3\">Prime factor of 7 is 7<\/li>\n<li class=\"calibre3\">Prime factors of 30 are 5 x 3 x 2<\/li>\n<li class=\"calibre3\">Prime factors of 40 are 5 x 2 x 2 x 2<\/li>\n<li class=\"calibre3\">Prime factors of 50 are 5 x 5 x 2<\/li>\n<\/ul>\n<p class=\"rights\">Create three projects:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A class library named <code class=\"calibre9\">Ch04Ex02PrimeFactorsLib<\/code> with a static class and static method named <code class=\"calibre9\">PrimeFactors<\/code>, which, when passed an <code class=\"calibre9\">int<\/code> variable as a parameter, returns a <code class=\"calibre9\">string<\/code> showing its prime factors.<\/li>\n<li class=\"calibre3\">A unit test project named <code class=\"calibre9\">Ch04Ex02PrimeFactorsTests<\/code> with a few suitable unit tests.<\/li>\n<li class=\"calibre3\">A console application to use it, named <code class=\"calibre9\">Ch04Ex02PrimeFactorsApp<\/code>.<\/li>\n<\/ul>\n<p class=\"rights\">To keep it simple, you can assume that the largest number entered will be 1,000.Use the debugging tools and write unit tests to ensure that your function works correctly with multiple inputs and returns the correct output.<\/p>\n<\/section>\n<section data-number=\"5.8.3\" id=\"calibre_link-243\">\n<h3 data-number=\"5.8.3\" class=\"calibre8\">Exercise 4.3 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more about the topics covered in this chapter:<\/p>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-4---writing-debugging-and-testing-functions\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-4---writing-debugging-and-testing-functions<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"5.9\" id=\"calibre_link-244\">\n<h2 data-number=\"5.9\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">How to write reusable functions with input parameters and return values, in both an imperative and functional style.<\/li>\n<li class=\"calibre3\">How to use the Visual Studio and Visual Studio Code debugging and diagnostic features like logging and unit tests to identify and fix any bugs in them.<\/li>\n<li class=\"calibre3\">How to throw and catch exceptions in functions and understand the call stack.<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will learn how to build your own types using object-oriented programming techniques.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-1\">\n<div id=\"calibre_link-1931\" class=\"calibre1\">\n<section data-number=\"6\" id=\"calibre_link-245\">\n<h1 data-number=\"6\" class=\"title\">5 Building Your Own Types with Object-Oriented Programming<\/h1>\n<section data-number=\"6.1\" id=\"calibre_link-246\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"6.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000062.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about making your own types using <strong class=\"calibre2\">object-oriented programming<\/strong> (<strong class=\"calibre2\">OOP<\/strong>). You will learn about all the different categories of members that a <em class=\"calibre10\">type<\/em> can have, including fields to store data and methods to perform actions. You will use OOP concepts such as aggregation and encapsulation. You will also learn about language features such as tuple syntax support, out variables, inferred tuple names, and default literals. Finally, you will learn about pattern matching and defining records to make the equality of variables and immutability easier to implement.This chapter will cover the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Talking about OOP<\/li>\n<li class=\"calibre3\">Building class libraries<\/li>\n<li class=\"calibre3\">Storing data in fields<\/li>\n<li class=\"calibre3\">Working with methods and tuples<\/li>\n<li class=\"calibre3\">Controlling access with properties and indexers<\/li>\n<li class=\"calibre3\">Pattern matching with objects<\/li>\n<li class=\"calibre3\">Working with record types<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"6.2\" id=\"calibre_link-247\">\n<h2 data-number=\"6.2\" class=\"calibre5\">Talking about OOP<\/h2>\n<p class=\"rights\">An object in the real world is a thing, such as a car or a person, whereas an object in programming often represents something in the real world, such as a product or bank account, but it can also be something more abstract.In C#, we use the C# keywords <code class=\"calibre9\">class<\/code>, <code class=\"calibre9\">record<\/code>, and <code class=\"calibre9\">struct<\/code> to define a type of object. You will learn about <code class=\"calibre9\">struct<\/code> types in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>. You can think of a type as being a blueprint or template for an object.The concepts of OOP are briefly described here:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Encapsulation<\/strong> is the combination of the data and actions that are related to an object. For example, a <code class=\"calibre9\">BankAccount<\/code> type might have data, such as <code class=\"calibre9\">Balance<\/code> and <code class=\"calibre9\">AccountName<\/code>, as well as actions, such as <code class=\"calibre9\">Deposit<\/code> and <code class=\"calibre9\">Withdraw<\/code>. When encapsulating, you often want to control what can access those actions and the data, for example, restricting how the internal state of an object can be accessed or modified from the outside.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Composition<\/strong> is about what an object is made of. For example, a <code class=\"calibre9\">Car<\/code> is composed of different parts, such as four <code class=\"calibre9\">Wheel<\/code> objects, several <code class=\"calibre9\">Seat<\/code> objects, and an <code class=\"calibre9\">Engine<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Aggregation<\/strong> is about what can be combined with an object. For example, a <code class=\"calibre9\">Person<\/code> is not part of a <code class=\"calibre9\">Car<\/code> object, but they could sit in the driver's <code class=\"calibre9\">Seat<\/code> and then become the car's <code class=\"calibre9\">Driver<\/code>&mdash;two separate objects that are aggregated together to form a new component.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Inheritance<\/strong> is about reusing code by having a <strong class=\"calibre2\">subclass<\/strong> derive from a <strong class=\"calibre2\">base<\/strong> or <strong class=\"calibre2\">superclass<\/strong>. All functionality in the base class is inherited by, and becomes available in, the <strong class=\"calibre2\">derived<\/strong> class. For example, the base or super <code class=\"calibre9\">Exception<\/code> class has some members that have the same implementation across all exceptions, and the sub or derived <code class=\"calibre9\">SqlException<\/code> class inherits those members and has extra members that are only relevant when a SQL database exception occurs, like a property for the database connection.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Abstraction<\/strong> is about capturing the core idea of an object and ignoring the details or specifics. C# has the <code class=\"calibre9\">abstract<\/code> keyword that formalizes this concept but do not confuse the concept of abstraction with meaning the use of the <code class=\"calibre9\">abstract<\/code> keyword because it is more than that. The concept of abstraction can also be achieved using interfaces. If a class is not explicitly <strong class=\"calibre2\">abstract<\/strong>, then it can be described as being <strong class=\"calibre2\">concrete<\/strong>. Bases or superclasses are often abstract; for example, the superclass <code class=\"calibre9\">Stream<\/code> is abstract, and its subclasses, like <code class=\"calibre9\">FileStream<\/code> and <code class=\"calibre9\">MemoryStream<\/code>, are concrete. Only concrete classes can be used to create objects; abstract classes can only be used as the base for other classes because they miss some implementation. Abstraction is a tricky balance. If you make a class more abstract, more classes will be able to inherit from it, but at the same time, there will be less functionality to share. A real-world example of abstraction is the approach car manufacturers have taken to electric vehicles (EVs). They create a common \"platform\" (basically just the battery and wheels) that is an abstraction of what all EVs need, and then add on top of that to build different vehicles like cars, trucks, vans, and so on. The platform on its own is not a complete product, like an abstract class.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Polymorphism<\/strong> is about allowing a derived class to override an inherited action to provide custom behavior.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">There is a lot to cover in the next two chapters about OOP, and some parts of it are difficult to learn. At the end of <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>, I have written a summary of the categories of custom types and their capabilities with example code. This will help you review the most important facts and highlight the differences between choices, like an <code class=\"calibre9\">abstract<\/code> class or an <code class=\"calibre9\">interface<\/code>, and when to use them.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.3\" id=\"calibre_link-248\">\n<h2 data-number=\"6.3\" class=\"calibre5\">Building class libraries<\/h2>\n<p class=\"rights\"><strong class=\"calibre2\">Class library<\/strong> assemblies group types together into easily deployable units (DLL files). Apart from when you learned about unit testing, you have only created console apps to contain your code. To make the code that you write reusable across multiple projects, you should put it in class library assemblies, just like Microsoft does.<\/p>\n<section data-number=\"6.3.1\" id=\"calibre_link-249\">\n<h3 data-number=\"6.3.1\" class=\"calibre8\">Creating a class library<\/h3>\n<p class=\"rights\">The first task is to create a reusable .NET class library:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to create a new project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Class Library<\/strong> \/ <code class=\"calibre9\">classlib<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">PacktLibraryNetStandard2<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter05<\/code><\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Open the <code class=\"calibre9\">PacktLibraryNetStandard2.csproj<\/code> file, and note that, by default, class libraries created by the .NET 8 SDK target .NET 8 and, therefore, can only be referenced by other .NET 8-compatible assemblies, as highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the framework to target .NET Standard 2.0, add an entry to explicitly use the C# 12 compiler, and statically import the <code class=\"calibre9\">System.Console<\/code> class for all C# files, as highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;!--.NET Standard 2.0 class library can be used by:\n        .NET Framework, Xamarin, modern .NET. --&gt;\n    &lt;TargetFramework&gt;netstandard2.0&lt;\/TargetFramework&gt;\n    &lt;!--Compile this library using C# 12 so we can use most\n        modern compiler features. --&gt;\n    &lt;LangVersion&gt;12&lt;\/LangVersion&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n  &lt;\/PropertyGroup&gt;\n  &lt;ItemGroup&gt;\n    &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n  &lt;\/ItemGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Although we can use the C# 12 compiler, some modern compiler features require a modern .NET runtime. For example, we cannot use default implementations in an interface (introduced in C# 8) because it requires .NET Standard 2.1. We cannot use the <code class=\"calibre9\">required<\/code> keyword (introduced in C# 11) because it requires an attribute introduced in .NET 7. But many useful modern compiler features, like raw literal strings, will be available to us.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Save and close the file.<\/li>\n<li class=\"calibre3\">Delete the file named <code class=\"calibre9\">Class1.cs<\/code>.<\/li>\n<li class=\"calibre3\">Compile the project so that other projects can reference it later:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">In Visual Studio 2022, navigate to <strong class=\"calibre2\">Build<\/strong> | <strong class=\"calibre2\">Build PacktLibraryNetStandard2<\/strong>.<\/li>\n<li class=\"calibre3\">In Visual Studio Code, enter the following command: <code class=\"calibre9\">dotnet build<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: To use all the latest C# language and .NET platform features, put types in a .NET 8 class library. To support legacy .NET platforms like .NET Core, .NET Framework, and Xamarin, put types that you might reuse in a .NET Standard 2.0 class library. By default, targeting .NET Standard 2.0 uses the C# 7 compiler, but this can be overridden so you get the benefits of the newer SDK and compiler even though you are limited to .NET Standard 2.0 APIs.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.3.2\" id=\"calibre_link-250\">\n<h3 data-number=\"6.3.2\" class=\"calibre8\">Understanding file-scoped namespaces<\/h3>\n<p class=\"rights\">Traditionally, you define types like a class nested in a namespace, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared\n{\n  public class Person\n  {\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you define multiple types in the same code file, then they can be in different namespaces, since the types must be explicitly inside the curly braces for each namespace.If you use C# 10 or later, you can simplify your code by ending a namespace declaration with a semicolon and removing the curly braces, so the type definitions do not need to be indented, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ All types in this file will be defined in this file-scoped namespace.\nnamespace Packt.Shared;\npublic class Person\n{\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This is known as a <strong class=\"calibre2\">file-scoped namespace<\/strong> declaration. You can only have one file-scoped namespace per file. This feature is especially useful for book writers who have limited horizontal space.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Put each type that you create in its own code file, or at least put types in the same namespace in the same code file so that you can use file-scoped namespace declarations.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.3.3\" id=\"calibre_link-251\">\n<h3 data-number=\"6.3.3\" class=\"calibre8\">Defining a class in a namespace<\/h3>\n<p class=\"rights\">The next task is to define a class that will represent a person:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibraryNetStandard2<\/code> project, add a new class file named <code class=\"calibre9\">Person.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, delete any existing statements, set the namespace to <code class=\"calibre9\">Packt.Shared<\/code>, and for the <code class=\"calibre9\">Person<\/code> class, set the access modifier to <code class=\"calibre9\">public<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ All types in this file will be defined in this file-scoped namespace.\nnamespace Packt.Shared;\npublic class Person\n{\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: We're doing this because it is important to put your classes in a logically named namespace. A better namespace name would be domain-specific, for example, <code class=\"calibre9\">System.Numerics<\/code> for types related to advanced numbers. In this case, the types we will create are <code class=\"calibre9\">Person<\/code>, <code class=\"calibre9\">BankAccount<\/code>, and <code class=\"calibre9\">WondersOfTheWorld<\/code>, and they do not have a typical domain, so we will use the more generic <code class=\"calibre9\">Packt.Shared<\/code>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.3.4\" id=\"calibre_link-252\">\n<h3 data-number=\"6.3.4\" class=\"calibre8\">Understanding type access modifiers<\/h3>\n<p class=\"rights\">Note that the C# keyword <code class=\"calibre9\">public<\/code> is applied before <code class=\"calibre9\">class<\/code>. This keyword is an <strong class=\"calibre2\">access modifier<\/strong>, and it allows for any other code to access this class even outside this class library.If you do not explicitly apply the <code class=\"calibre9\">public<\/code> keyword, then it will only be accessible within the assembly that defined it. This is because the implicit access modifier for a class is <code class=\"calibre9\">internal<\/code>. We need this class to be accessible outside the assembly, so we must make sure it is <code class=\"calibre9\">public<\/code>.If you have nested classes, meaning a class defined in another class, then the inner class could have the <code class=\"calibre9\">private<\/code> access modifier, which would mean it is not accessible outside its parent class.Introduced with .NET 7, the <code class=\"calibre9\">file<\/code> access modifier applied to a type means that type can only be used within its code file. This would only be useful if you define multiple classes in the same code file, which is rarely good practice but is used with source generators.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about the <code class=\"calibre9\">file<\/code> access modifier at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/file\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/file<\/a>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: The two most common access modifiers for a class are <code class=\"calibre9\">public<\/code> and <code class=\"calibre9\">internal<\/code> (the default access modifier for a class if not specified). Always explicitly specify the access modifier for a class to make it clear what it is. Other access modifiers include <code class=\"calibre9\">private<\/code> and <code class=\"calibre9\">file<\/code>, but they are rarely used.<\/p>\n<\/blockquote>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.3.5\" id=\"calibre_link-253\">\n<h3 data-number=\"6.3.5\" class=\"calibre8\">Understanding members<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">Person<\/code> type does not yet have any members encapsulated within it. We will create some over the following pages. Members can be fields, methods, or specialized versions of both. You'll find a description of them here:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Fields<\/strong> are used to store data. You can think of fields as variables that belong to a type. There are also three specialized categories of field, as shown in the following bullets:\n<ul class=\"calibre16\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Constant<\/strong>: The data never changes. The compiler literally copies the data into any code that reads it. For example, <code class=\"calibre9\">byte.MaxValue<\/code> is always <code class=\"calibre9\">255<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Read-only<\/strong>: The data cannot change after the class is instantiated, but the data can be calculated or loaded from an external source at the time of instantiation. For example, <code class=\"calibre9\">DateTime.UnixEpoch<\/code> is January 1, 1970.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Event<\/strong>: The data references one or more methods that you want to execute when something happens, such as clicking on a button or responding to a request from some other code. Events will be covered in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>. For example, <code class=\"calibre9\">Console.CancelKeyPress<\/code> happens when <span>Ctrl<\/span>+<span>C<\/span> or <span>Ctrl<\/span>+<span>Break<\/span> are pressed in a console app.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Methods<\/strong> are used to execute statements. You saw some examples when you learned about functions in <em class=\"calibre10\">Chapter 4<\/em>, <em class=\"calibre10\">Writing, Debugging, and Testing Functions<\/em>. There are also four specialized categories of methods:\n<ul class=\"calibre16\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Constructor<\/strong>: The statements execute when you use the <code class=\"calibre9\">new<\/code> keyword to allocate memory to instantiate a class. For example, to instantiate Christmas Day 2023, you could write the following code: <code class=\"calibre9\">new DateTime(2023, 12, 25)<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Property<\/strong>: The statements execute when you get or set data. The data is commonly stored in a field but can be stored externally or calculated at runtime. Properties are the preferred way to encapsulate fields unless the memory address of the field needs to be exposed, for example, <code class=\"calibre9\">Console.ForegroundColor<\/code> to set the current color of text in a console app.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Indexer<\/strong>: The statements execute when you get or set data using \"array\" syntax <code class=\"calibre9\">[]<\/code>. For example, use <code class=\"calibre9\">name[o]<\/code> to get the first character in the <code class=\"calibre9\">name<\/code> variable, which is a <code class=\"calibre9\">string<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Operator<\/strong>: The statements execute when you apply an operator like <code class=\"calibre9\">+<\/code> and <code class=\"calibre9\">\/<\/code> to operands of your type. For example, use <code class=\"calibre9\">a + b<\/code> to add two variables together.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"6.3.6\" id=\"calibre_link-254\">\n<h3 data-number=\"6.3.6\" class=\"calibre8\">Importing a namespace to use a type<\/h3>\n<p class=\"rights\">In this section, we will make an instance of the <code class=\"calibre9\">Person<\/code> class.Before we can instantiate a class, we need to reference the assembly that contains it from another project. We will use the class in a console app:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> named <code class=\"calibre9\">PeopleApp<\/code> to the <code class=\"calibre9\">Chapter05<\/code> solution. Make sure you <em class=\"calibre10\">add<\/em> the new project to the existing <code class=\"calibre9\">Chapter05<\/code> solution because you are about to reference from the console app project to the existing class library project so both projects must be in the same solution.<\/li>\n<li class=\"calibre3\">If you use Visual Studio 2022:\n<ol class=\"toc1\">\n<li class=\"calibre3\">Configure the startup project for the solution to the current selection.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, select the <code class=\"calibre9\">PeopleApp<\/code> project, navigate to <strong class=\"calibre2\">Project<\/strong> | <strong class=\"calibre2\">Add Project Reference\u2026<\/strong>, check the box to select the <code class=\"calibre9\">PacktLibraryNetStandard2<\/code> project, and then click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">PeopleApp.csproj<\/code>, add an entry to statically import the <code class=\"calibre9\">System.Console<\/code> class, as shown in the following markup:<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Build<\/strong> | <strong class=\"calibre2\">Build PeopleApp<\/strong>.<\/li>\n<\/ol>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you use Visual Studio Code:\n<ol class=\"toc1\">\n<li class=\"calibre3\">Edit <code class=\"calibre9\">PeopleApp.csproj<\/code> to add a project reference to <code class=\"calibre9\">PacktLibraryNetStandard2<\/code>, and add an entry to statically import the <code class=\"calibre9\">System.Console<\/code> class, as highlighted in the following markup:<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n  &lt;\/PropertyGroup&gt;\n  &lt;ItemGroup&gt;\n    &lt;ProjectReference Include=\n      \"..\/PacktLibraryNetStandard2\/PacktLibraryNetStandard2.csproj\" \/&gt;\n  &lt;\/ItemGroup&gt;\n  &lt;ItemGroup&gt;\n    &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n  &lt;\/ItemGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In a terminal, compile the <code class=\"calibre9\">PeopleApp<\/code> project and its dependency <code class=\"calibre9\">PacktLibraryNetStandard2<\/code> project, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet build<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PeopleApp<\/code> project, add a new class file named <code class=\"calibre9\">Program.Methods.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Methods.cs<\/code>, delete any existing statements, and define a <code class=\"calibre9\">partial Program<\/code> class with a method to configure the console to enable special symbols, like the euro currency, and to control the current culture, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Globalization; \/\/ To use CultureInfo.\npartial class Program\n{\n  private static void ConfigureConsole(\n    string culture = \"en-US\",\n    bool useComputerCulture = false,\n    bool showCulture = true)\n  {\n    OutputEncoding = System.Text.Encoding.UTF8;\n    if (!useComputerCulture)\n    {\n      CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo(culture);\n    }\n    if (showCulture)\n    {\n      WriteLine($\"Current culture: {CultureInfo.CurrentCulture.DisplayName}.\");\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">By the end of this chapter, you will understand how the preceding method uses C# features like partial classes, optional parameters, and so on. If you would like to learn more about working with languages and cultures, as well as dates, times, and time zones, then there is a chapter about globalization and localization in my companion book, <em class=\"calibre10\">Apps and Services with .NET 8<\/em>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.3.7\" id=\"calibre_link-255\">\n<h3 data-number=\"6.3.7\" class=\"calibre8\">Instantiating a class<\/h3>\n<p class=\"rights\">Now, we are ready to write statements to instantiate the <code class=\"calibre9\">Person<\/code> class:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PeopleApp<\/code> project, in the <code class=\"calibre9\">Program.cs<\/code> file, delete the existing statements, then add statements to import the namespace for our <code class=\"calibre9\">Person<\/code> class, and then call the <code class=\"calibre9\">ConfigureConsole<\/code> method without any arguments so that it sets the current culture to US English, allowing all readers to see the same output, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Packt.Shared; \/\/ To use Person.\nConfigureConsole(); \/\/ Sets current culture to US English.\n\/\/ Alternatives:\n\/\/ ConfigureConsole(useComputerCulture: true); \/\/ Use your culture.\n\/\/ ConfigureConsole(culture: \"fr-FR\"); \/\/ Use French culture.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Although we could import the <code class=\"calibre9\">Packt.Shared<\/code> namespace globally, it will be clearer to anyone reading this code where we import the types we use from if the <code class=\"calibre9\">import<\/code> statement is at the top of the file, and the <code class=\"calibre9\">PeopleApp<\/code> project will only have this one <code class=\"calibre9\">Program.cs<\/code> file that needs the namespace imported.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Create an instance of the <code class=\"calibre9\">Person<\/code> type.<\/li>\n<li class=\"calibre3\">Output the instance using a textual description of itself.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p class=\"rights\">The <code class=\"calibre9\">new<\/code> keyword allocates memory for the object and initializes any internal data, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Person bob = new Person(); \/\/ C# 1 or later.\n\/\/ var bob = new Person(); \/\/ C# 3 or later.\nPerson bob = new(); \/\/ C# 9 or later.\nWriteLine(bob); \/\/ Implicit call to ToString().\n\/\/ WriteLine(bob.ToString()); \/\/ Does the same thing.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Current culture: English (United States).\nPackt.Shared.Person<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You might be wondering, \"Why does the <code class=\"calibre9\">bob<\/code> variable have a method named <code class=\"calibre9\">ToString<\/code>? The <code class=\"calibre9\">Person<\/code> class is empty!\" Don't worry, we're about to find out!<\/p>\n<\/section>\n<section data-number=\"6.3.8\" id=\"calibre_link-256\">\n<h3 data-number=\"6.3.8\" class=\"calibre8\">Inheriting from System.Object<\/h3>\n<p class=\"rights\">Although our <code class=\"calibre9\">Person<\/code> class did not explicitly choose to inherit from a type, all types ultimately inherit directly or indirectly from a special type named <code class=\"calibre9\">System.Object<\/code>. The implementation of the <code class=\"calibre9\">ToString<\/code> method in the <code class=\"calibre9\">System.Object<\/code> type outputs the full namespace and type name.Back in the original <code class=\"calibre9\">Person<\/code> class, we could have explicitly told the compiler that <code class=\"calibre9\">Person<\/code> inherits from the <code class=\"calibre9\">System.Object<\/code> type, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class Person : System.Object<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When class B is inherited from class A, we say that A is the base or superclass, and B is the derived or subclass. In this case, <code class=\"calibre9\">System.Object<\/code> is the base or superclass, and <code class=\"calibre9\">Person<\/code> is the derived or subclass. You can also use the C# keyword <code class=\"calibre9\">object<\/code>.Let's make our class explicitly inherit from <code class=\"calibre9\">object<\/code> and then review what members all objects have:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify your <code class=\"calibre9\">Person<\/code> class to explicitly inherit from <code class=\"calibre9\">object<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class Person : object<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Click inside the <code class=\"calibre9\">object<\/code> keyword and press <em class=\"calibre10\">F12<\/em>, or right-click on the <code class=\"calibre9\">object<\/code> keyword and choose <strong class=\"calibre2\">Go to Definition<\/strong>.<\/li>\n<\/ol>\n<p class=\"rights\">You will see the Microsoft-defined <code class=\"calibre9\">System.Object<\/code> type and its members. This is something you don't need to understand the details of yet, but note that the class is in a .NET Standard 2.0 class library assembly and has a method named <code class=\"calibre9\">ToString<\/code>, as shown in <em class=\"calibre10\">Figure 5.1<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 5.1: System.Object class definition in .NET Standard 2.0\" height=\"795\" src=\"\/images\/cs12\/000078.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 5.1: System.Object class definition in .NET Standard 2.0<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Assume other programmers know that if inheritance is not specified, the class will inherit from <code class=\"calibre9\">System.Object<\/code>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.3.9\" id=\"calibre_link-257\">\n<h3 data-number=\"6.3.9\" class=\"calibre8\">Avoiding a namespace conflict with a using alias<\/h3>\n<p class=\"rights\">We need to learn a bit more about namespaces and their types. It is possible that there are two namespaces that contain the same type name, and importing both namespaces causes ambiguity. For example, <code class=\"calibre9\">JsonOptions<\/code> exists in multiple Microsoft-defined namespaces. If you use the wrong one to configure JSON serialization, then it will be ignored and you'll be confused why!Let's review a made-up example:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ In the file, France.Paris.cs\nnamespace France\n{\n  public class Paris\n  {\n  }\n}\n\/\/ In the file, Texas.Paris.cs\nnamespace France\n{\n  public class Paris\n  {\n  }\n}\n\/\/ In the file, Program.cs\nusing France;\nusing Texas;\nParis p = new();<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If we build this project, then the compiler would complain with the following error:<code class=\"calibre9\">Error CS0104: 'Paris' is an ambiguous reference between 'France.Paris' and 'Texas.Paris'<\/code>We can define an alias for one of the namespaces to differentiate it, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using France; \/\/ To use Paris.\nusing Tx = Texas; \/\/ Tx becomes alias for the namespace, and it is not imported.\nParis p1 = new(); \/\/ Creates an instance of France.Paris.\nTx.Paris p2 = new(); \/\/ Creates an instance of Texas.Paris.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"6.3.10\" id=\"calibre_link-258\">\n<h3 data-number=\"6.3.10\" class=\"calibre8\">Renaming a type with a using alias<\/h3>\n<p class=\"rights\">Another situation where you might want to use an alias is if you would like to rename a type. For example, if you use the <code class=\"calibre9\">Environment<\/code> class in the <code class=\"calibre9\">System<\/code> namespace a lot, you could rename it with an alias to make it shorter, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Env = System.Environment;\nWriteLine(Env.OSVersion);\nWriteLine(Env.MachineName);\nWriteLine(Env.CurrentDirectory);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Starting with C# 12, you can alias any type. This means you can rename existing types or give a type name to unnamed types like tuples, as you will see later in this chapter.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"6.4\" id=\"calibre_link-259\">\n<h2 data-number=\"6.4\" class=\"calibre5\">Storing data in fields<\/h2>\n<p class=\"rights\">In this section, we will define a selection of fields in the class to store information about a person.<\/p>\n<section data-number=\"6.4.1\" id=\"calibre_link-260\">\n<h3 data-number=\"6.4.1\" class=\"calibre8\">Defining fields<\/h3>\n<p class=\"rights\">Let's say that we have decided that a person is composed of a name and a date and time of birth. We will encapsulate these two values inside a person, and the values will be visible outside it.<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Inside the <code class=\"calibre9\">Person<\/code> class, write statements to declare two public fields to store a person's name and the date of when they were born, as highlighted in the following code:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class Person : object\n{\n  #region Fields: Data or state for this person.\n  public string? Name; \/\/ ? means it can be null.\n  public DateTimeOffset Born;\n  #endregion\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">We have multiple choices for the data type of the <code class=\"calibre9\">Born<\/code> field. .NET 6 introduced the <code class=\"calibre9\">DateOnly<\/code> type. This would store only the date without a time value. <code class=\"calibre9\">DateTime<\/code> stores the date and time of when the person was born, but it varies between local and UTC time. The best choice is <code class=\"calibre9\">DateTimeOffset<\/code>, which stores the date, time, and hours offset from <strong class=\"calibre2\">Universal Coordinated Time<\/strong> (<strong class=\"calibre2\">UTC<\/strong>), which is related to the time zone. The choice depends on how much detail you need to store.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.4.2\" id=\"calibre_link-261\">\n<h3 data-number=\"6.4.2\" class=\"calibre8\">Types for fields<\/h3>\n<p class=\"rights\">Since C# 8, the compiler has had the ability to warn you if a reference type like a <code class=\"calibre9\">string<\/code> could have a <code class=\"calibre9\">null<\/code> value and, therefore, potentially throw a <code class=\"calibre9\">NullReferenceException<\/code>. Since .NET 6, the SDK enables those warnings by default. You can suffix the <code class=\"calibre9\">string<\/code> type with a question mark, <code class=\"calibre9\">?<\/code>, to indicate that you accept this, and the warning disappears. You will learn more about nullability and how to handle it in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>.You can use any type for a field, including arrays and collections such as lists and dictionaries. These would be used if you needed to store multiple values in one named field. In this example, a person only has one name and one date and time of birth.<\/p>\n<\/section>\n<section data-number=\"6.4.3\" id=\"calibre_link-262\">\n<h3 data-number=\"6.4.3\" class=\"calibre8\">Member access modifiers<\/h3>\n<p class=\"rights\">Part of encapsulation is choosing how visible members are to other code.Note that, as we did with the class, we explicitly applied the <code class=\"calibre9\">public<\/code> keyword to these fields. If we hadn't, then they would be implicitly <code class=\"calibre9\">private<\/code> to the class, which means they are accessible only inside the class.There are four <strong class=\"calibre2\">member access modifier<\/strong> keywords, and two combinations of access modifier keywords that you can apply to a class member, like a field or method. Member access modifiers apply to an individual member. They are similar to but separate from type access modifiers that apply to the whole type. The six possible combinations are shown in <em class=\"calibre10\">Table 5.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Member Access Modifier<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">private<\/code><\/td>\n<td class=\"calibre21\">The member is accessible inside the type only. This is the default.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">internal<\/code><\/td>\n<td class=\"calibre21\">The member is accessible inside the type and any type in the same assembly.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">protected<\/code><\/td>\n<td class=\"calibre21\">The member is accessible inside the type and any type that inherits from the type.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">public<\/code><\/td>\n<td class=\"calibre21\">The member is accessible everywhere.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">internal protected<\/code><\/td>\n<td class=\"calibre21\">The member is accessible inside the type, any type in the same assembly, and any type that inherits from the type. Equivalent to a fictional access modifier named <code class=\"calibre9\">internal_or_protected<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">private protected<\/code><\/td>\n<td class=\"calibre21\">The member is accessible inside the type and any type that inherits from the type and is in the same assembly. Equivalent to a fictional access modifier named <code class=\"calibre9\">internal_and_protected<\/code> . This combination is only available with C# 7.2 or later.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 5.1: Six member access modifiers<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Explicitly apply one of the access modifiers to all type members, even if you want to use the implicit access modifier for members, which is <code class=\"calibre9\">private<\/code>. Additionally, fields should usually be <code class=\"calibre9\">private<\/code> or <code class=\"calibre9\">protected<\/code>, and you should then create <code class=\"calibre9\">public<\/code> properties to get or set the field values. This is because the property then controls access. You will do this later in the chapter.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.4.4\" id=\"calibre_link-263\">\n<h3 data-number=\"6.4.4\" class=\"calibre8\">Setting and outputting field values<\/h3>\n<p class=\"rights\">Now we will use those fields in your code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, after instantiating <code class=\"calibre9\">bob<\/code>, add statements to set his name and date and time of birth, and then output those fields formatted nicely, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">bob.Name = \"Bob Smith\";\nbob.Born = new DateTimeOffset(\n  year: 1965, month: 12, day: 22,\n  hour: 16, minute: 28, second: 0, \n  offset: TimeSpan.FromHours(-5)); \/\/ US Eastern Standard Time.\nWriteLine(format: \"{0} was born on {1:D}.\", \/\/ Long date.\n  arg0: bob.Name, arg1: bob.Born);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The format code for <code class=\"calibre9\">arg1<\/code> is one of the standard date and time formats. <code class=\"calibre9\">D<\/code> means a long date format and <code class=\"calibre9\">d<\/code> would mean a short date format. You can learn more about standard date and time format codes at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/base-types\/standard-date-and-time-format-strings\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/base-types\/standard-date-and-time-format-strings<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Bob Smith was born on Wednesday, December 22, 1965.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you change the call to <code class=\"calibre9\">ConfigureConsole<\/code> to use your local computer culture or a specified culture like French in France (<code class=\"calibre9\">\"fr-FR\"<\/code>), then your output will look different.<\/p>\n<\/section>\n<section data-number=\"6.4.5\" id=\"calibre_link-264\">\n<h3 data-number=\"6.4.5\" class=\"calibre8\">Setting field values using object initializer syntax<\/h3>\n<p class=\"rights\">You can also initialize fields using a shorthand <strong class=\"calibre2\">object initializer<\/strong> syntax with curly braces, which was introduced with C# 3. Let's see how:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements underneath the existing code to create another new person named Alice. Note the different standard format code for the date and time of birth when writing her to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Person alice = new()\n{\n  Name = \"Alice Jones\",\n  Born = new(1998, 3, 7, 16, 28, 0,\n    \/\/ This is an optional offset from UTC time zone.\n    TimeSpan.Zero)\n};\nWriteLine(format: \"{0} was born on {1:d}.\", \/\/ Short date.\n  arg0: alice.Name, arg1: alice.Born);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">We could have used string interpolation to format the output, but for long strings, it will wrap over multiple lines, which can be harder to read in a printed book. In the code examples in this book, remember that <code class=\"calibre9\">{0}<\/code> is a placeholder for <code class=\"calibre9\">arg0<\/code>, and so on.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Alice Jones was born on 3\/7\/1998.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Use named parameters to pass arguments, so it is clearer what the values mean, especially for types like <code class=\"calibre9\">DateTimeOffset<\/code> where there are a bunch of numbers one after the other.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.4.6\" id=\"calibre_link-265\">\n<h3 data-number=\"6.4.6\" class=\"calibre8\">Storing a value using an enum type<\/h3>\n<p class=\"rights\">Sometimes, a value needs to be one of a limited set of options. For example, there are seven ancient wonders of the world, and a person may have one favorite. At other times, a value needs to be a combination of a limited set of options. For example, a person may have a bucket list of ancient world wonders they want to visit. We can store this data by defining an <code class=\"calibre9\">enum<\/code> type.An <code class=\"calibre9\">enum<\/code> type is a very efficient way of storing one or more choices because, internally, it uses integer values in combination with a lookup table of <code class=\"calibre9\">string<\/code> descriptions. Let's see an example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a new file to the <code class=\"calibre9\">PacktLibraryNetStandard2<\/code> project named <code class=\"calibre9\">WondersOfTheAncientWorld.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify the <code class=\"calibre9\">WondersOfTheAncientWorld.cs<\/code> contents, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic enum WondersOfTheAncientWorld\n{\n  GreatPyramidOfGiza,\n  HangingGardensOfBabylon,\n  StatueOfZeusAtOlympia,\n  TempleOfArtemisAtEphesus,\n  MausoleumAtHalicarnassus,\n  ColossusOfRhodes,\n  LighthouseOfAlexandria\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, define a field to store a person's favorite ancient world wonder, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public WondersOfTheAncientWorld FavoriteAncientWonder;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, set Bob's favorite ancient wonder of the world and output it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">bob.FavoriteAncientWonder = WondersOfTheAncientWorld.StatueOfZeusAtOlympia;\nWriteLine(\n  format: \"{0}'s favorite wonder is {1}. Its integer is {2}.\",\n  arg0: bob.Name,\n  arg1: bob.FavoriteAncientWonder,\n  arg2: (int)bob.FavoriteAncientWonder);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Bob Smith's favorite wonder is StatueOfZeusAtOlympia. Its integer is 2.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">enum<\/code> value is internally stored as an <code class=\"calibre9\">int<\/code> for efficiency. The <code class=\"calibre9\">int<\/code> values are automatically assigned starting at <code class=\"calibre9\">0<\/code>, so the third-world wonder in our <code class=\"calibre9\">enum<\/code> has a value of <code class=\"calibre9\">2<\/code>. You can assign <code class=\"calibre9\">int<\/code> values that are not listed in the <code class=\"calibre9\">enum<\/code>. They will output as the <code class=\"calibre9\">int<\/code> value instead of a name, since a match will not be found.<\/p>\n<\/section>\n<section data-number=\"6.4.7\" id=\"calibre_link-266\">\n<h3 data-number=\"6.4.7\" class=\"calibre8\">Storing multiple values using an enum type<\/h3>\n<p class=\"rights\">For the bucket list, we could create an array or collection of instances of the <code class=\"calibre9\">enum<\/code>, and collections as fields will be shown later in this chapter, but there is a better approach for this scenario. We can combine multiple choices into a single value using <code class=\"calibre9\">enum<\/code> flags. Let's see how:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the <code class=\"calibre9\">enum<\/code> by decorating it with the <code class=\"calibre9\">[Flags]<\/code> attribute, and explicitly set a <code class=\"calibre9\">byte<\/code> value for each wonder that represents different bit columns, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\n[Flags]\npublic enum WondersOfTheAncientWorld : byte\n{\n  None                     = 0b_0000_0000, \/\/ i.e. 0\n  GreatPyramidOfGiza       = 0b_0000_0001, \/\/ i.e. 1\n  HangingGardensOfBabylon  = 0b_0000_0010, \/\/ i.e. 2\n  StatueOfZeusAtOlympia    = 0b_0000_0100, \/\/ i.e. 4\n  TempleOfArtemisAtEphesus = 0b_0000_1000, \/\/ i.e. 8\n  MausoleumAtHalicarnassus = 0b_0001_0000, \/\/ i.e. 16\n  ColossusOfRhodes         = 0b_0010_0000, \/\/ i.e. 32\n  LighthouseOfAlexandria   = 0b_0100_0000  \/\/ i.e. 64\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">We assign explicit values for each choice that will not overlap when looking at the bits stored in memory. We should also decorate the <code class=\"calibre9\">enum<\/code> type with the <code class=\"calibre9\">System.Flags<\/code> attribute so that when the value is returned, it can automatically match with multiple values as a comma-separated <code class=\"calibre9\">string<\/code> instead of returning an <code class=\"calibre9\">int<\/code> value.Normally, an <code class=\"calibre9\">enum<\/code> type uses an <code class=\"calibre9\">int<\/code> variable internally, but since we don't need values that big, we can reduce memory requirements by 75%, that is, 1 byte per value instead of 4 bytes, by telling it to use a <code class=\"calibre9\">byte<\/code> variable. As another example, if you wanted to define an <code class=\"calibre9\">enum<\/code> for days of the week, there will only ever be seven of them.If we want to indicate that our bucket list includes the <em class=\"calibre10\">Hanging Gardens of Babylon<\/em> and the <em class=\"calibre10\">Mausoleum at Halicarnassus<\/em> ancient world wonders, then we would want the <code class=\"calibre9\">16<\/code> and <code class=\"calibre9\">2<\/code> bits set to <code class=\"calibre9\">1<\/code>. In other words, we would store the value <code class=\"calibre9\">18<\/code>, as shown in <em class=\"calibre10\">Table 5.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">64<\/td>\n<td class=\"calibre21\">32<\/td>\n<td class=\"calibre21\">16<\/td>\n<td class=\"calibre21\">8<\/td>\n<td class=\"calibre21\">4<\/td>\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">1<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">0<\/td>\n<td class=\"calibre21\">0<\/td>\n<td class=\"calibre21\">1<\/td>\n<td class=\"calibre21\">0<\/td>\n<td class=\"calibre21\">0<\/td>\n<td class=\"calibre21\">1<\/td>\n<td class=\"calibre21\">0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 5.2: Storing 18 as bits in an enum<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, leave the existing field to store a single favorite ancient world wonder and add the following statement to your list of fields to store multiple ancient world wonders, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public WondersOfTheAncientWorld BucketList;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to set the bucket list using the <code class=\"calibre9\">|<\/code> operator (the bitwise logical <code class=\"calibre9\">OR<\/code>) to combine the <code class=\"calibre9\">enum<\/code> values. We could also set the value using the number <code class=\"calibre9\">18<\/code> cast into the <code class=\"calibre9\">enum<\/code> type, as shown in the comment, but we shouldn't because that would make the code harder to understand, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">bob.BucketList = \n  WondersOfTheAncientWorld.HangingGardensOfBabylon\n  | WondersOfTheAncientWorld.MausoleumAtHalicarnassus;\n\/\/ bob.BucketList = (WondersOfTheAncientWorld)18;\nWriteLine($\"{bob.Name}'s bucket list is {bob.BucketList}.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Bob Smith's bucket list is HangingGardensOfBabylon, MausoleumAtHalicarnassus.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Use the <code class=\"calibre9\">enum<\/code> values to store combinations of discrete options. Derive an <code class=\"calibre9\">enum<\/code> type from <code class=\"calibre9\">byte<\/code> if there are up to eight options, from <code class=\"calibre9\">ushort<\/code> if there are up to 16 options, from <code class=\"calibre9\">uint<\/code> if there are up to 32 options, and from <code class=\"calibre9\">ulong<\/code> if there are up to 64 options.<\/p>\n<\/blockquote>\n<p class=\"rights\">Now that we have decorated the <code class=\"calibre9\">enum<\/code> with the <code class=\"calibre9\">[Flags]<\/code> attribute, combinations of values can be stored in a single variable or field. Now a programmer could store a combination of values in the <code class=\"calibre9\">FavoriteAncientWonder<\/code> too when it should only store one value. To enforce this, we should convert the field into a property that allows us to take control over how other programmers can get and set the value. You will see how to do this later in this chapter.<\/p>\n<\/section>\n<section data-number=\"6.4.8\" id=\"calibre_link-267\">\n<h3 data-number=\"6.4.8\" class=\"calibre8\">Storing multiple values using collections<\/h3>\n<p class=\"rights\">Let's now add a field to store a person's children. This is an example of aggregation because children are instances of a class that is related to the current person, but they are not part of the person itself. We will use a generic <code class=\"calibre9\">List&lt;T&gt;<\/code> collection type that can store an ordered collection of any type. You will learn more about collections in <em class=\"calibre10\">Chapter 8<\/em>, <em class=\"calibre10\">Working with Common .NET Types<\/em>. For now, just follow along:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, declare a new field to store multiple <code class=\"calibre9\">Person<\/code> instances that represent the children of this person, as shown in the following code:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public List&lt;Person&gt; Children = new();<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><code class=\"calibre9\">List&lt;Person&gt;<\/code> is read aloud as \"list of <code class=\"calibre9\">Person<\/code>,\" for example, \"the type of the property named <code class=\"calibre9\">Children<\/code> is a list of <code class=\"calibre9\">Person<\/code> instances.\"We must ensure the collection is initialized to a new instance before we can add items to it; otherwise, the field will be <code class=\"calibre9\">null<\/code> and throw runtime exceptions when we try to use any of its members, like <code class=\"calibre9\">Add<\/code>.<\/p>\n<\/section>\n<section data-number=\"6.4.9\" id=\"calibre_link-268\">\n<h3 data-number=\"6.4.9\" class=\"calibre8\">Understanding generic collections<\/h3>\n<p class=\"rights\">The angle brackets in the <code class=\"calibre9\">List&lt;T&gt;<\/code> type is a feature of C# called <strong class=\"calibre2\">generics<\/strong> that was introduced in 2005 with C# 2. It's a fancy term for making a collection <strong class=\"calibre2\">strongly typed<\/strong>, that is, the compiler knows specifically what type of object can be stored in the collection. Generics improve the performance and correctness of your code.<strong class=\"calibre2\">Strongly typed<\/strong> has a different meaning than <strong class=\"calibre2\">statically typed<\/strong>. The old <code class=\"calibre9\">System.Collection<\/code> types are statically typed to contain weakly typed <code class=\"calibre9\">System.Object<\/code> items. The newer <code class=\"calibre9\">System.Collection.Generic<\/code> types are statically typed to contain strongly typed <code class=\"calibre9\">&lt;T&gt;<\/code> instances.Ironically, the term <em class=\"calibre10\">generics<\/em> means we can use a more specific static type!<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to add three children for <code class=\"calibre9\">Bob<\/code>, and then show how many children he has and what their names are, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Works with all versions of C#.\nPerson alfred = new Person();\nalfred.Name = \"Alfred\";\nbob.Children.Add(alfred);\n\/\/ Works with C# 3 and later.\nbob.Children.Add(new Person { Name = \"Bella\" });\n\/\/ Works with C# 9 and later.\nbob.Children.Add(new() { Name = \"Zoe\" });\nWriteLine($\"{bob.Name} has {bob.Children.Count} children:\");\nfor (int childIndex = 0; childIndex &lt; bob.Children.Count; childIndex++)\n{\n  WriteLine($\"&gt; {bob.Children[childIndex].Name}\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Bob Smith has 3 children:\n&gt; Alfred\n&gt; Bella\n&gt; Zoe<\/code><\/pre>\n<\/div>\n<p class=\"rights\">We could also use a <code class=\"calibre9\">foreach<\/code> statement to enumerate over the collection. As an optional challenge, change the <code class=\"calibre9\">for<\/code> statement to output the same information using <code class=\"calibre9\">foreach<\/code>.<\/p>\n<\/section>\n<section data-number=\"6.4.10\" id=\"calibre_link-269\">\n<h3 data-number=\"6.4.10\" class=\"calibre8\">Making a field static<\/h3>\n<p class=\"rights\">The fields that we have created so far have all been <strong class=\"calibre2\">instance<\/strong> members, meaning that a different value of each field exists for each instance of the class that is created. The <code class=\"calibre9\">alice<\/code> and <code class=\"calibre9\">bob<\/code> variables have different <code class=\"calibre9\">Name<\/code> values.Sometimes, you want to define a field that only has one value that is shared across all instances.These are called <strong class=\"calibre2\">static members<\/strong> because fields are not the only members that can be static. Let's see what can be achieved using <code class=\"calibre9\">static<\/code> fields using a bank account as an example. Each instance of <code class=\"calibre9\">BankAccount<\/code> will have its own <code class=\"calibre9\">AccountName<\/code> and <code class=\"calibre9\">Balance<\/code> values, but all instances will share a single <code class=\"calibre9\">InterestRate<\/code> value.Let's do it:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibraryNetStandard2<\/code> project, add a new class file named <code class=\"calibre9\">BankAccount.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify the class to give it three fields &ndash; two instance fields and one static field &ndash; as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class BankAccount\n{\n  public string? AccountName; \/\/ Instance member. It could be null.\n  public decimal Balance; \/\/ Instance member. Defaults to zero.\n  public static decimal InterestRate; \/\/ Shared member. Defaults to zero.\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to set the shared interest rate, and then create two instances of the <code class=\"calibre9\">BankAccount<\/code> type, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">BankAccount.InterestRate = 0.012M; \/\/ Store a shared value in static field.\nBankAccount jonesAccount = new();\njonesAccount.AccountName = \"Mrs. Jones\"; \njonesAccount.Balance = 2400;\nWriteLine(format: \"{0} earned {1:C} interest.\",\n  arg0: jonesAccount.AccountName,\n  arg1: jonesAccount.Balance * BankAccount.InterestRate);\nBankAccount gerrierAccount = new(); \ngerrierAccount.AccountName = \"Ms. Gerrier\"; \ngerrierAccount.Balance = 98;\nWriteLine(format: \"{0} earned {1:C} interest.\",\n  arg0: gerrierAccount.AccountName,\n  arg1: gerrierAccount.Balance * BankAccount.InterestRate);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the additional output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Mrs. Jones earned $28.80 interest.\nMs. Gerrier earned $1.18 interest.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Remember that <code class=\"calibre9\">C<\/code> is a format code that tells .NET to use the current culture's currency format for the decimal numbers.<\/p>\n<\/blockquote>\n<p class=\"rights\">Fields are not the only members that can be static. Constructors, methods, properties, and other members can also be static.<\/p>\n<\/section>\n<section data-number=\"6.4.11\" id=\"calibre_link-270\">\n<h3 data-number=\"6.4.11\" class=\"calibre8\">Making a field constant<\/h3>\n<p class=\"rights\">If the value of a field will never ever change, you can use the <code class=\"calibre9\">const<\/code> keyword and assign a literal value at compile time. Any statement that changes the value will cause a compile-time error. Let's see a simple example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add a <code class=\"calibre9\">string<\/code> constant for the species of a person, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\"> \/\/ Constant fields: Values that are fixed at compilation.\npublic const string Species = \"Homo Sapiens\";<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">To get the value of a constant field, you must write the name of the class, not the name of an instance of the class. In <code class=\"calibre9\">Program.cs<\/code>, add a statement to write Bob's name and species to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Constant fields are accessible via the type.\nWriteLine($\"{bob.Name} is a {Person.Species}.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Bob Smith is a Homo Sapiens.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Examples of <code class=\"calibre9\">const<\/code> fields in Microsoft types include <code class=\"calibre9\">System.Int32.MaxValue<\/code> and <code class=\"calibre9\">System.Math.PI<\/code> because neither value will ever change, as you can see in <em class=\"calibre10\">Figure 5.2<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 5.2: Examples of constants in System.Math class\" height=\"770\" src=\"\/images\/cs12\/000173.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 5.2: Examples of constants in System.Math class<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Constants are not always the best choice for two important reasons: the value must be known at compile time, and it must be expressible as a literal <code class=\"calibre9\">string<\/code>, <code class=\"calibre9\">Boolean<\/code>, or number value. Every reference to the <code class=\"calibre9\">const<\/code> field is replaced with the literal value at compile time, which will, therefore, not be reflected if the value changes in a future version and you do not recompile any assemblies that reference it to get the new value.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.4.12\" id=\"calibre_link-271\">\n<h3 data-number=\"6.4.12\" class=\"calibre8\">Making a field read-only<\/h3>\n<p class=\"rights\">Often, a better choice for fields that should not change is to mark them as read-only:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add a statement to declare an instance read-only field to store a person's home planet, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Read-only fields: Values that can be set at runtime.\npublic readonly string HomePlanet = \"Earth\";<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement to write Bob's name and home planet to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Read-only fields are accessible via the variable.\nWriteLine($\"{bob.Name} was born on {bob.HomePlanet}.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Bob Smith was born on Earth.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Use read-only fields over constant fields for two important reasons: the value can be calculated or loaded at runtime and can be expressed using any executable statement. So, a read-only field can be set using a constructor or a field assignment. Every reference to the read-only field is a live reference, so any future changes will be correctly reflected by the calling code.<\/p>\n<\/blockquote>\n<p class=\"rights\">You can also declare <code class=\"calibre9\">static<\/code> <code class=\"calibre9\">readonly<\/code> fields whose values will be shared across all instances of the type.<\/p>\n<\/section>\n<section data-number=\"6.4.13\" id=\"calibre_link-272\">\n<h3 data-number=\"6.4.13\" class=\"calibre8\">Requiring fields to be set during instantiation<\/h3>\n<p class=\"rights\">C# 11 introduced the <code class=\"calibre9\">required<\/code> modifier. If you use it on a field or property, the compiler will ensure that you set the field or property to a value when you instantiate it. It requires targeting .NET 7 or later, so we need to create a new class library first:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Chapter05<\/code> solution, add a new class library project named <code class=\"calibre9\">PacktLibraryModern<\/code> that targets .NET 8. (The oldest supported version for the <code class=\"calibre9\">required<\/code> modifier is .NET 7.)<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibraryModern<\/code> project, rename <code class=\"calibre9\">Class1.cs<\/code> to <code class=\"calibre9\">Book.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify the code file contents to give the class four fields, with two set as <code class=\"calibre9\">required<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class Book\n{\n  \/\/ Needs .NET 7 or later as well as C# 11 or later.\n  public required string? Isbn;\n  public required string? Title;\n  \/\/ Works with any version of .NET.\n  public string? Author;\n  public int PageCount;\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note that all <code class=\"calibre9\">three<\/code> string properties are nullable. Setting a property or field to be <code class=\"calibre9\">required<\/code> does not mean that it cannot be <code class=\"calibre9\">null<\/code>. It just means that it must be explicitly set to <code class=\"calibre9\">null<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PeopleApp<\/code> console app project, add a reference to the <code class=\"calibre9\">PacktLibraryModern<\/code> class library project:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">If you use Visual Studio 2022, then in <strong class=\"calibre2\">Solution Explorer<\/strong>, select the <code class=\"calibre9\">PeopleApp<\/code> project, navigate to <strong class=\"calibre2\">Project<\/strong> | <strong class=\"calibre2\">Add Project Reference\u2026<\/strong>, check the box to select the <code class=\"calibre9\">PacktLibraryModern<\/code> project, and then click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<li class=\"calibre3\">If you use Visual Studio Code, then edit <code class=\"calibre9\">PeopleApp.csproj<\/code> to add a project reference to <code class=\"calibre9\">PacktLibraryModern<\/code>, as highlighted in the following markup:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;ProjectReference Include=\n\"..\\PacktLibraryNetStandard2\\PacktLibraryNetStandard2.csproj\" \/&gt;\n  &lt;ProjectReference Include=\n    \"..\\PacktLibraryModern\\PacktLibraryModern.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">PeopleApp<\/code> project to compile its referenced dependencies and copy the class library <code class=\"calibre9\">.dll<\/code> to the local <code class=\"calibre9\">bin<\/code> folder.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">PeopleApp<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, attempt to instantiate a <code class=\"calibre9\">Book<\/code> without setting the <code class=\"calibre9\">Isbn<\/code> and <code class=\"calibre9\">Title<\/code> fields, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Book book = new();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note that you will see a compiler error, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">C:\\cs12dotnet8\\Chapter05\\PeopleApp\\Program.cs(137,13): error CS9035: Required member 'Book.Isbn' must be set in the object initializer or attribute constructor. [C:\\cs12dotnet8\\Chapter05\\PeopleApp\\PeopleApp.csproj]\nC:\\cs12dotnet8\\Chapter05\\PeopleApp\\Program.cs(137,13): error CS9035: Required member 'Book.Title' must be set in the object initializer or attribute constructor. [C:\\cs12dotnet8\\Chapter05\\PeopleApp\\PeopleApp.csproj]\n    0 Warning(s)\n    2 Error(s)<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, modify the statement to set the two required properties using object initialization syntax, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Book book = new()\n{\n  Isbn = \"978-1803237800\",\n  Title = \"C# 12 and .NET 8 - Modern Cross-Platform Development Fundamentals\"\n};<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note that the statement now compiles without errors.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement to output information about the book, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(\"{0}: {1} written by {2} has {3:N0} pages.\",\n  book.Isbn, book.Title, book.Author, book.PageCount);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Before we run the project and view the output, let's talk about an alternative way that we could initialize fields (or properties) for a type.<\/p>\n<\/section>\n<section data-number=\"6.4.14\" id=\"calibre_link-273\">\n<h3 data-number=\"6.4.14\" class=\"calibre8\">Initializing fields with constructors<\/h3>\n<p class=\"rights\">Fields often need to be initialized at runtime. You can do this in a constructor that will be called when you make an instance of a class using the <code class=\"calibre9\">new<\/code> keyword. Constructors execute before any fields are set by the code that uses the type:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add statements after the existing read-only <code class=\"calibre9\">HomePlanet<\/code> field to define a second read-only field, and then set the <code class=\"calibre9\">Name<\/code> and <code class=\"calibre9\">Instantiated<\/code> fields in a constructor, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Read-only fields: Values that can be set at runtime.\npublic readonly string HomePlanet = \"Earth\";\npublic readonly DateTime Instantiated;\n#endregion\n#region Constructors: Called when using new to instantiate a type.\npublic Person()\n{\n  \/\/ Constructors can set default values for fields\n  \/\/ including any read-only fields like Instantiated.\n  Name = \"Unknown\"; \n  Instantiated = DateTime.Now;\n}\n#endregion<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to instantiate a new person and then output its initial field values, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Person blankPerson = new();\nWriteLine(format:\n  \"{0} of {1} was created at {2:hh:mm:ss} on a {2:dddd}.\",\n  arg0: blankPerson.Name,\n  arg1: blankPerson.HomePlanet,\n  arg2: blankPerson.Instantiated);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result from both the code about the book as well as the blank person, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">978-1803237800: Title = \"C# 12 and .NET 8 - Modern Cross-Platform Development Fundamentals written by  has 0 pages.\nUnknown of Earth was created at 11:58:12 on a Sunday<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"6.4.15\" id=\"calibre_link-274\">\n<h3 data-number=\"6.4.15\" class=\"calibre8\">Defining multiple constructors<\/h3>\n<p class=\"rights\">You can have multiple constructors in a type. This is especially useful to encourage developers to set initial values for fields:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add statements to define a second constructor that allows a developer to set initial values for the person's name and home planet, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public Person(string initialName, string homePlanet)\n{\n  Name = initialName;\n  HomePlanet = homePlanet;\n  Instantiated = DateTime.Now;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to create another person using the constructor with two parameters, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Person gunny = new(initialName: \"Gunny\", homePlanet: \"Mars\");\nWriteLine(format:\n  \"{0} of {1} was created at {2:hh:mm:ss} on a {2:dddd}.\",\n  arg0: gunny.Name,\n  arg1: gunny.HomePlanet,\n  arg2: gunny.Instantiated);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Gunny of Mars was created at 11:59:25 on a Sunday<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"6.4.16\" id=\"calibre_link-275\">\n<h3 data-number=\"6.4.16\" class=\"calibre8\">Setting required fields with a constructor<\/h3>\n<p class=\"rights\">Now let's return to the <code class=\"calibre9\">Book<\/code> class example with its <code class=\"calibre9\">required<\/code> fields:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibraryModern<\/code> project, in <code class=\"calibre9\">Book.cs<\/code>, add statements to define a pair of constructors, one that supports object initializer syntax and one to set the two required properties, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class Book\n{\n  \/\/ Constructor for use with object initializer syntax.\n  public Book() { } \/\/ For use with object initializer syntax.\n  \/\/ Constructor with parameters to set required fields.\n  public Book(string? isbn, string? title)\n  {\n    Isbn = isbn;\n    Title = title;\n  }<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the statement that instantiates a book using object initializer syntax, add a statement to instantiate a book using the constructor, and then set the non-<code class=\"calibre9\">required<\/code> properties for the book, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/* \n\/\/ Instantiate a book using object initializer syntax.\nBook book = new()\n{\n  Isbn = \"978-1803237800\",\n  Title = \"C# 12 and .NET 8 - Modern Cross-Platform Development Fundamentals\"\n};\n*\/\nBook book = new(isbn: \"978-1803237800\",\n  title: \"C# 12 and .NET 8 - Modern Cross-Platform Development Fundamentals\")\n{\n  Author = \"Mark J. Price\",\n  PageCount = 821\n};<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note that you will see a compiler error as before, because the compiler cannot automatically tell that calling the constructor will have set the two <code class=\"calibre9\">required<\/code> properties.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibraryModern<\/code> project, in <code class=\"calibre9\">Book.cs<\/code>, import the namespace to perform code analysis, and then decorate the constructor with the attribute to tell the compiler that it sets all the required properties and fields, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Diagnostics.CodeAnalysis; \/\/ To use [SetsRequiredMembers].\nnamespace Packt.Shared;\npublic class Book\n{\n  public Book() { } \/\/ For use with initialization syntax.\n  [SetsRequiredMembers]\n  public Book(string isbn, string title)<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, note the statement that calls the constructor now compiles without errors.<\/li>\n<li class=\"calibre3\">Optionally, run the <code class=\"calibre9\">PeopleApp<\/code> project to confirm it behaves as expected, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">978-1803237800: C# 12 and .NET 8 - Modern Cross-Platform Development Fundamentals written by Mark J. Price has 821 pages.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about <code class=\"calibre9\">required<\/code> fields and how to set them using a constructor at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/required\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/required<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Constructors are a special category of method. Let's look at methods in more detail.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"6.5\" id=\"calibre_link-276\">\n<h2 data-number=\"6.5\" class=\"calibre5\">Working with methods and tuples<\/h2>\n<p class=\"rights\"><strong class=\"calibre2\">Methods<\/strong> are members of a type that execute a block of statements. They are functions that belong to a type.<\/p>\n<section data-number=\"6.5.1\" id=\"calibre_link-277\">\n<h3 data-number=\"6.5.1\" class=\"calibre8\">Returning values from methods<\/h3>\n<p class=\"rights\">Methods can return a single value or nothing:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A method that performs some actions but does not return a value indicates this with the <code class=\"calibre9\">void<\/code> type before the name of the method.<\/li>\n<li class=\"calibre3\">A method that performs some actions and returns a value indicates this with the type of the return value before the name of the method.<\/li>\n<\/ul>\n<p class=\"rights\">For example, in the next task, you will create two methods:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">WriteToConsole<\/code>: This will perform an action (writing some text to the console), but it will return nothing from the method, indicated by the <code class=\"calibre9\">void<\/code> keyword.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">GetOrigin<\/code>: This will return a text value, indicated by the <code class=\"calibre9\">string<\/code> keyword.<\/li>\n<\/ul>\n<p class=\"rights\">Let's write the code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add statements to define the two methods that I described earlier, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Methods: Actions the type can perform.\npublic void WriteToConsole()\n{\n  WriteLine($\"{Name} was born on a {Born:dddd}.\");\n}\npublic string GetOrigin()\n{\n  return $\"{Name} was born on {HomePlanet}.\";\n}\n#endregion<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to call the two methods, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">bob.WriteToConsole(); \nWriteLine(bob.GetOrigin());<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Bob Smith was born on a Wednesday.\nBob Smith was born on Earth.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"6.5.2\" id=\"calibre_link-278\">\n<h3 data-number=\"6.5.2\" class=\"calibre8\">Defining and passing parameters to methods<\/h3>\n<p class=\"rights\">Methods can have parameters passed to them to change their behavior. Parameters are defined a bit like variable declarations but inside the parentheses of the method declaration, as you saw earlier in this chapter with constructors. Let's see more examples:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add statements to define two methods, the first without parameters and the second with one parameter, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public string SayHello()\n{\n  return $\"{Name} says 'Hello!'\";\n}\npublic string SayHelloTo(string name)\n{\n  return $\"{Name} says 'Hello, {name}!'\";\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to call the two methods, and write the return value to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(bob.SayHello()); \nWriteLine(bob.SayHelloTo(\"Emily\"));<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Bob Smith says 'Hello!'\nBob Smith says 'Hello, Emily!'<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When typing a statement that calls a method, IntelliSense shows a tooltip with the name, the type of any parameters, and the return type of the method.<\/p>\n<\/section>\n<section data-number=\"6.5.3\" id=\"calibre_link-279\">\n<h3 data-number=\"6.5.3\" class=\"calibre8\">Overloading methods<\/h3>\n<p class=\"rights\">Instead of having two different method names, we could give both methods the same name. This is allowed because the methods each have a different signature.A <strong class=\"calibre2\">method signature<\/strong> is a list of parameter types that can be passed when calling the method. Overloaded methods must differ in their list of parameters types. Two overloaded methods cannot have the same list of parameters types and differ only in their return types. Let's code an example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, change the name of the <code class=\"calibre9\">SayHelloTo<\/code> method to <code class=\"calibre9\">SayHello<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, change the method call to use the <code class=\"calibre9\">SayHello<\/code> method, and note that the quick info for the method tells you that it has an additional overload, <strong class=\"calibre2\">1 of 2<\/strong>, as well as <strong class=\"calibre2\">2 of 2<\/strong>, in Visual Studio 2022, although other code editors may be different, as shown in <em class=\"calibre10\">Figure 5.3<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 5.3: An IntelliSense tooltip for an overloaded method\" height=\"595\" src=\"\/images\/cs12\/000011.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 5.3: An IntelliSense tooltip for an overloaded method<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Use overloaded methods to simplify your class by making it appear to have fewer methods.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.5.4\" id=\"calibre_link-280\">\n<h3 data-number=\"6.5.4\" class=\"calibre8\">Passing optional parameters<\/h3>\n<p class=\"rights\">Another way to simplify methods is to make parameters optional. You make a parameter optional by assigning a default value inside the method parameter list. Optional parameters must always come last in the list of parameters.We will now create a method with three optional parameters:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add statements to define the method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public string OptionalParameters(string command  = \"Run!\",\n  double number = 0.0, bool active = true)\n{\n  return string.Format(\n    format: \"command is {0}, number is {1}, active is {2}\",\n    arg0: command,\n    arg1: number,\n    arg2: active);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement to call the method and write its return value to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(bob.OptionalParameters());<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Watch IntelliSense appear as you type the code. You will see a tooltip showing the three optional parameters with their default values.<\/li>\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">command is Run!, number is 0, active is True<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement to pass a <code class=\"calibre9\">string<\/code> value for the <code class=\"calibre9\">command<\/code> parameter and a <code class=\"calibre9\">double<\/code> value for the <code class=\"calibre9\">number<\/code> parameter, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(bob.OptionalParameters(\"Jump!\", 98.5));<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and see the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">command is Jump!, number is 98.5, active is True<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The default values for the <code class=\"calibre9\">command<\/code> and <code class=\"calibre9\">number<\/code> parameters have been replaced, but the default for <code class=\"calibre9\">active<\/code> is still <code class=\"calibre9\">true<\/code>.<\/p>\n<\/section>\n<section data-number=\"6.5.5\" id=\"calibre_link-281\">\n<h3 data-number=\"6.5.5\" class=\"calibre8\">Naming parameter values when calling methods<\/h3>\n<p class=\"rights\">Optional parameters are often combined with naming parameters when you call the method, because naming a parameter allows the values to be passed in a different order than how they were declared:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement to pass a <code class=\"calibre9\">string<\/code> value for the <code class=\"calibre9\">command<\/code> parameter and a <code class=\"calibre9\">double<\/code> value for the <code class=\"calibre9\">number<\/code> parameter, but using named parameters, so that the order they are passed through can be swapped around, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(bob.OptionalParameters(number: 52.7, command: \"Hide!\"));<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">command is Hide!, number is 52.7, active is True<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You can even use named parameters to skip over optional parameters.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement to pass a <code class=\"calibre9\">string<\/code> value for the <code class=\"calibre9\">command<\/code> parameter using positional order, skip the <code class=\"calibre9\">number<\/code> parameter, and use the named <code class=\"calibre9\">active<\/code> parameter, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(bob.OptionalParameters(\"Poke!\", active: false));<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">command is Poke!, number is 0, active is False<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Although you can mix named and positional parameter values, most developers prefer to read code that uses one or the other within the same method call.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.5.6\" id=\"calibre_link-282\">\n<h3 data-number=\"6.5.6\" class=\"calibre8\">Mixing optional and required parameters<\/h3>\n<p class=\"rights\">At the moment, all the parameters in the <code class=\"calibre9\">OptionalParameters<\/code> method are optional. What if one of them is required?<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add a fourth parameter without a default value to the <code class=\"calibre9\">OptionalParameters<\/code> method, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public string OptionalParameters(string command = \"Run!\",\n  double number = 0.0, bool active = true, int count)<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the project and note the compiler error: <code class=\"calibre9\">Error CS1737 Optional parameters must appear after all required parameters<\/code>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">OptionalParameters<\/code> method, move the <code class=\"calibre9\">count<\/code> parameter before the optional parameters, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public string OptionalParameters(int count, \n  string command = \"Run!\",\n  double number = 0.0, bool active = true)<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, modify all the calls to the <code class=\"calibre9\">OptionalParameters<\/code> method to pass an <code class=\"calibre9\">int<\/code> value as the first argument, for example, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(bob.OptionalParameters(3));\nWriteLine(bob.OptionalParameters(3, \"Jump!\", 98.5));\nWriteLine(bob.OptionalParameters(3, number: 52.7, command: \"Hide!\"));\nWriteLine(bob.OptionalParameters(3, \"Poke!\", active: false));<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Remember that if you name the arguments, then you can change their positions, for example: <code class=\"calibre9\">bob.OptionalParameters(number: 52.7, command: \"Hide!\", count: 3)<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">As you call the <code class=\"calibre9\">OptionalParameters<\/code> method, note the tooltip that shows the one required, three optional parameters, and their default values in Visual Studio 2022, as shown in <em class=\"calibre10\">Figure 5.4<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 5.4: IntelliSense showing the required and optional parameters as you type code\" height=\"595\" src=\"\/images\/cs12\/000028.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 5.4: IntelliSense showing the required and optional parameters as you type code<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"6.5.7\" id=\"calibre_link-283\">\n<h3 data-number=\"6.5.7\" class=\"calibre8\">Controlling how parameters are passed<\/h3>\n<p class=\"rights\">When a parameter is passed into a method, it can be passed in one of several ways:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">By <strong class=\"calibre2\">value<\/strong> (this is the default): Think of these as being <em class=\"calibre10\">in-only<\/em>. Although the value can be changed, this only affects the parameter in the method.<\/li>\n<li class=\"calibre3\">As an <code class=\"calibre9\">out<\/code> parameter: Think of these as being <em class=\"calibre10\">out-only<\/em>. <code class=\"calibre9\">out<\/code> parameters cannot have a default value assigned in their declaration and cannot be left uninitialized. They must be set inside the method; otherwise, the compiler will give an error.<\/li>\n<li class=\"calibre3\">By <strong class=\"calibre2\">reference<\/strong> as a <code class=\"calibre9\">ref<\/code> parameter: Think of these as being <em class=\"calibre10\">in-and-out<\/em>. Like <code class=\"calibre9\">out<\/code> parameters, <code class=\"calibre9\">ref<\/code> parameters also cannot have default values, but since they can already be set outside the method, they do not need to be set inside the method.<\/li>\n<li class=\"calibre3\">As an <code class=\"calibre9\">in<\/code> parameter: Think of these as being a reference parameter that is <em class=\"calibre10\">read-only<\/em>. <code class=\"calibre9\">in<\/code> parameters cannot have their value changed and the compiler will show an error if you try.<\/li>\n<\/ul>\n<p class=\"rights\">Let's see some examples of passing parameters in and out of a method:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add statements to define a method with three parameters, one <code class=\"calibre9\">in<\/code> parameter, one <code class=\"calibre9\">ref<\/code> parameter, and one <code class=\"calibre9\">out<\/code> parameter, as shown in the following method:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public void PassingParameters(int w, in int x, ref int y, out int z)\n{\n  \/\/ out parameters cannot have a default and they\n  \/\/ must be initialized inside the method.\n  z = 100;\n  \/\/ Increment each parameter except the read-only x.\n  w++;\n  \/\/ x++; \/\/ Gives a compiler error!\n  y++; \n  z++;\n  WriteLine($\"In the method: w={w}, x={x}, y={y}, z={z}\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to declare some <code class=\"calibre9\">int<\/code> variables and pass them into the method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int a = 10; \nint b = 20; \nint c = 30;\nint d = 40;\nWriteLine($\"Before: a={a}, b={b}, c={c}, d={d}\"); \nbob.PassingParameters(a, b, ref c, out d);\nWriteLine($\"After: a={a}, b={b}, c={c}, d={d}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Before: a=10, b=20, c=30, d=40\nIn the method: w=11, x=20, y=31, z=101\nAfter: a=10, b=20, c=31, d=101 <\/code><\/pre>\n<\/div>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">When passing a variable as a parameter by default, its current value gets passed, not the variable itself. Therefore, <code class=\"calibre9\">w<\/code> has a copy of the value of the <code class=\"calibre9\">a<\/code> variable. The <code class=\"calibre9\">a<\/code> variable retains its original value of <code class=\"calibre9\">10<\/code> even after <code class=\"calibre9\">w<\/code> is incremented to 11.<\/li>\n<li class=\"calibre3\">When passing a variable as an <code class=\"calibre9\">in<\/code> parameter, a reference to the variable gets passed into the method. Therefore, <code class=\"calibre9\">x<\/code> is a reference to <code class=\"calibre9\">b<\/code>. If the <code class=\"calibre9\">b<\/code> variable gets incremented by some other process while the method is executing, then the <code class=\"calibre9\">x<\/code> parameter would show that.<\/li>\n<li class=\"calibre3\">When passing a variable as a <code class=\"calibre9\">ref<\/code> parameter, a reference to the variable gets passed into the method. Therefore, <code class=\"calibre9\">y<\/code> is a reference to <code class=\"calibre9\">c<\/code>. The <code class=\"calibre9\">c<\/code> variable gets incremented when the <code class=\"calibre9\">y<\/code> parameter gets incremented.<\/li>\n<li class=\"calibre3\">When passing a variable as an <code class=\"calibre9\">out<\/code> parameter, a reference to the variable gets passed into the method. Therefore, <code class=\"calibre9\">z<\/code> is a reference to <code class=\"calibre9\">d<\/code>. The value of the <code class=\"calibre9\">d<\/code> variable gets replaced by whatever code executes inside the method.<\/li>\n<\/ul>\n<p class=\"rights\">We could simplify the code in the <code class=\"calibre9\">Main<\/code> method by not assigning the value <code class=\"calibre9\">40<\/code> to the <code class=\"calibre9\">d<\/code> variable, since it will always be replaced anyway. In C# 7 and later, we can simplify code that uses the <code class=\"calibre9\">out<\/code> parameter.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to declare some more variables, including an <code class=\"calibre9\">out<\/code> parameter named <code class=\"calibre9\">f<\/code> declared inline, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int e = 50;\nint f = 60;\nint g = 70;\nWriteLine($\"Before: e={e}, f={f}, g={g}, h doesn't exist yet!\");\n\/\/ Simplified C# 7 or later syntax for the out parameter.\nbob.PassingParameters(e, f, ref g, out int h);\nWriteLine($\"After: e={e}, f={f}, g={g}, h={h}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Before: e=50, f=60, g=70, h doesn't exist yet!\nIn the method: w=51, x=60, y=71, z=101\nAfter: e=50, f=60, g=71, h=101<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"6.5.8\" id=\"calibre_link-284\">\n<h3 data-number=\"6.5.8\" class=\"calibre8\">Understanding ref returns<\/h3>\n<p class=\"rights\">In C# 7 or later, the <code class=\"calibre9\">ref<\/code> keyword is not just for passing parameters into a method; it can also be applied to the <code class=\"calibre9\">return<\/code> value. This allows an external variable to reference an internal variable and modify its value after the method call. This might be useful in advanced scenarios, for example, passing placeholders into big data structures, but it's beyond the scope of this book. If you are interested in learning more, then you can read the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/ref#reference-return-values\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/ref#reference-return-values<\/a>.Now let's return to looking at more advanced scenarios of methods that return values.<\/p>\n<\/section>\n<section data-number=\"6.5.9\" id=\"calibre_link-285\">\n<h3 data-number=\"6.5.9\" class=\"calibre8\">Combining multiple returned values using tuples<\/h3>\n<p class=\"rights\">Each method can only return a single value that has a single type. That type could be a simple type, such as <code class=\"calibre9\">string<\/code> in the previous example; a complex type, such as <code class=\"calibre9\">Person<\/code>; or a collection type, such as <code class=\"calibre9\">List&lt;Person&gt;<\/code>.Imagine that we want to define a method named <code class=\"calibre9\">GetTheData<\/code> that needs to return both a <code class=\"calibre9\">string<\/code> value and an <code class=\"calibre9\">int<\/code> value. We could define a new class named <code class=\"calibre9\">TextAndNumber<\/code> with a <code class=\"calibre9\">string<\/code> field and an <code class=\"calibre9\">int<\/code> field, and return an instance of that complex type, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class TextAndNumber\n{\n  public string Text;\n  public int Number;\n}\npublic class LifeTheUniverseAndEverything\n{\n  public TextAndNumber GetTheData()\n  {\n    return new TextAndNumber\n    {\n      Text = \"What's the meaning of life?\",\n      Number = 42\n    };\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">But defining a class just to combine two values together is unnecessary because, in modern versions of C#, we can use <strong class=\"calibre2\">tuples<\/strong>. Tuples are an efficient way to combine two or more values into a single unit. I pronounce them as <em class=\"calibre10\">tuh-ples<\/em> but I have heard other developers pronounce them as <em class=\"calibre10\">too-ples<\/em>. To-may-toe, to-mah-toe, po-tay-toe, po-tah-toe, I guess.Tuples have been a part of some languages, such as F#, since their first version, but .NET only added support for them with .NET 4 in 2010, using the <code class=\"calibre9\">System.Tuple<\/code> type.It was only with C# 7 in 2017 that C# added language syntax support for tuples using the parentheses characters <code class=\"calibre9\">()<\/code>, and at the same time, .NET added a new <code class=\"calibre9\">System.ValueTuple<\/code> type that is more efficient in some common scenarios than the old .NET 4 <code class=\"calibre9\">System.Tuple<\/code> type. The C# tuple syntax uses the more efficient one.Let's explore tuples:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add statements to define a method that returns a tuple combining a <code class=\"calibre9\">string<\/code> and <code class=\"calibre9\">int<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Method that returns a tuple: (string, int).\npublic (string, int) GetFruit()\n{\n  return (\"Apples\", 5);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to call the <code class=\"calibre9\">GetFruit<\/code> method, and then output the tuple's fields, which are automatically named <code class=\"calibre9\">Item1<\/code> and <code class=\"calibre9\">Item2<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">(string, int) fruit = bob.GetFruit();\nWriteLine($\"{fruit.Item1}, {fruit.Item2} there are.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Apples, 5 there are.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"6.5.10\" id=\"calibre_link-286\">\n<h3 data-number=\"6.5.10\" class=\"calibre8\">Naming the fields of a tuple<\/h3>\n<p class=\"rights\">To access the fields of a tuple, the default names are <code class=\"calibre9\">Item1<\/code>, <code class=\"calibre9\">Item2<\/code>, and so on.You can explicitly specify the field names:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add statements to define a method that returns a tuple with named fields, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Method that returns a tuple with named fields.\npublic (string Name, int Number) GetNamedFruit()\n{\n  return (Name: \"Apples\", Number: 5);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to call the method and output the tuple's named fields, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var fruitNamed = bob.GetNamedFruit();\nWriteLine($\"There are {fruitNamed.Number} {fruitNamed.Name}.\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">We use <code class=\"calibre9\">var<\/code> to shorten the following full syntax:<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">(string Name, int Number) fruitNamed = bob.GetNamedFruit();<\/code><\/p>\n<\/blockquote>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">There are 5 Apples.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you construct a tuple from another object, you can use a feature introduced in C# 7.1 called <strong class=\"calibre2\">tuple name inference<\/strong>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, create two tuples, each made of a <code class=\"calibre9\">string<\/code> and <code class=\"calibre9\">int<\/code> value, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var thing1 = (\"Neville\", 4);\nWriteLine($\"{thing1.Item1} has {thing1.Item2} children.\");\nvar thing2 = (bob.Name, bob.Children.Count); \nWriteLine($\"{thing2.Name} has {thing2.Count} children.\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">In C# 7, both things would use the <code class=\"calibre9\">Item1<\/code> and <code class=\"calibre9\">Item2<\/code> naming schemes. In C# 7.1 and later, <code class=\"calibre9\">thing2<\/code> can infer the names <code class=\"calibre9\">Name<\/code> and <code class=\"calibre9\">Count<\/code>.<\/p>\n<\/section>\n<section data-number=\"6.5.11\" id=\"calibre_link-287\">\n<h3 data-number=\"6.5.11\" class=\"calibre8\">Aliasing tuples<\/h3>\n<p class=\"rights\">The ability to alias a tuple was introduced in C# 12 so that you can name the type and use that as the type name when declaring variables and parameters, for example, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using UnnamedParameters = (string, int); \/\/ Aliasing a tuple type.\n\/\/ Aliasing a tuple type with parameter names.\nusing Fruit = (string Name, int Number);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When aliasing tuples use the title case naming convention for its parameters, for example, <code class=\"calibre9\">Name<\/code>, <code class=\"calibre9\">Number<\/code>, and <code class=\"calibre9\">BirthDate<\/code>.Let's see an example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, at the top of the file, define a named tuple type, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Fruit = (string Name, int Number); \/\/ Aliasing a tuple type.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, copy and paste the statement that calls the <code class=\"calibre9\">GetNamedFruit<\/code> method and change <code class=\"calibre9\">var<\/code> to <code class=\"calibre9\">Fruit<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Without an aliased tuple type.\n\/\/var fruitNamed = bob.GetNamedFruit();\n\/\/ With an aliased tuple type.\nFruit fruitNamed = bob.GetNamedFruit();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and note the result is the same.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"6.5.12\" id=\"calibre_link-288\">\n<h3 data-number=\"6.5.12\" class=\"calibre8\">Deconstructing tuples<\/h3>\n<p class=\"rights\">You can also deconstruct tuples into separate variables. The deconstructing declaration has the same syntax as named field tuples but without a named variable for the tuple, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Store return value in a tuple variable with two named fields.\n(string name, int number) namedFields = bob.GetNamedFruit();\n\/\/ You can then access the named fields.\nWriteLine($\"{namedFields.name}, {namedFields.number}\");\n\/\/ Deconstruct the return value into two separate variables.\n(string name, int number) = bob.GetNamedFruit();\n\/\/ You can then access the separate variables.\nWriteLine($\"{name}, {number}\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Deconstruction has the effect of splitting the tuple into its parts and assigning those parts to new variables. Let's see it in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to deconstruct the tuple returned from the <code class=\"calibre9\">GetFruit<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">(string fruitName, int fruitNumber) = bob.GetFruit();\nWriteLine($\"Deconstructed tuple: {fruitName}, {fruitNumber}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Deconstructed tuple: Apples, 5<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"6.5.13\" id=\"calibre_link-289\">\n<h3 data-number=\"6.5.13\" class=\"calibre8\">Deconstructing other types using tuples<\/h3>\n<p class=\"rights\">Tuples are not the only type that can be deconstructed. Any type can have special methods, named <code class=\"calibre9\">Deconstruct<\/code>, that break down an object into parts. You can have as many <code class=\"calibre9\">Deconstruct<\/code> methods as you like as long as they have different signatures. Let's implement some for the <code class=\"calibre9\">Person<\/code> class:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add two <code class=\"calibre9\">Deconstruct<\/code> methods with <code class=\"calibre9\">out<\/code> parameters defined for the parts we want to deconstruct into, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Deconstructors: Break down this object into parts.\npublic void Deconstruct(out string? name,\n  out DateTimeOffset dob)\n{\n  name = Name;\n  dob = Born;\n}\npublic void Deconstruct(out string? name, \n  out DateTimeOffset dob,\n  out WondersOfTheAncientWorld fav)\n{\n  name = Name;\n  dob = Born;\n  fav = FavoriteAncientWonder;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to deconstruct <code class=\"calibre9\">bob<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var (name1, dob1) = bob; \/\/ Implicitly calls the Deconstruct method.\nWriteLine($\"Deconstructed person: {name1}, {dob1}\");\nvar (name2, dob2, fav2) = bob;\nWriteLine($\"Deconstructed person: {name2}, {dob2}, {fav2}\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You do not explicitly call the <code class=\"calibre9\">Deconstruct<\/code> method. It is called implicitly when you assign an object to a tuple variable.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Deconstructed person: Bob Smith, 12\/22\/1965 4:28:00 PM -05:00\nDeconstructed person: Bob Smith, 12\/22\/1965 4:28:00 PM -05:00, StatueOfZeusAtOlympia<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"6.5.14\" id=\"calibre_link-290\">\n<h3 data-number=\"6.5.14\" class=\"calibre8\">Implementing functionality using local functions<\/h3>\n<p class=\"rights\">A language feature introduced in C# 7 is the ability to define a <strong class=\"calibre2\">local function<\/strong>.Local functions are the method equivalent of local variables. In other words, they are methods that are only accessible from within the containing method in which they have been defined. In other languages, they are sometimes called <strong class=\"calibre2\">nested<\/strong> or <strong class=\"calibre2\">inner functions<\/strong>.Local functions can be defined anywhere inside a method: the top, the bottom, or even somewhere in the middle!We will use a local function to implement a factorial calculation:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add statements to define a <code class=\"calibre9\">Factorial<\/code> function that uses a local function inside itself to calculate the result, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Method with a local function.\npublic static int Factorial(int number)\n{\n  if (number &lt; 0)\n  {\n    throw new ArgumentException(\n      $\"{nameof(number)} cannot be less than zero.\");\n  }\n  return localFactorial(number);\n  int localFactorial(int localNumber) \/\/ Local function.\n  {\n    if (localNumber == 0) return 1;\n    return localNumber * localFactorial(localNumber - 1);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to call the <code class=\"calibre9\">Factorial<\/code> function, and write the return value to the console, with exception handling, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Change to -1 to make the exception handling code execute.\nint number = 5;\ntry\n{\n  WriteLine($\"{number}! is {Person.Factorial(number)}\"); \n}\ncatch (Exception ex)\n{\n  WriteLine($\"{ex.GetType()} says: {ex.Message} number was {number}.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">5! is 120<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Change the number to -1 so that we can check the exception handling.<\/li>\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">System.ArgumentException says: number cannot be less than zero. number was -1.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"6.5.15\" id=\"calibre_link-291\">\n<h3 data-number=\"6.5.15\" class=\"calibre8\">Splitting classes using partial<\/h3>\n<p class=\"rights\">When working on large projects with multiple team members, or when working with especially large and complex class implementations, it is useful to be able to split the definition of a class across multiple files. You do this using the <code class=\"calibre9\">partial<\/code> keyword.Imagine that we want to add statements to the <code class=\"calibre9\">Person<\/code> class that are automatically generated by a tool, like an object-relational mapper, that reads schema information from a database. If the class is defined as <code class=\"calibre9\">partial<\/code>, then we can split the class into an autogenerated code file and a manually edited code file.Let's write some code that simulates this example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add the <code class=\"calibre9\">partial<\/code> keyword, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public partial class Person<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibraryNetStandard2<\/code> project\/folder, add a new class file named <code class=\"calibre9\">PersonAutoGen.cs<\/code>.<\/li>\n<li class=\"calibre3\">Add statements to the new file, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\n\/\/ This file simulates an auto-generated class.\npublic partial class Person\n{\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">PacktLibraryNetStandard2<\/code> project. If you see error: <code class=\"calibre9\">CS0260 Missing partial modifier on declaration of type 'Person'; another partial declaration of this type exists<\/code>, then make sure you have applied the <code class=\"calibre9\">partial<\/code> keyword to both <code class=\"calibre9\">Person<\/code> classes.<\/li>\n<\/ol>\n<p class=\"rights\">The rest of the code we write for this chapter will be written in the <code class=\"calibre9\">PersonAutoGen.cs<\/code> file.Now that you\u2019ve seen lots of examples of fields and methods, we will look at some specialized types of methods that can be used to access fields to provide control and improve the developer\u2019s experience.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"6.6\" id=\"calibre_link-292\">\n<h2 data-number=\"6.6\" class=\"calibre5\">Controlling access with properties and indexers<\/h2>\n<p class=\"rights\">Earlier, you created a method named <code class=\"calibre9\">GetOrigin<\/code> that returned a <code class=\"calibre9\">string<\/code> containing the name and origin of the person. Languages such as Java do this a lot. C# has a better way, and it is called properties.A <strong class=\"calibre2\">property<\/strong> is simply a method (or a pair of methods) that acts and looks like a field when you want to get or set a value, but it acts like a method, thereby simplifying the syntax and enabling functionality, like validation and calculation, when you set and get a value.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">A fundamental difference between a field and a property is that a field provides a memory address to data. You could pass that memory address to an external component, like a Windows API C-style function call, and it could then modify the data. A property does not provide a memory address to its data, which provides more control. All you can do is ask the property to get or set the data. The property then executes statements and can decide how to respond, including refusing the request!<\/p>\n<\/blockquote>\n<section data-number=\"6.6.1\" id=\"calibre_link-293\">\n<h3 data-number=\"6.6.1\" class=\"calibre8\">Defining read-only properties<\/h3>\n<p class=\"rights\">A <code class=\"calibre9\">readonly<\/code> property only has a <code class=\"calibre9\">get<\/code> implementation:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">PersonAutoGen.cs<\/code>, in the <code class=\"calibre9\">Person<\/code> class, add statements to define three properties:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">The first property will perform the same role as the <code class=\"calibre9\">GetOrigin<\/code> method, using the property syntax that works with all versions of C#.<\/li>\n<li class=\"calibre3\">The second property will return a greeting message, using the lambda expression body <code class=\"calibre9\">=&gt;<\/code> syntax from C# 6 and later.<\/li>\n<li class=\"calibre3\">The third property will calculate the person's age.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p class=\"rights\">Here's the code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Properties: Methods to get and\/or set data or state.\n\/\/ A readonly property defined using C# 1 to 5 syntax.\npublic string Origin\n{\n  get\n  {\n    return string.Format(\"{0} was born on {1}.\",\n      arg0: Name, arg1: HomePlanet);\n  }\n}\n\/\/ Two readonly properties defined using C# 6 or later \n\/\/ lambda expression body syntax.\npublic string Greeting =&gt; $\"{Name} says 'Hello!'\";\npublic int Age =&gt; DateTime.Today.Year - Born.Year;\n#endregion<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: This isn't the best way to calculate someone's age, but we aren't learning how to calculate an age from a date and time of birth. If you need to do that properly, then read the discussion at the following link: <a href=\"https:\/\/stackoverflow.com\/questions\/9\/how-do-i-calculate-someones-age-in-c\">https:\/\/stackoverflow.com\/questions\/9\/how-do-i-calculate-someones-age-in-c<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add the statements to get the properties, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Person sam = new()\n{\n  Name = \"Sam\",\n  Born = new(1969, 6, 25, 0, 0, 0, TimeSpan.Zero)\n};\nWriteLine(sam.Origin); \nWriteLine(sam.Greeting); \nWriteLine(sam.Age);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Sam was born on Earth \nSam says 'Hello!'\n54<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The output shows <code class=\"calibre9\">54<\/code> because I ran the console app on July 5, 2023, when Sam was 54 years old.<\/p>\n<\/section>\n<section data-number=\"6.6.2\" id=\"calibre_link-294\">\n<h3 data-number=\"6.6.2\" class=\"calibre8\">Defining settable properties<\/h3>\n<p class=\"rights\">To create a settable property, you must use the older syntax and provide a pair of methods&mdash;not just a <code class=\"calibre9\">get<\/code> part, but also a <code class=\"calibre9\">set<\/code> part:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">PersonAutoGen.cs<\/code>, add statements to define a <code class=\"calibre9\">string<\/code> property that has both a <code class=\"calibre9\">get<\/code> and <code class=\"calibre9\">set<\/code> method (also known as a <strong class=\"calibre2\">getter<\/strong> and <strong class=\"calibre2\">setter<\/strong>), as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ A read-write property defined using C# 3 auto-syntax.\npublic string? FavoriteIceCream { get; set; }<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Although you have not manually created a field to store the person's favorite ice cream, it is there, automatically created by the compiler for you.Sometimes, you need more control over what happens when a property is set. In this scenario, you must use a more detailed syntax and manually create a <code class=\"calibre9\">private<\/code> field to store the value of the property.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">PersonAutoGen.cs<\/code>, add statements to define a <code class=\"calibre9\">private<\/code> <code class=\"calibre9\">string<\/code> field, known as a <strong class=\"calibre2\">backing field<\/strong>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ A private backing field to store the property value.\nprivate string? _favoritePrimaryColor;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Although there is no formal standard to name private fields, the most common is to use camel case with an underscore as a prefix.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">PersonAutoGen.cs<\/code>, add statements to define a <code class=\"calibre9\">string<\/code> property that has both <code class=\"calibre9\">get<\/code> and <code class=\"calibre9\">set<\/code> and validation logic in the setter, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ A public property to read and write to the field.\npublic string? FavoritePrimaryColor\n{\n  get\n  {\n    return _favoritePrimaryColor;\n  }\n  set\n  {\n    switch (value?.ToLower())\n    {\n      case \"red\":\n      case \"green\":\n      case \"blue\":\n        _favoritePrimaryColor = value;\n        break;\n      default:\n        throw new ArgumentException(\n          $\"{value} is not a primary color. \" + \n          \"Choose from: red, green, blue.\");\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Avoid adding too much code to your getters and setters. This could indicate a problem with your design. Consider adding private methods that you then call in the <code class=\"calibre9\">set<\/code> and <code class=\"calibre9\">get<\/code> methods to simplify your implementations.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to set Sam's favorite ice cream and color, and then write them out, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">sam.FavoriteIceCream = \"Chocolate Fudge\";\nWriteLine($\"Sam's favorite ice-cream flavor is {sam.FavoriteIceCream}.\");\nstring color = \"Red\";\ntry\n{\n  sam.FavoritePrimaryColor = color;\n  WriteLine($\"Sam's favorite primary color is {sam.FavoritePrimaryColor}.\");\n}\ncatch (Exception ex)\n{\n  WriteLine(\"Tried to set {0} to '{1}': {2}\",\n    nameof(sam.FavoritePrimaryColor), color, ex.Message);\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The print book is limited to about 820 pages. If I added exception handling code to all code examples as we have done here, then I would probably have to remove at least one chapter from the book to make enough space. In the future, I will not explicitly tell you to add exception handling code, but get into the habit of adding it yourself when needed.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Sam's favorite ice-cream flavor is Chocolate Fudge.\nSam's favorite primary color is Red.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Try to set the color to any value other than red, green, or blue, like black.<\/li>\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Tried to set FavoritePrimaryColor to 'Black': Black is not a primary color. Choose from: red, green, blue.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Use properties instead of fields when you want to execute statements during a read or write to a field without using a method pair, like <code class=\"calibre9\">GetAge<\/code> and <code class=\"calibre9\">SetAge<\/code>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.6.3\" id=\"calibre_link-295\">\n<h3 data-number=\"6.6.3\" class=\"calibre8\">Limiting flags enum values<\/h3>\n<p class=\"rights\">Earlier in this chapter we defined a field to store a person's favorite ancient wonder. But we then made the <code class=\"calibre9\">enum<\/code> able to store combinations of values. Now let's limit the favorite to one:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, comment out the <code class=\"calibre9\">FavoriteAncientWonder<\/code> field and add a comment to note it has moved to the <code class=\"calibre9\">PersonAutoGen.cs<\/code> code file, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ This has been moved to PersonAutoGen.cs as a property.\n\/\/ public WondersOfTheAncientWorld FavoriteAncientWonder;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">PersonAutoGen.cs<\/code>, add a <code class=\"calibre9\">private<\/code> field and <code class=\"calibre9\">public<\/code> property for <code class=\"calibre9\">FavoriteAncientWonder<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private WondersOfTheAncientWorld _favoriteAncientWonder;\npublic WondersOfTheAncientWorld FavoriteAncientWonder\n{\n  get { return _favoriteAncientWonder; }\n  set\n  {\n    string wonderName = value.ToString();\n    if (wonderName.Contains(','))\n    {\n      throw new ArgumentException(\n        message: \"Favorite ancient wonder can only have a single enum value.\",\n        paramName: nameof(FavoriteAncientWonder));\n    }\n    if (!Enum.IsDefined(typeof(WondersOfTheAncientWorld), value))\n    {\n      throw new ArgumentException(\n        $\"{value} is not a member of the WondersOfTheAncientWorld enum.\",\n        paramName: nameof(FavoriteAncientWonder));\n    }\n    _favoriteAncientWonder = value;\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">We could simplify the validation by only checking if the value is defined in the original <code class=\"calibre9\">enum<\/code> because <code class=\"calibre9\">IsDefined<\/code> returns <code class=\"calibre9\">false<\/code> for multiple values and undefined values. However, I want to show a different exception for multiple values, so I will use the fact that multiple values formatted as a string would include a comma in the list of names. This also means we must check for multiple values before we check if the value is defined. A comma-separated list is how multiple <code class=\"calibre9\">enum<\/code> values are represented as a <code class=\"calibre9\">string<\/code>, but you cannot use commas to set multiple <code class=\"calibre9\">enum<\/code> values. You should use <code class=\"calibre9\">|<\/code> (the bitwise <code class=\"calibre9\">OR<\/code>).<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, in the <em class=\"calibre10\">Storing a value using an enum type<\/em> region, set Bob's favorite wonder to more than one <code class=\"calibre9\">enum<\/code> value, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">bob.FavoriteAncientWonder = \n  WondersOfTheAncientWorld.StatueOfZeusAtOlympia |\n  WondersOfTheAncientWorld.GreatPyramidOfGiza;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and note the exception, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Unhandled exception. System.ArgumentException: Favorite ancient wonder can only have a single enum value. (Parameter 'FavoriteAncientWonder')\n   at Packt.Shared.Person.set_FavoriteAncientWonder(WondersOfTheAncientWorld value) in C:\\cs12dotnet8\\Chapter05\\PacktLibraryNetStandard2\\PersonAutoGen.cs:line 67\n   at Program.&lt;Main&gt;$(String[] args) in C:\\cs12dotnet8\\Chapter05\\PeopleApp\\Program.cs:line 57<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, set Bob's favorite wonder to an invalid <code class=\"calibre9\">enum<\/code> value like 128, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">bob.FavoriteAncientWonder = (WondersOfTheAncientWorld)128;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and note the exception, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Unhandled exception. System.ArgumentException: 128 is not a member of the WondersOfTheAncientWorld enum. (Parameter 'FavoriteAncientWonder')<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, set Bob's favorite wonder back to a valid single <code class=\"calibre9\">enum<\/code> value.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"6.6.4\" id=\"calibre_link-296\">\n<h3 data-number=\"6.6.4\" class=\"calibre8\">Defining indexers<\/h3>\n<p class=\"rights\"><strong class=\"calibre2\">Indexers<\/strong> allow the calling code to use the array syntax to access a property. For example, the <code class=\"calibre9\">string<\/code> type defines an indexer so that the calling code can access individual characters in the <code class=\"calibre9\">string<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string alphabet = \"abcdefghijklmnopqrstuvwxyz\";\nchar letterF = alphabet[5]; \/\/ 0 is a, 1 is b, and so on.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You can overload indexers so that different types can be used for their parameters. For example, as well as passing an <code class=\"calibre9\">int<\/code> value, you could also pass a <code class=\"calibre9\">string<\/code> value.We will define an indexer to simplify access to the children of a person:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">PersonAutoGen.cs<\/code>, add statements to define an indexer to get and set a child using the index of the child, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Indexers: Properties that use array syntax to access them.\npublic Person this[int index]\n{\n  get\n  {\n    return Children[index]; \/\/ Pass on to the List&lt;T&gt; indexer.\n  }\n  set\n  {\n    Children[index] = value;\n  }\n}\n#endregion<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">PersonAutoGen.cs<\/code>, add statements to define an indexer to get and set a child using the name of the child, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ A read-only string indexer.\npublic Person this[string name]\n{\n  get\n  {\n    return Children.Find(p =&gt; p.Name == name);\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You will learn more about collections like <code class=\"calibre9\">List&lt;T&gt;<\/code> in <em class=\"calibre10\">Chapter 8<\/em>, <em class=\"calibre10\">Working with Common .NET Types<\/em>, and how to write lambda expressions using <code class=\"calibre9\">=&gt;<\/code> in <em class=\"calibre10\">Chapter 11<\/em>, <em class=\"calibre10\">Querying and Manipulating Data Using LINQ<\/em>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to add two children to <code class=\"calibre9\">Sam<\/code>, and then access the first and second child using the longer <code class=\"calibre9\">Children<\/code> field and the shorter indexer syntax, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">sam.Children.Add(new() { Name = \"Charlie\",\n  Born = new(2010, 3, 18, 0, 0, 0, TimeSpan.Zero) });\nsam.Children.Add(new() { Name = \"Ella\",\n  Born = new(2020, 12, 24, 0, 0, 0, TimeSpan.Zero) });\n\/\/ Get using Children list.\nWriteLine($\"Sam's first child is {sam.Children[0].Name}.\"); \nWriteLine($\"Sam's second child is {sam.Children[1].Name}.\");\n\/\/ Get using the int indexer.\nWriteLine($\"Sam's first child is {sam[0].Name}.\"); \nWriteLine($\"Sam's second child is {sam[1].Name}.\");\n\/\/ Get using the string indexer.\nWriteLine($\"Sam's child named Ella is {sam[\"Ella\"].Age} years old.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Sam's first child is Charlie.\nSam's second child is Ella.\nSam's first child is Charlie.\nSam's second child is Ella.\nSam's child named Ella is 3 years old.<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"6.7\" id=\"calibre_link-297\">\n<h2 data-number=\"6.7\" class=\"calibre5\">Pattern matching with objects<\/h2>\n<p class=\"rights\">In <em class=\"calibre10\">Chapter 3<\/em>, <em class=\"calibre10\">Controlling Flow, Converting Types, and Handling Exceptions<\/em>, you were introduced to basic pattern matching. In this section, we will explore pattern matching in more detail.<\/p>\n<section data-number=\"6.7.1\" id=\"calibre_link-298\">\n<h3 data-number=\"6.7.1\" class=\"calibre8\">Pattern-matching flight passengers<\/h3>\n<p class=\"rights\">In this example, we will define some classes that represent various types of passengers on a flight, and then we will use a switch expression with pattern matching to determine the cost of their flight:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibraryNetStandard2<\/code> project\/folder, add a new file named <code class=\"calibre9\">FlightPatterns.cs<\/code>.<\/li>\n<li class=\"calibre3\">If you use Visual Studio 2022, in <code class=\"calibre9\">FlightPatterns.cs<\/code>, delete the existing statements, including the class named <code class=\"calibre9\">FlightPatterns<\/code>, because we will define multiple classes, and none match the name of the code file.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">FlightPatterns.cs<\/code>, add statements to define three types of passenger with different properties, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ All the classes in this file will be defined in the following namespace.\nnamespace Packt.Shared;\npublic class Passenger\n{\n  public string? Name { get; set; }\n}\npublic class BusinessClassPassenger : Passenger\n{\n  public override string ToString()\n  {\n    return $\"Business Class: {Name}\";\n  }\n}\npublic class FirstClassPassenger : Passenger\n{\n  public int AirMiles { get; set; }\n  public override string ToString()\n  {\n    return $\"First Class with {AirMiles:N0} air miles: {Name}\";\n  }\n}\npublic class CoachClassPassenger : Passenger\n{\n  public double CarryOnKG { get; set; }\n  public override string ToString()\n  {\n    return $\"Coach Class with {CarryOnKG:N2} KG carry on: {Name}\";\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You will learn about overriding the <code class=\"calibre9\">ToString<\/code> method in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to define an object array containing five passengers of various types and property values, and then enumerate them, outputting the cost of their flight, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ An array containing a mix of passenger types.\nPassenger[] passengers = {\n  new FirstClassPassenger { AirMiles = 1_419, Name = \"Suman\" },\n  new FirstClassPassenger { AirMiles = 16_562, Name = \"Lucy\" },\n  new BusinessClassPassenger { Name = \"Janice\" },\n  new CoachClassPassenger { CarryOnKG = 25.7, Name = \"Dave\" },\n  new CoachClassPassenger { CarryOnKG = 0, Name = \"Amit\" },\n};\nforeach (Passenger passenger in passengers)\n{\n  decimal flightCost = passenger switch\n  {\n    FirstClassPassenger p when p.AirMiles &gt; 35_000 =&gt; 1_500M, \n    FirstClassPassenger p when p.AirMiles &gt; 15_000 =&gt; 1_750M, \n    FirstClassPassenger _                         =&gt; 2_000M,\n    BusinessClassPassenger _                      =&gt; 1_000M,\n    CoachClassPassenger p when p.CarryOnKG &lt; 10.0 =&gt; 500M, \n    CoachClassPassenger _                         =&gt; 650M,\n    _                                             =&gt; 800M\n  };\n  WriteLine($\"Flight costs {flightCost:C} for {passenger}\");\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">While reviewing the preceding code, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Most code editors do not align the lambda symbols =&gt; as I have done above.<\/li>\n<li class=\"calibre3\">To pattern match on the properties of an object, you must name a local variable, like <code class=\"calibre9\">p<\/code>, which can then be used in an expression.<\/li>\n<li class=\"calibre3\">To pattern match on a type only, you can use <code class=\"calibre9\">_<\/code> to discard the local variable, for example, <code class=\"calibre9\">FirstClassPassenger _<\/code> means that you match on the type but you don't care what values any of its properties have, so a named variable like <code class=\"calibre9\">p<\/code> is not needed. In a moment, you will see how we can improve the code even more.<\/li>\n<li class=\"calibre3\">The switch expression also uses <code class=\"calibre9\">_<\/code> to represent its default branch.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Flight costs $2,000.00 for First Class with 1,419 air miles: Suman\nFlight costs $1,750.00 for First Class with 16,562 air miles: Lucy\nFlight costs $1,000.00 for Business Class: Janice\nFlight costs $650.00 for Coach Class with 25.70 KG carry on: Dave\nFlight costs $500.00 for Coach Class with 0.00 KG carry on: Amit<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"6.7.2\" id=\"calibre_link-299\">\n<h3 data-number=\"6.7.2\" class=\"calibre8\">Enhancements to pattern matching in C# 9 or later<\/h3>\n<p class=\"rights\">The previous examples worked with C# 8. Now we will look at some enhancements in C# 9 and later. First, you no longer need to use the underscore to discard the local variable when doing type matching:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the C# 8 syntax, and add C# 9 and later syntax to modify the branches for first-class passengers to use a nested switch expression and the new support for conditionals, like <code class=\"calibre9\">&gt;<\/code>, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">decimal flightCost = passenger switch\n{\n  \/* C# 8 syntax\n  FirstClassPassenger p when p.AirMiles &gt; 35_000 =&gt; 1_500M,\n  FirstClassPassenger p when p.AirMiles &gt; 15_000 =&gt; 1_750M,\n  FirstClassPassenger _                          =&gt; 2_000M, *\/\n  \/\/ C# 9 or later syntax\n  FirstClassPassenger p =&gt; p.AirMiles switch\n  {\n    &gt; 35_000 =&gt; 1_500M,\n    &gt; 15_000 =&gt; 1_750M,\n    _       =&gt; 2_000M\n  },\n  BusinessClassPassenger                        =&gt; 1_000M,\n  CoachClassPassenger p when p.CarryOnKG &lt; 10.0 =&gt; 500M,\n  CoachClassPassenger                           =&gt; 650M,\n  _                                             =&gt; 800M\n};<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project to view the results, and note that they are the same as before.<\/li>\n<\/ol>\n<p class=\"rights\">You could also use the relational pattern in combination with the property pattern to avoid the nested <code class=\"calibre9\">switch<\/code> expression, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">FirstClassPassenger { AirMiles: &gt; 35000 } =&gt; 1500,\nFirstClassPassenger { AirMiles: &gt; 15000 } =&gt; 1750M,\nFirstClassPassenger                       =&gt; 2000M,<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: There are many more ways to use pattern matching in your projects. I recommend that you review the official documentation at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/fundamentals\/functional\/pattern-matching\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/fundamentals\/functional\/pattern-matching<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"6.8\" id=\"calibre_link-300\">\n<h2 data-number=\"6.8\" class=\"calibre5\">Working with record types<\/h2>\n<p class=\"rights\">Before we dive into the new <code class=\"calibre9\">record<\/code> language feature, let us see some other related new features of C# 9 and later.<\/p>\n<section data-number=\"6.8.1\" id=\"calibre_link-301\">\n<h3 data-number=\"6.8.1\" class=\"calibre8\">Init-only properties<\/h3>\n<p class=\"rights\">You have used object initialization syntax to instantiate objects and set initial properties throughout this chapter. Those properties can also be changed after instantiation.Sometimes, you want to treat properties like <code class=\"calibre9\">readonly<\/code> fields so that they can be set during instantiation but not after. In other words, they are immutable. The <code class=\"calibre9\">init<\/code> keyword enables this. It can be used in place of the <code class=\"calibre9\">set<\/code> keyword in a property definition.Since this is a language feature not supported by .NET Standard 2.0, we cannot use it in the <code class=\"calibre9\">PacktLibraryNetStandard2<\/code> project. We must use it in the modern project:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibraryModern<\/code> project, add a new file named <code class=\"calibre9\">Records.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Records.cs<\/code>, define a person class with two immutable properties, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class ImmutablePerson\n{\n  public string? FirstName { get; init; }\n  public string? LastName { get; init; }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to instantiate a new immutable person, and then try to change one of its properties, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ImmutablePerson jeff = new() \n{\n  FirstName = \"Jeff\",\n  LastName = \"Winger\"\n};\njeff.FirstName = \"Geoff\";<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Compile the console app and note the compile error, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">C:\\cs12dotnet8\\Chapter05\\PeopleApp\\Program.cs(404,1): error CS8852: Init-only property or indexer 'ImmutablePerson.FirstName' can only be assigned in an object initializer, or on 'this' or 'base' in an instance constructor or an 'init' accessor. [\/Users\/markjprice\/Code\/Chapter05\/PeopleApp\/PeopleApp.csproj]<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Comment out the attempt to set the <code class=\"calibre9\">FirstName<\/code> property after instantiation.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Even if you do not set <code class=\"calibre9\">FirstName<\/code> in the object initializer, you still would not be able to set it post-initialization. If you need to force a property to be set, then apply the <code class=\"calibre9\">required<\/code> keyword that you learned about earlier in this chapter.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.8.2\" id=\"calibre_link-302\">\n<h3 data-number=\"6.8.2\" class=\"calibre8\">Defining record types<\/h3>\n<p class=\"rights\">Init-only properties provide some immutability to C#. You can take the concept further by using <strong class=\"calibre2\">record types<\/strong>. These are defined by using the <code class=\"calibre9\">record<\/code> keyword instead of (or as well as) the <code class=\"calibre9\">class<\/code> keyword. That can make the whole object immutable, and it acts like a value when compared. We will discuss equality and comparisons of classes, records, and value types in more detail in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>.Immutable records should not have any state (properties and fields) that change after instantiation. Instead, the idea is that you create new records from existing ones. The new record has the changed state. This is called non-destructive mutation. To do this, C# 9 introduced the <code class=\"calibre9\">with<\/code> keyword:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Records.cs<\/code>, add a record named <code class=\"calibre9\">ImmutableVehicle<\/code> after the <code class=\"calibre9\">ImmutablePerson<\/code> class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public record ImmutableVehicle\n{\n  public int Wheels { get; init; }\n  public string? Color { get; init; }\n  public string? Brand { get; init; }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to create a <code class=\"calibre9\">car<\/code> and then a mutated copy of it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ImmutableVehicle car = new() \n{\n  Brand = \"Mazda MX-5 RF\",\n  Color = \"Soul Red Crystal Metallic\",\n  Wheels = 4\n};\nImmutableVehicle repaintedCar = car \n  with { Color = \"Polymetal Grey Metallic\" }; \nWriteLine($\"Original car color was {car.Color}.\");\nWriteLine($\"New car color is {repaintedCar.Color}.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project to view the results, and note the change to the car color in the mutated copy, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Original car color was Soul Red Crystal Metallic.\nNew car color is Polymetal Grey Metallic.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You could also release the memory for the <code class=\"calibre9\">car<\/code> variable and the <code class=\"calibre9\">repaintedCar<\/code> would still fully exist.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.8.3\" id=\"calibre_link-303\">\n<h3 data-number=\"6.8.3\" class=\"calibre8\">Equality of record types<\/h3>\n<p class=\"rights\">One of the most important behaviors of <code class=\"calibre9\">record<\/code> types is their equality. Two records with the same property values are considered equal. This may not sound surprising, but if you used a normal class instead of a record, then they would <em class=\"calibre10\">not<\/em> be considered equal. Let's see:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibraryModern<\/code> project, add a new file named <code class=\"calibre9\">Equality.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Equality.cs<\/code>, define a <code class=\"calibre9\">class<\/code> and a <code class=\"calibre9\">record<\/code> type, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class AnimalClass\n{\n  public string? Name { get; set; }\n}\npublic record AnimalRecord\n{\n  public string? Name { get; set; }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to create two instances of <code class=\"calibre9\">AnimalClass<\/code> and two instances of <code class=\"calibre9\">AnimalRecord<\/code>, and then compare them for equality, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">AnimalClass ac1 = new() { Name = \"Rex\" };\nAnimalClass ac2 = new() { Name = \"Rex\" };\nWriteLine($\"ac1 == ac2: {ac1 == ac2}\");\nAnimalRecord ar1 = new() { Name = \"Rex\" };\nAnimalRecord ar2 = new() { Name = \"Rex\" };\nWriteLine($\"ar1 == ar2: {ar1 == ar2}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project to view the results, and note that two class instances are not equal even if they have the same property values, and two record instances are equal if they have the same property values, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ac1 == ac2: False\nar1 == ar2: True<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Class instances are only equal if they are literally the same object. This is true when their memory addresses are equal. You will learn more about the equality of types in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.8.4\" id=\"calibre_link-304\">\n<h3 data-number=\"6.8.4\" class=\"calibre8\">Positional data members in records<\/h3>\n<p class=\"rights\">The syntax for defining a record can be greatly simplified using positional data members. Instead of using object initialization syntax with curly braces, sometimes you might prefer to provide a constructor with positional parameters, as you saw earlier in this chapter. You can also combine this with a deconstructor to split the object into individual parts, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public record ImmutableAnimal\n{\n  public string Name { get; init; } \n  public string Species { get; init; }\n  public ImmutableAnimal(string name, string species)\n  {\n    Name = name;\n    Species = species;\n  }\n  public void Deconstruct(out string name, out string species)\n  {\n    name = Name;\n    species = Species;\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The properties, constructor, and deconstructor can be generated for you:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Records.cs<\/code>, add statements to define another record using simplified syntax, known as positional records, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Simpler syntax to define a record that auto-generates the \n\/\/ properties, constructor, and deconstructor.\npublic record ImmutableAnimal(string Name, string Species);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to construct and deconstruct immutable animals, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ImmutableAnimal oscar = new(\"Oscar\", \"Labrador\");\nvar (who, what) = oscar; \/\/ Calls the Deconstruct method.\nWriteLine($\"{who} is a {what}.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Oscar is a Labrador.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You will see records again when we look at C# 10 support to create <code class=\"calibre9\">struct<\/code> records in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: There are many more ways to use records in your projects. I recommend that you review the official documentation at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/whats-new\/tutorials\/records\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/whats-new\/tutorials\/records<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"6.8.5\" id=\"calibre_link-305\">\n<h3 data-number=\"6.8.5\" class=\"calibre8\">Defining a primary constructor for a class<\/h3>\n<p class=\"rights\">Introduced with C# 12, you can define one constructor as part of the class definition. This is called the primary constructor. The syntax is the same as for positional data members in records, but the behavior is slightly different.Traditionally, we separate the class definition from any constructors, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class Headset \/\/ Class definition.\n{\n  \/\/ Constructor.\n  public Headset(string manufacturer, string productName)\n  {\n    \/\/ You can reference manufacturer and productName parameters in \n    \/\/ the constructor and the rest of the class.\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">With class primary constructors, you combine both into a more succinct syntax, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class Headset(string manufacturer, string productName);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Let's see an example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibraryModern<\/code> project, add a class file named <code class=\"calibre9\">Headset.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify the code file contents to give the class two parameters for manufacturer and product name respectively, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class Headset(string manufacturer, string productName);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to instantiate a headset, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Headset vp = new(\"Apple\", \"Vision Pro\");\nWriteLine($\"{vp.ProductName} is made by {vp.Manufacturer}.\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">One of the differences between a <code class=\"calibre9\">record<\/code> and a <code class=\"calibre9\">class<\/code> type with a primary constructor is that its parameters don't become public properties automatically, so you will see <code class=\"calibre9\">CS1061<\/code> compiler errors. Neither <code class=\"calibre9\">ProductName<\/code> nor <code class=\"calibre9\">productName<\/code> are accessible outside the class.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Headset.cs<\/code>, modify the parameter declarations to make their first character lowercase, and then add statements to define two properties and set them using the parameters passed to the primary constructor, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class Headset(string manufacturer, string productName)\n{\n  public string Manufacturer { get; set; } = manufacturer;\n  public string ProductName { get; set; } = productName;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Vision Pro is made by Apple.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a default parameterless constructor, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class Headset(string manufacturer, string productName)\n{\n  public string Manufacturer { get; set; } = manufacturer;\n  public string ProductName { get; set; } = productName;\n  \/\/ Default parameterless constructor calls the primary constructor.\n  public Headset() : this(\"Microsoft\", \"HoloLens\") { }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, create an uninitialized instance of a headset and an instance for Meta Quest 3, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Headset holo = new();\nWriteLine($\"{holo.ProductName} is made by {holo.Manufacturer}.\");\nHeadset mq = new() { Manufacturer = \"Meta\", ProductName = \"Quest 3\" };\nWriteLine($\"{mq.ProductName} is made by {mq.Manufacturer}.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Vision Pro is made by Apple.\nHoloLens is made by Microsoft.\nQuest 3 is made by Meta.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about primary constructors for classes and structs at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/whats-new\/tutorials\/primary-constructors\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/whats-new\/tutorials\/primary-constructors<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"6.9\" id=\"calibre_link-306\">\n<h2 data-number=\"6.9\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring this chapter's topics with deeper research.<\/p>\n<section data-number=\"6.9.1\" id=\"calibre_link-307\">\n<h3 data-number=\"6.9.1\" class=\"calibre8\">Exercise 5.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the seven access modifier keywords and combinations of keywords, and what do they do?<\/li>\n<li class=\"calibre3\">What is the difference between the <code class=\"calibre9\">static<\/code>, <code class=\"calibre9\">const<\/code>, and <code class=\"calibre9\">readonly<\/code> keywords when applied to a type member?<\/li>\n<li class=\"calibre3\">What does a constructor do?<\/li>\n<li class=\"calibre3\">Why should you apply the <code class=\"calibre9\">[Flags]<\/code> attribute to an <code class=\"calibre9\">enum<\/code> type when you want to store combined values?<\/li>\n<li class=\"calibre3\">Why is the <code class=\"calibre9\">partial<\/code> keyword useful?<\/li>\n<li class=\"calibre3\">What is a tuple?<\/li>\n<li class=\"calibre3\">What does the <code class=\"calibre9\">record<\/code> keyword do?<\/li>\n<li class=\"calibre3\">What does overloading mean?<\/li>\n<li class=\"calibre3\">What is the difference between the following two statements? (Do not just say a \"&gt;\" character!)<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public List&lt;Person&gt; Children = new();\npublic List&lt;Person&gt; Children =&gt; new();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">How do you make a method parameter optional?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"6.9.2\" id=\"calibre_link-308\">\n<h3 data-number=\"6.9.2\" class=\"calibre8\">Exercise 5.2 &ndash; Practice with access modifiers<\/h3>\n<p class=\"rights\">Imagine that you are the compiler. What errors would you show when building the following projects? What would need to change to fix it?In a class library project, in <code class=\"calibre9\">Car.cs<\/code>:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">class Car\n{\n  int Wheels { get; set; }\n  public bool IsEV { get; set; }\n  internal void Start()\n  {\n    Console.WriteLine(\"Starting...\");\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">In a console app project that references the class library project, in <code class=\"calibre9\">Program.cs<\/code>:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Car fiat = new() { Wheels = 4, IsEV = true };\nfiat.Start();<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"6.9.3\" id=\"calibre_link-309\">\n<h3 data-number=\"6.9.3\" class=\"calibre8\">Exercise 5.3 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more details about the topics covered in this chapter:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-5---building-your-own-types-with-object-oriented-programming\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-5---building-your-own-types-with-object-oriented-programming<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"6.10\" id=\"calibre_link-310\">\n<h2 data-number=\"6.10\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned about:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Making your own types using OOP.<\/li>\n<li class=\"calibre3\">Some of the different categories of members that a type can have, including fields to store data and methods to perform actions.<\/li>\n<li class=\"calibre3\">OOP concepts, such as aggregation and encapsulation<\/li>\n<li class=\"calibre3\">How to use modern C# features, like relational and property pattern matching enhancements, <code class=\"calibre9\">init<\/code>-only properties, and record types.<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will take these concepts further by defining operators, delegates, and events, implementing interfaces, and inheriting from existing classes.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-940\">\n<div id=\"calibre_link-1932\" class=\"calibre1\">\n<section data-number=\"7\" id=\"calibre_link-311\">\n<h1 data-number=\"7\" class=\"title\">6 Implementing Interfaces and Inheriting Classes<\/h1>\n<section data-number=\"7.1\" id=\"calibre_link-312\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"7.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000122.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about deriving new types from existing ones using <strong class=\"calibre2\">object-oriented programming<\/strong> (<strong class=\"calibre2\">OOP<\/strong>). You will learn how to use operators as an alternative method to implement simple functionality, and you will learn how to use generics to make your code safer and more performant. You will learn about delegates and events to exchange messages between types. You will see the differences between reference and value types. You will implement interfaces for common functionality. You will create a derived class to inherit from a base class to reuse functionality, override an inherited type member, and use polymorphism. Finally, you will learn how to create extension methods and cast between classes in an inheritance hierarchy.This chapter covers the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Setting up a class library and console application<\/li>\n<li class=\"calibre3\">Static methods and overloading operators<\/li>\n<li class=\"calibre3\">Making types safely reusable with generics<\/li>\n<li class=\"calibre3\">Raising and handling events<\/li>\n<li class=\"calibre3\">Implementing interfaces<\/li>\n<li class=\"calibre3\">Managing memory with reference and value types<\/li>\n<li class=\"calibre3\">Working with <code class=\"calibre9\">null<\/code> values<\/li>\n<li class=\"calibre3\">Inheriting from classes<\/li>\n<li class=\"calibre3\">Casting within inheritance hierarchies<\/li>\n<li class=\"calibre3\">Inheriting and extending .NET types<\/li>\n<li class=\"calibre3\">Summarizing custom type choices<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"7.2\" id=\"calibre_link-313\">\n<h2 data-number=\"7.2\" class=\"calibre5\">Setting up a class library and console application<\/h2>\n<p class=\"rights\">We will start by defining a solution with two projects, like the one created in <em class=\"calibre10\">Chapter 5<\/em>, <em class=\"calibre10\">Building Your Own Types with Object-Oriented Programming<\/em>. Even if you completed all the exercises in that chapter, follow the instructions below so that you start this chapter with fresh working projects:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to create a new project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Class Library<\/strong> \/ <code class=\"calibre9\">classlib<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">PacktLibrary<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter06<\/code><\/li>\n<li class=\"calibre3\">Framework: .NET 8.0 (Long-Term Support)<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Add a new project, as defined in the following list:<\/p>\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">PeopleApp<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter06<\/code><\/li>\n<li class=\"calibre3\">Framework: .NET 8.0 (Long-Term Support)<\/li>\n<li class=\"calibre3\">Do not use top-level statements: Cleared.<\/li>\n<li class=\"calibre3\">Enable native AOT publish: Cleared.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In this chapter, both projects target .NET 8 and, therefore, use the C# 12 compiler by default.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibrary<\/code> project, rename the file named <code class=\"calibre9\">Class1.cs<\/code> to <code class=\"calibre9\">Person.cs<\/code>.<\/li>\n<li class=\"calibre3\">In both projects, add <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> to globally and statically import the <code class=\"calibre9\">System.Console<\/code> class, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, delete any existing statements and define a <code class=\"calibre9\">Person<\/code> class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class Person\n{\n  #region Properties\n  public string? Name { get; set; }\n  public DateTimeOffset Born { get; set; }\n  public List&lt;Person&gt; Children = new();\n  #endregion\n  #region Methods\n  public void WriteToConsole() \n  {\n    WriteLine($\"{Name} was born on a {Born:dddd}.\");\n  }\n  public void WriteChildrenToConsole()\n  {\n    string term = Children.Count == 1 ? \"child\" : \"children\";\n    WriteLine($\"{Name} has {Children.Count} {term}.\");\n  }\n  #endregion\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PeopleApp<\/code> project, add a project reference to <code class=\"calibre9\">PacktLibrary<\/code>, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;ProjectReference\n    Include=\"..\\PacktLibrary\\PacktLibrary.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, write statements to create an instance of <code class=\"calibre9\">Person<\/code>, and then write information about it to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Packt.Shared;\nPerson harry = new()\n{\n  Name = \"Harry\",\n  Born = new(year: 2001, month: 3, day: 25,\n    hour: 0, minute: 0, second: 0, \n    offset: TimeSpan.Zero)\n};\nharry.WriteToConsole();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you use Visual Studio 2022, configure the startup project for the solution as the current selection.<\/li>\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Harry was born on a Sunday.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"7.3\" id=\"calibre_link-314\">\n<h2 data-number=\"7.3\" class=\"calibre5\">Static methods and overloading operators<\/h2>\n<p class=\"rights\">This section is specifically about methods that apply to two instances of the same type. It is not about the more general case of methods that apply to zero, one, or more than two instances.I wanted to think of some methods that would apply to two <code class=\"calibre9\">Person<\/code> instances that could also become operators, like <code class=\"calibre9\">+<\/code> and <code class=\"calibre9\">*<\/code>. What would adding two people together represent? What would multiplying two people represent? The obvious answers are getting married and having babies.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">We will design our methods to enable us to model the story of Lamech and his two wives and their children, as described at the following link: <a href=\"https:\/\/www.kingjamesbibleonline.org\/Genesis-4-19\/\">https:\/\/www.kingjamesbibleonline.org\/Genesis-4-19\/<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">We might want two instances of <code class=\"calibre9\">Person<\/code> to be able to marry and procreate. We can implement this by writing methods and overriding operators. Instance methods are actions that an object does to itself; static methods are actions the type does.Which you choose depends on what makes the most sense for the action.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Having both static and instance methods to perform similar actions often makes sense. For example, <code class=\"calibre9\">string<\/code> has both a <code class=\"calibre9\">Compare<\/code> static method and a <code class=\"calibre9\">CompareTo<\/code> instance method. This puts the choice of how to use the functionality in the hands of the programmers using your type, giving them more flexibility.<\/p>\n<\/blockquote>\n<section data-number=\"7.3.1\" id=\"calibre_link-315\">\n<h3 data-number=\"7.3.1\" class=\"calibre8\">Implementing functionality using methods<\/h3>\n<p class=\"rights\">Let's start by implementing some functionality by using both static and instance methods:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add properties with private backing storage fields to indicate if that person is married and to whom, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Allow multiple spouses to be stored for a person.\npublic List&lt;Person&gt; Spouses = new();\n\/\/ A read-only property to show if a person is married to anyone.\npublic bool Married =&gt; Spouses.Count &gt; 0;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add one instance method and one static method that will allow two <code class=\"calibre9\">Person<\/code> objects to marry, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Static method to marry two people.\npublic static void Marry(Person p1, Person p2)\n{\n  ArgumentNullException.ThrowIfNull(p1);\n  ArgumentNullException.ThrowIfNull(p2);\n  if (p1.Spouses.Contains(p2) || p2.Spouses.Contains(p1))\n  {\n    throw new ArgumentException(\n      string.Format(\"{0} is already married to {1}.\",\n      arg0: p1.Name, arg1: p2.Name));\n  }\n  p1.Spouses.Add(p2);\n  p2.Spouses.Add(p1);\n}\n\/\/ Instance method to marry another person.\npublic void Marry(Person partner)\n{\n  Marry(this, partner); \/\/ \"this\" is the current person.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">static<\/code> method, the <code class=\"calibre9\">Person<\/code> objects are passed as parameters named <code class=\"calibre9\">p1<\/code> and <code class=\"calibre9\">p2<\/code>, and guard clauses are used to check for <code class=\"calibre9\">null<\/code> values. If either is already married to the other an exception is thrown; otherwise, they are each added to each other's list of spouses. You can model this differently if you want to allow two people to have multiple marriage ceremonies. In that case, you might choose to not throw an exception and instead do nothing. Their state of marriage would remain the same. Additional calls to <code class=\"calibre9\">Marry<\/code> would not change if they are married or not. In this scenario, I want you to see that the code recognizes that they are already married by throwing an exception.<\/li>\n<li class=\"calibre3\">In the instance method, a call is made to the <code class=\"calibre9\">static<\/code> method, passing the current person (<code class=\"calibre9\">this<\/code>) and the <code class=\"calibre9\">partner<\/code> they want to marry.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add an instance method to the <code class=\"calibre9\">Person<\/code> class that will output the spouses of a person if they are married, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public void OutputSpouses()\n{\n  if (Married)\n  {\n    string term = Spouses.Count == 1 ? \"person\" : \"people\";\n    WriteLine($\"{Name} is married to {Spouses.Count} {term}:\");\n    foreach (Person spouse in Spouses)\n    {\n      WriteLine($\"  {spouse.Name}\");\n    }\n  }\n  else\n  {\n    WriteLine($\"{Name} is a singleton.\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add one instance method and one static method to the <code class=\"calibre9\">Person<\/code> class that will allow two <code class=\"calibre9\">Person<\/code> objects to procreate if they are married to each other, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/\/ &lt;summary&gt;\n\/\/\/ Static method to \"multiply\" aka procreate and have a child together.\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=\"p1\"&gt;Parent 1&lt;\/param&gt;\n\/\/\/ &lt;param name=\"p2\"&gt;Parent 2&lt;\/param&gt;\n\/\/\/ &lt;returns&gt;A Person object that is the child of Parent 1 and Parent 2.&lt;\/returns&gt;\n\/\/\/ &lt;exception cref=\"ArgumentNullException\"&gt;If p1 or p2 are null.&lt;\/exception&gt;\n\/\/\/ &lt;exception cref=\"ArgumentException\"&gt;If p1 and p2 are not married.&lt;\/exception&gt;\npublic static Person Procreate(Person p1, Person p2)\n{\n  ArgumentNullException.ThrowIfNull(p1);\n  ArgumentNullException.ThrowIfNull(p2);\n  if (!p1.Spouses.Contains(p2) &amp;&amp; !p2.Spouses.Contains(p1))\n  {\n    throw new ArgumentException(string.Format(\n      \"{0} must be married to {1} to procreate with them.\",\n      arg0: p1.Name, arg1: p2.Name));\n  }\n  Person baby = new()\n  {\n    Name = $\"Baby of {p1.Name} and {p2.Name}\",\n    Born = DateTimeOffset.Now\n  };\n  p1.Children.Add(baby);\n  p2.Children.Add(baby);\n  return baby;\n}\n\/\/ Instance method to \"multiply\".\npublic Person ProcreateWith(Person partner)\n{\n  return Procreate(this, partner);\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">static<\/code> method named <code class=\"calibre9\">Procreate<\/code>, the <code class=\"calibre9\">Person<\/code> objects that will procreate are passed as parameters named <code class=\"calibre9\">p1<\/code> and <code class=\"calibre9\">p2<\/code>.<\/li>\n<li class=\"calibre3\">A new <code class=\"calibre9\">Person<\/code> class named <code class=\"calibre9\">baby<\/code> is created with a name composed of a combination of the two people who have procreated. This could be changed later by setting the returned <code class=\"calibre9\">baby<\/code> variable's <code class=\"calibre9\">Name<\/code> property. Although we could add a third parameter to the <code class=\"calibre9\">Procreate<\/code> method for the baby name, we will define a binary operator later, and they cannot have third parameters, so for consistency, we will just return the baby reference and let the calling code set the name of it.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">baby<\/code> object is added to the <code class=\"calibre9\">Children<\/code> collection of both parents and then returned. Classes are reference types, meaning a reference to the <code class=\"calibre9\">baby<\/code> object stored in memory is added, not a clone of the <code class=\"calibre9\">baby<\/code> object. You will learn the difference between reference types and value types later in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>.<\/li>\n<li class=\"calibre3\">In the instance method named <code class=\"calibre9\">ProcreateWith<\/code>, the <code class=\"calibre9\">Person<\/code> object to procreate with is passed as a parameter named <code class=\"calibre9\">partner<\/code>, and that, along with <code class=\"calibre9\">this<\/code>, is passed to the static <code class=\"calibre9\">Procreate<\/code> method to reuse the method implementation. <code class=\"calibre9\">this<\/code> is a keyword that references the current instance of the class. It is a convention to use a different method name for related static and instance methods, for example, <code class=\"calibre9\">Compare(x, y)<\/code> for the static method name and <code class=\"calibre9\">x.CompareTo(y)<\/code> for the instance method name.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: A method that creates a new object, or modifies an existing object, should return a reference to that object so that the caller can access the results.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, create three people and have them marry and then procreate with each other, noting that to add a double-quote character into a <code class=\"calibre9\">string<\/code>, you must prefix it with a backslash character like this, <code class=\"calibre9\">\\\"<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Implementing functionality using methods.\nPerson lamech = new() { Name = \"Lamech\" };\nPerson adah = new() { Name = \"Adah\" };\nPerson zillah = new() { Name = \"Zillah\" };\n\/\/ Call the instance method to marry Lamech and Adah.\nlamech.Marry(adah);\n\/\/ Call the static method to marry Lamech and Zillah.\nPerson.Marry(lamech, zillah);\nlamech.OutputSpouses();\nadah.OutputSpouses();\nzillah.OutputSpouses();\n\/\/ Call the instance method to make a baby.\nPerson baby1 = lamech.ProcreateWith(adah);\nbaby1.Name = \"Jabal\";\nWriteLine($\"{baby1.Name} was born on {baby1.Born}\");\n\/\/ Call the static method to make a baby.\nPerson baby2 = Person.Procreate(zillah, lamech);\nbaby2.Name = \"Tubalcain\";\nadah.WriteChildrenToConsole();\nzillah.WriteChildrenToConsole();\nlamech.WriteChildrenToConsole();\nfor (int i = 0; i &lt; lamech.Children.Count; i++)\n{\n  WriteLine(format: \"  {0}'s child #{1} is named \\\"{2}\\\".\",\n    arg0: lamech.Name, arg1: i, \n    arg2: lamech.Children[i].Name);\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">I used a <code class=\"calibre9\">for<\/code> instead of a <code class=\"calibre9\">foreach<\/code> statement so that I could use the <code class=\"calibre9\">i<\/code> variable with the indexer to access each child.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Lamech is married to 2 people:\n  Adah\n  Zillah\nAdah is married to 1 person:\n  Lamech\nZillah is married to 1 person:\n  Lamech\nJabal was born on 05\/07\/2023 15:17:03 +01:00\nAdah has 1 child.\nZillah has 1 child.\nLamech has 2 children:\n  Lamech's child #0 is named \"Jabal\".\n  Lamech's child #1 is named \"Tubalcain\".<\/code><\/pre>\n<\/div>\n<p class=\"rights\">As you have just seen, for functionality that applies to two instances of an object type, it is easy to provide both static and instance methods to implement the same functionality. Neither static nor instance methods are best in all scenarios, and you cannot predict how your type might be used. It is best to provide both to allow a developer to use your types in the way that best fits the way they need.Now let's see how we can add a third way to provide the same functionality for two instances of a type.<\/p>\n<\/section>\n<section data-number=\"7.3.2\" id=\"calibre_link-316\">\n<h3 data-number=\"7.3.2\" class=\"calibre8\">Implementing functionality using operators<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">System.String<\/code> class has a <code class=\"calibre9\">static<\/code> method named <code class=\"calibre9\">Concat<\/code> that concatenates two <code class=\"calibre9\">string<\/code> values and returns the result, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string s1 = \"Hello \"; \nstring s2 = \"World!\";\nstring s3 = string.Concat(s1, s2); \nWriteLine(s3); \/\/ Hello World!<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Calling a method like <code class=\"calibre9\">Concat<\/code> works, but it might be more natural for a programmer to use the <code class=\"calibre9\">+<\/code> symbol operator to \"add\" two <code class=\"calibre9\">string<\/code> values together, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string s3 = s1 + s2;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">A well-known biblical phrase is <em class=\"calibre10\">Go forth and multiply<\/em>, meaning to procreate. Let's write code so that the <code class=\"calibre9\">*<\/code> (multiply) symbol will allow two <code class=\"calibre9\">Person<\/code> objects to procreate. And we will use the <code class=\"calibre9\">+<\/code> operator to marry two people.We do this by defining a <code class=\"calibre9\">static<\/code> operator for the <code class=\"calibre9\">*<\/code> symbol. The syntax is rather like a method, because in effect, an operator <em class=\"calibre10\">is<\/em> a method, but it uses a symbol instead of a method name, which makes the syntax more concise:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, create a <code class=\"calibre9\">static<\/code> operator for the <code class=\"calibre9\">+<\/code> symbol, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Operators\n\/\/ Define the + operator to \"marry\".\npublic static bool operator +(Person p1, Person p2)\n{\n  Marry(p1, p2);\n  \/\/ Confirm they are both now married.\n  return p1.Married &amp;&amp; p2.Married;\n}\n#endregion<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The return type for an operator does not need to match the types passed as parameters to the operator, but the return type cannot be <code class=\"calibre9\">void<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, create a <code class=\"calibre9\">static<\/code> operator for the <code class=\"calibre9\">*<\/code> symbol, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Define the * operator to \"multiply\".\npublic static Person operator *(Person p1, Person p2)\n{\n  \/\/ Return a reference to the baby that results from multiplying.\n  return Procreate(p1, p2);\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Unlike methods, operators do not appear in IntelliSense lists for a type or a type instance when you enter a dot (<code class=\"calibre9\">.<\/code>). For every operator that you define, make a method as well, because it may not be obvious to a programmer that the operator is available. The implementation of the operator can then call the method, reusing the code you have written. A second reason to provide a method is that operators are not supported by every language compiler; for example, although arithmetic operators like <code class=\"calibre9\">*<\/code> are supported by Visual Basic and F#, there is no requirement that other languages support all operators supported by C#. You have to read the type definition or the documentation to discover if operators are implemented.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the statement that calls that static <code class=\"calibre9\">Marry<\/code> method to marry Zillah and Lamech, and replace it with an <code class=\"calibre9\">if<\/code> statement that uses the <code class=\"calibre9\">+<\/code> operator to marry them, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Person.Marry(lamech, zillah);\nif (lamech + zillah)\n{\n  WriteLine($\"{lamech.Name} and {zillah.Name} successfully got married.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, after calling the <code class=\"calibre9\">Procreate<\/code> method and before the statements that write the children to the console, use the <code class=\"calibre9\">*<\/code> operator for Lamech to make two more babies with his wives Adah and Zillah, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Use the * operator to \"multiply\".\nPerson baby3 = lamech * adah;\nbaby3.Name = \"Jubal\";\nPerson baby4 = zillah * lamech;\nbaby4.Name = \"Naamah\";<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Lamech and Zillah successfully got married.\nLamech is married to 2 people:\n  Adah\n  Zillah\nAdah is married to 1 person:\n  Lamech\nZillah is married to 1 person:\n  Lamech\nJabal was born on 05\/07\/2023 15:27:30 +01:00\nAdah has 2 children.\nZillah has 2 children.\nLamech has 4 children:\n  Lamech's child #0 is named \"Jabal\".\n  Lamech's child #1 is named \"Tubalcain\".\n  Lamech's child #2 is named \"Jubal\".\n  Lamech's child #3 is named \"Naamah\".<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: To learn more about operator overloading, you can read the documentation at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/operators\/operator-overloading\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/operators\/operator-overloading<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"7.4\" id=\"calibre_link-317\">\n<h2 data-number=\"7.4\" class=\"calibre5\">Making types safely reusable with generics<\/h2>\n<p class=\"rights\">In 2005, with C# 2 and .NET Framework 2, Microsoft introduced a feature named <strong class=\"calibre2\">generics<\/strong>, which enables your types to be more safely reusable and more efficient. It does this by allowing a programmer to pass types as parameters, like how you can pass objects as parameters.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">This topic is only about types that need to provide flexibility for the types it works with. For example, collection types need to be able to store multiple instances of any type. That flexibility can be provided either by using the <code class=\"calibre9\">System.Object<\/code> type or generics. For other scenarios that do not need type flexibility, the use of non-generic types is good practice.<\/p>\n<\/blockquote>\n<section data-number=\"7.4.1\" id=\"calibre_link-318\">\n<h3 data-number=\"7.4.1\" class=\"calibre8\">Working with non-generic types<\/h3>\n<p class=\"rights\">First, let's look at an example of working with a non-generic type so that you can understand the problems that generics are designed to solve, such as weakly typed parameters and values, and performance problems caused by using <code class=\"calibre9\">System.Object<\/code>.<code class=\"calibre9\">System.Collections.Hashtable<\/code> can be used to store multiple values, each with a unique key that can later be used to quickly look up its value. Both the key and value can be any object because they are declared as <code class=\"calibre9\">System.Object<\/code>. Although this provides flexibility, it is slow, and bugs are easier to introduce because no type checks are made when adding items.Let's write some code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, create an instance of the non-generic collection, <code class=\"calibre9\">System.Collections.Hashtable<\/code>, and then add four items to it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Non-generic lookup collection.\nSystem.Collections.Hashtable lookupObject = new();\nlookupObject.Add(key: 1, value: \"Alpha\");\nlookupObject.Add(key: 2, value: \"Beta\");\nlookupObject.Add(key: 3, value: \"Gamma\");\nlookupObject.Add(key: harry, value: \"Delta\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note that three items have a unique integer key to look them up. The last item has a <code class=\"calibre9\">Person<\/code> object as its key to look it up. This is valid in a non-generic collection.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to define a <code class=\"calibre9\">key<\/code> with the value of <code class=\"calibre9\">2<\/code> and use it to look up its value in the <em class=\"calibre10\">hash<\/em> table, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int key = 2; \/\/ Look up the value that has 2 as its key.\nWriteLine(format: \"Key {0} has value: {1}\",\n  arg0: key,\n  arg1: lookupObject[key]);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to use the <code class=\"calibre9\">harry<\/code> object to look up its value, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Look up the value that has harry as its key.\nWriteLine(format: \"Key {0} has value: {1}\",\n  arg0: harry,\n  arg1: lookupObject[harry]);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and note that it works, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Key 2 has value: Beta\nKey Packt.Shared.Person has value: Delta<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Although the code works, there is potential for mistakes because literally any type can be used for the key or value. If another developer used your <em class=\"calibre10\">lookup object<\/em> and expected all the items to be a certain type, they might cast them to that type and get exceptions because some values might be a different type. A lookup object with lots of items would also give poor performance.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Avoid types in the <code class=\"calibre9\">System.Collections<\/code> namespace. Use types in the <code class=\"calibre9\">System.Collections.Generics<\/code> and related namespaces instead. If you need to use a library that uses non-generic types, then of course you will have to use non-generic types. This is an example of what is commonly referred to as technical debt.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.4.2\" id=\"calibre_link-319\">\n<h3 data-number=\"7.4.2\" class=\"calibre8\">Working with generic types<\/h3>\n<p class=\"rights\"><code class=\"calibre9\">System.Collections.Generic.Dictionary&lt;TKey, TValue&gt;<\/code> can be used to store multiple values, each with a unique key that can later be used to quickly look up its value. Both the key and value can be any object, but you must tell the compiler what the types of the key and value will be when you first instantiate the collection. You do this by specifying types for the <strong class=\"calibre2\">generic parameters<\/strong> in angle brackets <code class=\"calibre9\">&lt;&gt;<\/code>, <code class=\"calibre9\">TKey<\/code>, and <code class=\"calibre9\">TValue<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: When a generic type has one definable type, it should be named <code class=\"calibre9\">T<\/code>, for example, <code class=\"calibre9\">List&lt;T&gt;<\/code>, where <code class=\"calibre9\">T<\/code> is the type stored in the list. When a generic type has multiple definable types, it should use <code class=\"calibre9\">T<\/code> as a name prefix and have a sensible name, for example, <code class=\"calibre9\">Dictionary&lt;TKey, TValue&gt;<\/code>.<\/p>\n<\/blockquote>\n<p class=\"rights\">This provides flexibility, is faster, and bugs are easier to avoid because type checks are made when adding items at compile time. We will not need to explicitly specify the <code class=\"calibre9\">System.Collections.Generic<\/code> namespace that contains <code class=\"calibre9\">Dictionary&lt;TKey, TValue&gt;<\/code> because it is implicitly and globally imported by default.Let's write some code to solve the problem by using generics:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, create an instance of the generic lookup collection <code class=\"calibre9\">Dictionary&lt;TKey, TValue&gt;<\/code> and then add four items to it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Define a generic lookup collection.\nDictionary&lt;int, string&gt; lookupIntString = new();\nlookupIntString.Add(key: 1, value: \"Alpha\");\nlookupIntString.Add(key: 2, value: \"Beta\");\nlookupIntString.Add(key: 3, value: \"Gamma\");\nlookupIntString.Add(key: harry, value: \"Delta\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the compile error when using <code class=\"calibre9\">harry<\/code> as a key, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/Users\/markjprice\/Code\/Chapter06\/PeopleApp\/Program.cs(98,32): error CS1503: Argument 1: cannot convert from 'Packt.Shared.Person' to 'int' [\/Users\/markjprice\/Code\/Chapter06\/PeopleApp\/PeopleApp.csproj]<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Replace <code class=\"calibre9\">harry<\/code> with <code class=\"calibre9\">4<\/code>.<\/li>\n<li class=\"calibre3\">Add statements to set the <code class=\"calibre9\">key<\/code> to <code class=\"calibre9\">3<\/code>, and use it to look up its value in the dictionary, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">key = 3;\nWriteLine(format: \"Key {0} has value: {1}\",\n  arg0: key,\n  arg1: lookupIntString[key]);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and note that it works, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Key 3 has value: Gamma<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You have now seen the difference between non-generic and generic types that need the flexibility to store any type. You know to always use generic collection types if possible. Unless you are unlucky enough to be forced to use a legacy non-generic library, you never need to write code that uses non-generic types that can store any type again.Just because it is good practice to use generic collection types in preference to non-generic collection types does not mean the more general case is also true. Non-generic non-collection types and other types that do not need the flexibility to work with any type are used all the time. Collection types just happen to be the most common type that benefits from generics.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"7.5\" id=\"calibre_link-320\">\n<h2 data-number=\"7.5\" class=\"calibre5\">Raising and handling events<\/h2>\n<p class=\"rights\">Methods are often described as <em class=\"calibre10\">actions that an object can perform, either on itself or on related objects<\/em>. For example, <code class=\"calibre9\">List&lt;T&gt;<\/code> can add an item to itself or clear itself, and <code class=\"calibre9\">File<\/code> can create or delete a file in the filesystem.Events are often described as <em class=\"calibre10\">actions that happen to an object<\/em>. For example, in a user interface, <code class=\"calibre9\">Button<\/code> has a <code class=\"calibre9\">Click<\/code> event, a click being something that happens to a button, and <code class=\"calibre9\">FileSystemWatcher<\/code> listens to the filesystem for change notifications and raises events like <code class=\"calibre9\">Created<\/code> and <code class=\"calibre9\">Deleted<\/code>, which are triggered when a directory or file changes.Another way to think of events is that they provide a way of exchanging messages between two objects.Events are built on <strong class=\"calibre2\">delegates<\/strong>, so let's start by having a look at what delegates are and how they work.<\/p>\n<section data-number=\"7.5.1\" id=\"calibre_link-321\">\n<h3 data-number=\"7.5.1\" class=\"calibre8\">Calling methods using delegates<\/h3>\n<p class=\"rights\">You have already seen the most common way to call or execute a method: using the <code class=\"calibre9\">.<\/code> operator to access the method using its name. For example, <code class=\"calibre9\">Console.WriteLine<\/code> tells the <code class=\"calibre9\">Console<\/code> type to call its <code class=\"calibre9\">WriteLine<\/code> method.The other way to call or execute a method is to use a delegate. If you have used languages that support <strong class=\"calibre2\">function pointers<\/strong>, then think of a delegate as being a <strong class=\"calibre2\">type-safe method pointer<\/strong>.In other words, a delegate contains the memory address of a method that must match the same signature as the delegate, enabling it to be called safely with the correct parameter types.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The code in this section is illustrative and not meant to be typed into a project. You will explore code like this in the next section, so for now just read the code and try to understand its meaning.<\/p>\n<\/blockquote>\n<p class=\"rights\">For example, imagine there is a method in the <code class=\"calibre9\">Person<\/code> class that must have a <code class=\"calibre9\">string<\/code> type passed as its only parameter, and it returns an <code class=\"calibre9\">int<\/code> type, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class Person\n{\n  public int MethodIWantToCall(string input)\n  {\n    return input.Length; \/\/ It doesn't matter what the method does.\n  }<\/code><\/pre>\n<\/div>\n<p class=\"rights\">I can call this method on an instance of <code class=\"calibre9\">Person<\/code> named <code class=\"calibre9\">p1<\/code> like this:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Person p1 = new();\nint answer = p1.MethodIWantToCall(\"Frog\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Alternatively, I can define a delegate with a matching signature to call the method indirectly. Note that the names of the parameters do not have to match. Only the types of parameters and return values must match, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">delegate int DelegateWithMatchingSignature(string s);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: A <code class=\"calibre9\">delegate<\/code> is a reference type like a <code class=\"calibre9\">class<\/code>, so if you define one in <code class=\"calibre9\">Program.cs<\/code> then it must be at the bottom of the file. It would be best to define it in its own class file, for example, <code class=\"calibre9\">Program.Delegates.cs<\/code>. If you define a delegate in the middle of <code class=\"calibre9\">Program.cs<\/code>, then you would see the following compiler error: <code class=\"calibre9\">CS8803: Top-level statements must precede namespace and type declarations<\/code>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Now, I can create an instance of the delegate, point it at the method, and finally, call the delegate (which calls the method), as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Create a delegate instance that points to the method.\nDelegateWithMatchingSignature d = new(p1.MethodIWantToCall);\n\/\/ Call the delegate, which then calls the method.\nint answer2 = d(\"Frog\");<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"7.5.2\" id=\"calibre_link-322\">\n<h3 data-number=\"7.5.2\" class=\"calibre8\">Examples of delegate use<\/h3>\n<p class=\"rights\">You are probably thinking, <em class=\"calibre10\">\"What's the point of that?\"<\/em> It provides flexibility. For example, we could use delegates to create a queue of methods that need to be called in order. Queuing actions that need to be performed is common in services to provide improved scalability.Another example is to allow multiple actions to execute in parallel. Delegates have built-in support for asynchronous operations that run on a different thread, which can provide improved responsiveness. The most important example is that delegates allow us to implement events to send messages between different objects that do not need to know about each other. Events are an example of loose coupling between components because they do not need to know about each other; they just need to know the event signature.<\/p>\n<\/section>\n<section data-number=\"7.5.3\" id=\"calibre_link-323\">\n<h3 data-number=\"7.5.3\" class=\"calibre8\">Status: It's complicated<\/h3>\n<p class=\"rights\">Delegates and events are two of the most confusing features of C# and can take a few attempts to understand, so don't worry if you feel lost as we walk through how they work! Move on to other topics and come back again another day when your brain has had the opportunity to process the concepts while you sleep.<\/p>\n<\/section>\n<section data-number=\"7.5.4\" id=\"calibre_link-324\">\n<h3 data-number=\"7.5.4\" class=\"calibre8\">Defining and handling delegates<\/h3>\n<p class=\"rights\">Microsoft has two predefined delegates for use as events. They both have two parameters:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">object? sender<\/code>: This parameter is a reference to the object raising the event or sending the message. The <code class=\"calibre9\">?<\/code> indicates that this reference could be <code class=\"calibre9\">null<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">EventArgs e<\/code> or <code class=\"calibre9\">TEventArgs e<\/code>: This parameter contains additional relevant information about the event. For example, in a GUI app, you might define <code class=\"calibre9\">MouseMoveEventArgs<\/code>, which has properties for the <code class=\"calibre9\">X<\/code> and <code class=\"calibre9\">Y<\/code> coordinates for the mouse pointer. A bank account might have a <code class=\"calibre9\">WithdrawEventArgs<\/code> with a property for the <code class=\"calibre9\">Amount<\/code> to withdraw.<\/li>\n<\/ul>\n<p class=\"rights\">Their signatures are simple, yet flexible, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ For methods that do not need additional argument values passed in.\npublic delegate void EventHandler(object? sender, EventArgs e);\n\/\/ For methods that need additional argument values passed in as \n\/\/ defined by the generic type TEventArgs.\npublic delegate void EventHandler&lt;TEventArgs&gt;(object? sender, TEventArgs e);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: When you want to define an event in your own type, you should use one of these two predefined delegates.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's explore delegates and events:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to the <code class=\"calibre9\">Person<\/code> class and note the following points, as shown in the following code:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">It defines an <code class=\"calibre9\">EventHandler<\/code> delegate field named <code class=\"calibre9\">Shout<\/code>.<\/li>\n<li class=\"calibre3\">It defines an <code class=\"calibre9\">int<\/code> field to store <code class=\"calibre9\">AngerLevel<\/code>.<\/li>\n<li class=\"calibre3\">It defines a method named <code class=\"calibre9\">Poke<\/code>.<\/li>\n<li class=\"calibre3\">Each time a person is poked, their <code class=\"calibre9\">AngerLevel<\/code> increments. Once their <code class=\"calibre9\">AngerLevel<\/code> reaches three, they raise the <code class=\"calibre9\">Shout<\/code> event, but only if there is at least one event delegate pointing at a method defined somewhere else in the code; that is, it is not <code class=\"calibre9\">null<\/code>:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Events\n\/\/ Delegate field to define the event.\npublic EventHandler? Shout; \/\/ null initially.\n\/\/ Data field related to the event.\npublic int AngerLevel;\n\/\/ Method to trigger the event in certain conditions.\npublic void Poke()\n{\n  AngerLevel++;\n  if (AngerLevel &lt; 3) return;\n  \n  \/\/ If something is listening to the event...\n  if (Shout is not null)\n  {\n    \/\/ ...then call the delegate to \"raise\" the event.\n    Shout(this, EventArgs.Empty);\n  }\n}\n#endregion<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Checking whether an object is not <code class=\"calibre9\">null<\/code> before calling one of its methods is very common. C# 6 and later allows <code class=\"calibre9\">null<\/code> checks to be simplified inline using a <code class=\"calibre9\">?<\/code> symbol before the <code class=\"calibre9\">.<\/code> operator, as shown in the following code:<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">Shout?.Invoke(this, EventArgs.Empty);<\/code><\/p>\n<\/blockquote>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PeopleApp<\/code> project, add a new class file named <code class=\"calibre9\">Program.EventHandlers.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.EventHandlers.cs<\/code>, delete any existing statements, and then add a method with a matching signature that gets a reference to the <code class=\"calibre9\">Person<\/code> object from the <code class=\"calibre9\">sender<\/code> parameter and outputs some information about them, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Packt.Shared; \/\/ To use Person.\n\/\/ No namespace declaration so this extends the Program class\n\/\/ in the null namespace.\npartial class Program\n{\n  \/\/ A method to handle the Shout event received by the harry object.\n  private static void Harry_Shout(object? sender, EventArgs e)\n  {\n    \/\/ If no sender, then do nothing.\n    if (sender is null) return;\n    \/\/ If sender is not a Person, then do nothing.\n    if (sender is not Person p) return;\n    WriteLine($\"{p.Name} is this angry: {p.AngerLevel}.\");\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Microsoft's convention for method names that handle events is <code class=\"calibre9\">ObjectName_EventName<\/code>. In this project, <code class=\"calibre9\">sender<\/code> will always be a <code class=\"calibre9\">Person<\/code> instance, so the <code class=\"calibre9\">null<\/code> checks are not necessary, and the event handler could be much simpler with just the <code class=\"calibre9\">WriteLine<\/code> statement. However, it is important to know that these types of <code class=\"calibre9\">null<\/code> checks make your code more robust in cases of event misuse.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement to assign the method to the delegate field, and then add statements to call the <code class=\"calibre9\">Poke<\/code> method four times, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Assign the method to the Shout delegate.\nharry.Shout = Harry_Shout;\n\/\/ Call the Poke method that eventually raises the Shout event.\nharry.Poke();\nharry.Poke();\nharry.Poke();\nharry.Poke();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, and note that Harry says nothing the first two times he is poked, and only gets angry enough to shout once he's been poked at least three times, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Harry is this angry: 3.\nHarry is this angry: 4.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"7.5.5\" id=\"calibre_link-325\">\n<h3 data-number=\"7.5.5\" class=\"calibre8\">Defining and handling events<\/h3>\n<p class=\"rights\">You've now seen how delegates implement the most important functionality of events: the ability to define a signature for a method that can be implemented by a completely different piece of code, calling that method and any others that are hooked up to the delegate field.But what about events? There is less to them than you might think.When assigning a method to a delegate field, you should not use the simple assignment operator as we did in the preceding example.Delegates are multicast, meaning that you can assign multiple delegates to a single delegate field. Instead of the <code class=\"calibre9\">=<\/code> assignment, we could have used the <code class=\"calibre9\">+=<\/code> operator so that we could add more methods to the same delegate field. When the delegate is called, all the assigned methods are called, although you have no control over the order in which they are called. Do not use events to implement a queuing system to buy concert tickets; otherwise, the wrath of millions of Swifties will fall upon you.If the <code class=\"calibre9\">Shout<\/code> delegate field already referenced one or more methods, by assigning another method, that method would replace all the others. With delegates that are used for events, we usually want to make sure that a programmer only ever uses either the <code class=\"calibre9\">+=<\/code> operator or the <code class=\"calibre9\">-=<\/code> operator to assign and remove methods:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">To enforce this, in <code class=\"calibre9\">Person.cs<\/code>, add the <code class=\"calibre9\">event<\/code> keyword to the delegate field declaration, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public event EventHandler? Shout;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">PeopleApp<\/code> project and note the compiler error message, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Program.cs(41,13): error CS0079: The event 'Person.Shout' can only appear on the left hand side of += or -=<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This is (almost) all that the <code class=\"calibre9\">event<\/code> keyword does! If you will never have more than one method assigned to a delegate field, then technically you do not need \"events,\" but it is still good practice to indicate your meaning and that you expect a delegate field to be used as an event.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, modify the comment and the method assignment to use <code class=\"calibre9\">+=<\/code> instead of just <code class=\"calibre9\">=<\/code>, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Assign the method to the Shout event delegate.\nharry.Shout += Harry_Shout;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and note that it has the same behavior as before.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.EventHandlers.cs<\/code>, create a second event handler for Harry's <code class=\"calibre9\">Shout<\/code> event, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Another method to handle the event received by the harry object.\nprivate static void Harry_Shout_2(object? sender, EventArgs e)\n{\n  WriteLine(\"Stop it!\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, after the statement that assigns the <code class=\"calibre9\">Harry_Shout<\/code> method to the <code class=\"calibre9\">Shout<\/code> event, add a statement to attach the new event handler to the <code class=\"calibre9\">Shout<\/code> event too, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Assign the method(s) to the Shout event delegate.\nharry.Shout += Harry_Shout;\nharry.Shout += Harry_Shout_2;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project, view the result, and note that both event handlers execute whenever an event is raised, which only happens once the anger level is three or more, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Harry is this angry: 3.\nStop it!\nHarry is this angry: 4.\nStop it!<\/code><\/pre>\n<\/div>\n<p class=\"rights\">That's it for events. Now let's look at interfaces.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"7.6\" id=\"calibre_link-326\">\n<h2 data-number=\"7.6\" class=\"calibre5\">Implementing interfaces<\/h2>\n<p class=\"rights\">Interfaces are a way to implement standard functionality and connect different types to make new things. Think of them like the studs on top of LEGO\u2122 bricks, which allow them to \"stick\" together, or electrical standards for plugs and sockets.If a type implements an interface, then it makes a promise to the rest of .NET that it supports specific functionality. Therefore, they are sometimes described as contracts.<\/p>\n<section data-number=\"7.6.1\" id=\"calibre_link-327\">\n<h3 data-number=\"7.6.1\" class=\"calibre8\">Common interfaces<\/h3>\n<p class=\"rights\"><em class=\"calibre10\">Table 6.1<\/em> shows some common interfaces that your types might implement:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre25\"><\/col>\n<col class=\"calibre25\"><\/col>\n<col class=\"calibre25\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Interface<\/td>\n<td class=\"calibre21\">Method(s)<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">IComparable<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">CompareTo(other)<\/code><\/td>\n<td class=\"calibre21\">This defines a comparison method that a type implements to order or sort its instances.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">IComparer<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Compare(first, second)<\/code><\/td>\n<td class=\"calibre21\">This defines a comparison method that a secondary type implements to order or sort instances of a primary type.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">IDisposable<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Dispose()<\/code><\/td>\n<td class=\"calibre21\">This defines a disposal method to release unmanaged resources more efficiently than waiting for a finalizer. See the <em class=\"calibre10\">Releasing unmanaged resources<\/em> section later in this chapter for more details.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">IFormattable<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">ToString(format, culture)<\/code><\/td>\n<td class=\"calibre21\">This defines a culture-aware method to format the value of an object into a string representation.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">IFormatter<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\"><code class=\"calibre9\">Serialize(stream, object)<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">Deserialize(stream)<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">This defines methods to convert an object to and from a stream of bytes for storage or transfer.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">IFormatProvider<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">GetFormat(type)<\/code><\/td>\n<td class=\"calibre21\">This defines a method to format inputs based on a language and region.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 6.1: Some common interfaces that your types might implement<br \/>\n<\/section>\n<section data-number=\"7.6.2\" id=\"calibre_link-328\">\n<h3 data-number=\"7.6.2\" class=\"calibre8\">Comparing objects when sorting<\/h3>\n<p class=\"rights\">One of the most common interfaces that you will want to implement in your types that represent data is <code class=\"calibre9\">IComparable<\/code>. If a type implements one of the <code class=\"calibre9\">IComparable<\/code> interfaces, then arrays and collections containing instances of that type can be sorted.This is an example of an abstraction for the concept of sorting. To sort any type, the minimum functionality would be the ability to compare two items and decide which goes before the other. If a type implements that minimum functionality, then a sorting algorithm can use it to sort instances of that type in any way the sorting algorithm wants to.The <code class=\"calibre9\">IComparable<\/code> interface has one method named <code class=\"calibre9\">CompareTo<\/code>. This has two variations, one that works with a nullable <code class=\"calibre9\">object<\/code> type and one that works with a nullable generic type <code class=\"calibre9\">T<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace System\n{\n  public interface IComparable\n  {\n    int CompareTo(object? obj);\n  }\n  public interface IComparable&lt;in T&gt;\n  {\n    int CompareTo(T? other);\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">in<\/code> keyword specifies that the type parameter <code class=\"calibre9\">T<\/code> is contravariant, which means that you can use a less derived type than that specified. For example, if <code class=\"calibre9\">Employee<\/code> derives from <code class=\"calibre9\">Person<\/code>, then both can be compared with each other.<\/p>\n<\/blockquote>\n<p class=\"rights\">For example, the <code class=\"calibre9\">string<\/code> type implements <code class=\"calibre9\">IComparable<\/code> by returning <code class=\"calibre9\">-1<\/code> if the <code class=\"calibre9\">string<\/code> should be sorted before the <code class=\"calibre9\">string<\/code> being compared to, <code class=\"calibre9\">1<\/code> if it should be sorted after, and <code class=\"calibre9\">0<\/code> if they are equal. The <code class=\"calibre9\">int<\/code> type implements <code class=\"calibre9\">IComparable<\/code> by returning <code class=\"calibre9\">-1<\/code> if the <code class=\"calibre9\">int<\/code> is less than the <code class=\"calibre9\">int<\/code> being compared to, <code class=\"calibre9\">1<\/code> if it is greater, and <code class=\"calibre9\">0<\/code> if they are equal.<code class=\"calibre9\">CompareTo<\/code> return values can be summarized as shown in <em class=\"calibre10\">Table 6.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">this before other<\/td>\n<td class=\"calibre21\">this is equal to other<\/td>\n<td class=\"calibre21\">this after other<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">-1<\/td>\n<td class=\"calibre21\">0<\/td>\n<td class=\"calibre21\">1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 6.2: Summary of the CompareTo return values<\/p>\n<p class=\"rights\">Before we implement the <code class=\"calibre9\">IComparable<\/code> interface and its <code class=\"calibre9\">CompareTo<\/code> method for the <code class=\"calibre9\">Person<\/code> class, let's see what happens when we try to sort an array of <code class=\"calibre9\">Person<\/code> instances without implementing this interface, including some that are <code class=\"calibre9\">null<\/code> or have a <code class=\"calibre9\">null<\/code> value for their <code class=\"calibre9\">Name<\/code> property:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PeopleApp<\/code> project, add a new class file named <code class=\"calibre9\">Program.Helpers.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Helpers.cs<\/code>, delete any existing statements, and then define a method for the <code class=\"calibre9\">partial<\/code> <code class=\"calibre9\">Program<\/code> class that will output all the names of a collection of people passed as a parameter, with a title beforehand, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Packt.Shared;\npartial class Program\n{\n  private static void OutputPeopleNames(\n    IEnumerable&lt;Person?&gt; people, string title)\n  {\n    WriteLine(title);\n    foreach (Person? p in people)\n    {\n      WriteLine(\"  {0}\",\n        p is null ? \"&lt;null&gt; Person\" : p.Name ?? \"&lt;null&gt; Name\");\n      \/* if p is null then output: &lt;null&gt; Person\n         else output: p.Name\n         unless p.Name is null then output: &lt;null&gt; Name *\/\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements that create an array of <code class=\"calibre9\">Person<\/code> instances, call the <code class=\"calibre9\">OutputPeopleNames<\/code> method to write the items to the console, and then attempt to sort the array and write the items to the console again, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Person?[] people =\n{\n  null,\n  new() { Name = \"Simon\" },\n  new() { Name = \"Jenny\" },\n  new() { Name = \"Adam\" },\n  new() { Name = null },\n  new() { Name = \"Richard\" }\n};\nOutputPeopleNames(people, \"Initial list of people:\"); \nArray.Sort(people);\nOutputPeopleNames(people,\n  \"After sorting using Person's IComparable implementation:\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and an exception will be thrown. As the message explains, to fix the problem, our type must implement <code class=\"calibre9\">IComparable<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Unhandled Exception: System.InvalidOperationException: Failed to compare two elements in the array. ---&gt; System.ArgumentException: At least one object must implement IComparable.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, after inheriting from <code class=\"calibre9\">object<\/code>, add a comma and enter <code class=\"calibre9\">IComparable&lt;Person?&gt;<\/code>, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class Person : IComparable&lt;Person?&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Your code editor will draw a red squiggle under the new code to warn you that you have not yet implemented the method you promised to. Your code editor can write the skeleton implementation for you.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Click on the light bulb and then click <strong class=\"calibre2\">Implement interface<\/strong>.<\/li>\n<li class=\"calibre3\">Scroll down to the bottom of the <code class=\"calibre9\">Person<\/code> class to find the method that was written for you, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public int CompareTo(Person? other)\n{\n  throw new NotImplementedException();\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Delete the statement that throws the <code class=\"calibre9\">NotImplementedException<\/code> error.<\/li>\n<li class=\"calibre3\">Add statements to handle variations of input values, including <code class=\"calibre9\">null<\/code>, and call the <code class=\"calibre9\">CompareTo<\/code> method of the <code class=\"calibre9\">Name<\/code> field, which uses the <code class=\"calibre9\">string<\/code> type's implementation of <code class=\"calibre9\">CompareTo<\/code>, and return the result, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int position;\nif (other is not null)\n{\n  if ((Name is not null) &amp;&amp; (other.Name is not null))\n  {\n    \/\/ If both Name values are not null, then\n    \/\/ use the string implementation of CompareTo.\n    position = Name.CompareTo(other.Name);\n  }\n  else if ((Name is not null) &amp;&amp; (other.Name is null))\n  {\n    position = -1; \/\/ this Person precedes other Person.\n  }\n  else if ((Name is null) &amp;&amp; (other.Name is not null))\n  {\n    position = 1; \/\/ this Person follows other Person.\n  }\n  else\n  {\n    position = 0; \/\/ this and other are at same position.\n  }\n}\nelse if (other is null)\n{\n  position = -1; \/\/ this Person precedes other Person.\n}\nelse\n{\n  position = 0; \/\/ this and other are at same position.\n}\nreturn position;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">We have chosen to compare two <code class=\"calibre9\">Person<\/code> instances by comparing their <code class=\"calibre9\">Name<\/code> fields. <code class=\"calibre9\">Person<\/code> instances will, therefore, be sorted alphabetically by their name. <code class=\"calibre9\">null<\/code> values will be sorted to the bottom of the collection. Storing the calculated <code class=\"calibre9\">position<\/code> before returning it is useful when debugging. I've also used more round brackets than the compiler needs to make the code easier for me to read. If you prefer fewer brackets, then feel free to remove them.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project, and note that this time it works as it should, sorted alphabetically by name, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Initial list of people:\n  Simon\n  &lt;null&gt; Person\n  Jenny\n  Adam\n  &lt;null&gt; Name\n  Richard\nAfter sorting using Person's IComparable implementation:\n  Adam\n  Jenny\n  Richard\n  Simon\n  &lt;null&gt; Name\n  &lt;null&gt; Person<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If you want to sort an array or collection of instances of your type, then implement the <code class=\"calibre9\">IComparable<\/code> interface.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.6.3\" id=\"calibre_link-329\">\n<h3 data-number=\"7.6.3\" class=\"calibre8\">Comparing objects using a separate class<\/h3>\n<p class=\"rights\">Sometimes, you won't have access to the source code for a type, and it might not implement the <code class=\"calibre9\">IComparable<\/code> interface. Luckily, there is another way to sort instances of a type. You can create a separate type that implements a slightly different interface, named <code class=\"calibre9\">IComparer<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibrary<\/code> project, add a new class file named <code class=\"calibre9\">PersonComparer.cs<\/code>, containing a class implementing the <code class=\"calibre9\">IComparer<\/code> interface that will compare two people, that is, two <code class=\"calibre9\">Person<\/code> instances. Implement it by comparing the length of their <code class=\"calibre9\">Name<\/code> fields, or if the names are the same length, then compare the names alphabetically, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class PersonComparer : IComparer&lt;Person?&gt;\n{\n  public int Compare(Person? x, Person? y)\n  {\n    int position;\n    if ((x is not null) &amp;&amp; (y is not null))\n    {\n      if ((x.Name is not null) &amp;&amp; (y.Name is not null))\n      {\n        \/\/ If both Name values are not null...\n        \/\/ ...then compare the Name lengths...\n        int result = x.Name.Length.CompareTo(y.Name.Length);\n        \/\/ ...and if they are equal... \n        if (result == 0)\n        {\n          \/\/ ...then compare by the Names...\n          return x.Name.CompareTo(y.Name);\n        }\n        else\n        {\n          \/\/ ...otherwise compare by the lengths.\n          position = result;\n        }\n      }\n      else if ((x.Name is not null) &amp;&amp; (y.Name is null))\n      {\n        position = -1; \/\/ x Person precedes y Person.\n      }\n      else if ((x.Name is null) &amp;&amp; (y.Name is not null))\n      {\n        position = 1; \/\/ x Person follows y Person.\n      }\n      else \/\/ x.Name and y.Name are both null.\n      {\n        position = 0; \/\/ x and y are at same position.\n      }\n    }\n    else if ((x is not null) &amp;&amp; (y is null))\n    {\n      position = -1; \/\/ x Person precedes y Person.\n    }\n    else if ((x is null) &amp;&amp; (y is not null))\n    {\n      position = 1; \/\/ x Person follows y Person.\n    }\n    else \/\/ x and y are both null.\n    {\n      position = 0; \/\/ x and y are at same position.\n    }\n    return position;\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to sort the array using an alternative implementation, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Array.Sort(people, new PersonComparer());\nOutputPeopleNames(people,\n  \"After sorting using PersonComparer's IComparer implementation:\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project, and view the result of sorting the people by the length of their names and then alphabetically, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">After sorting using PersonComparer's IComparer implementation:\n  Adam\n  Jenny\n  Simon\n  Richard\n  &lt;null&gt; Name\n  &lt;null&gt; Person<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This time, when we sort the <code class=\"calibre9\">people<\/code> array, we explicitly ask the sorting algorithm to use the <code class=\"calibre9\">PersonComparer<\/code> type instead so that the people are sorted with the shortest names first, like <code class=\"calibre9\">Adam<\/code>, and the longest names last, like <code class=\"calibre9\">Richard<\/code>, and when the lengths of two or more names are equal they are sorted alphabetically, like <code class=\"calibre9\">Jenny<\/code> and <code class=\"calibre9\">Simon<\/code>.<\/p>\n<\/section>\n<section data-number=\"7.6.4\" id=\"calibre_link-330\">\n<h3 data-number=\"7.6.4\" class=\"calibre8\">Implicit and explicit interface implementations<\/h3>\n<p class=\"rights\">Interfaces can be implemented implicitly and explicitly. Implicit implementations are simpler and more common. Explicit implementations are only necessary if a type must have multiple methods with the same name and signature. Personally, the only time I can remember ever having to explicitly implement an interface is when writing the code example for this book.For example, both <code class=\"calibre9\">IGamePlayer<\/code> and <code class=\"calibre9\">IKeyHolder<\/code> might have a method called <code class=\"calibre9\">Lose<\/code> with the same parameters because both a game and a key can be lost. The members of an interface are always and automatically <code class=\"calibre9\">public<\/code> because they have to be accessible for another type to implement them!In a type that must implement both interfaces, only one implementation of <code class=\"calibre9\">Lose<\/code> can be the implicit method. If both interfaces can share the same implementation, there is no problem, but if not, then the other <code class=\"calibre9\">Lose<\/code> method will have to be implemented differently and called explicitly, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public interface IGamePlayer\n{\n  void Lose();\n}\npublic interface IKeyHolder\n{\n  void Lose();\n}\npublic class Person : IGamePlayer, IKeyHolder\n{\n  public void Lose() \/\/ Implicit implementation.\n  {\n    \/\/ Implement losing a key.\n  }\n  public void IGamePlayer.Lose() \/\/ Explicit implementation.\n  {\n    \/\/ Implement losing a game.\n  }\n}\nPerson p = new();\np.Lose(); \/\/ Calls implicit implementation of losing a key.\n((IGamePlayer)p).Lose(); \/\/ Calls explicit implementation of losing a game.\n\/\/ Alternative way to do the same.\nIGamePlayer player = p as IGamePlayer;\nplayer.Lose(); \/\/ Calls explicit implementation of losing a game.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"7.6.5\" id=\"calibre_link-331\">\n<h3 data-number=\"7.6.5\" class=\"calibre8\">Defining interfaces with default implementations<\/h3>\n<p class=\"rights\">A language feature introduced in C# 8 is <strong class=\"calibre2\">default implementations<\/strong> for an interface. This allows an interface to contain implementation. This breaks the clean separation between interfaces that define a contract and classes and other types that implement them. It is considered by some .NET developers to be a perversion of the language.Let's see it in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibrary<\/code> project, add a new file named <code class=\"calibre9\">IPlayable.cs<\/code>, and modify the statements to define a public <code class=\"calibre9\">IPlayable<\/code> interface with two methods to <code class=\"calibre9\">Play<\/code> and <code class=\"calibre9\">Pause<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic interface IPlayable\n{\n  void Play();\n  void Pause();\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibrary<\/code> project, add a new class file named <code class=\"calibre9\">DvdPlayer.cs<\/code>, and modify the statements in the file to implement the <code class=\"calibre9\">IPlayable<\/code> interface, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class DvdPlayer : IPlayable\n{\n  public void Pause()\n  {\n    WriteLine(\"DVD player is pausing.\");\n  }\n  public void Play()\n  {\n    WriteLine(\"DVD player is playing.\");\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This is useful, but what if we decide to add a third method named <code class=\"calibre9\">Stop<\/code>? Before C# 8, this would be impossible once at least one type is implemented in the original interface. One of the main traits of an interface is that it is a fixed contract.C# 8 allows you to add new members to an interface after release if those new members have a default implementation. C# purists do not like the idea, but for practical reasons, such as avoiding breaking changes or having to define a whole new interface, it is useful, and other languages such as Java and Swift enable similar techniques.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Support for default interface implementations requires some fundamental changes to the underlying platform, so they are only supported with C# if the target framework is .NET 5 or later, .NET Core 3 or later, or .NET Standard 2.1. They are, therefore, not supported by .NET Framework.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's add a default implementation to the interface:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the <code class=\"calibre9\">IPlayable<\/code> interface to add a <code class=\"calibre9\">Stop<\/code> method with a default implementation, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic interface IPlayable\n{\n  void Play();\n  void Pause();\n  void Stop() \/\/ Default interface implementation.\n  {\n    WriteLine(\"Default implementation of Stop.\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">PeopleApp<\/code> project, and note that the projects compile successfully despite the <code class=\"calibre9\">DvdPlayer<\/code> class not implementing <code class=\"calibre9\">Stop<\/code>. In the future, we could override the default implementation of <code class=\"calibre9\">Stop<\/code> by implementing it in the <code class=\"calibre9\">DvdPlayer<\/code> class.<\/li>\n<\/ol>\n<p class=\"rights\">Although controversial, default implementations in interfaces might be useful in scenarios where the most common implementation is known at the time of defining the interface. Therefore, it is best if the interface defines that implementation once, and then most types that implement that interface can inherit it without needing to implement their own. However, if the interface definer does not know how the member should or even could be implemented, then it is a waste of effort to add a default implementation because it will always be replaced.Think about the <code class=\"calibre9\">IComparable<\/code> interface that you saw earlier in this chapter. It defines a <code class=\"calibre9\">CompareTo<\/code> method. What might a default implementation of that method be? Personally, I think it's obvious that there is no default implementation that would make any practical sense. The least-worst implementation that I can think of would be to compare the <code class=\"calibre9\">string<\/code> values returned from calling <code class=\"calibre9\">ToString<\/code> on the two objects. However, every type really should implement its own <code class=\"calibre9\">CompareTo<\/code> method. You are likely to find the same with 99.9% of the interfaces you use.Now let's look at how types are stored in a computer's memory.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"7.7\" id=\"calibre_link-332\">\n<h2 data-number=\"7.7\" class=\"calibre5\">Managing memory with reference and value types<\/h2>\n<p class=\"rights\">I mentioned <strong class=\"calibre2\">reference types<\/strong> a couple of times. Let's look at them in more detail.<\/p>\n<section data-number=\"7.7.1\" id=\"calibre_link-333\">\n<h3 data-number=\"7.7.1\" class=\"calibre8\">Understanding stack and heap memory<\/h3>\n<p class=\"rights\">There are two categories of memory: <strong class=\"calibre2\">stack<\/strong> memory and <strong class=\"calibre2\">heap<\/strong> memory. With modern operating systems, the stack and heap can be anywhere in physical or virtual memory.Stack memory is faster to work with but limited in size. It is fast because it is managed directly by the CPU and it uses a last-in, first-out mechanism, so it is more likely to have data in its L1 or L2 cache. Heap memory is slower but much more plentiful.On Windows, for ARM64, x86, and x64 machines, the default stack size is 1 MB. It is 8 MB on a typical modern Linux-based operating system. For example, in a macOS or Linux terminal, I can enter the command <code class=\"calibre9\">ulimit -a<\/code> to discover that the stack size is limited to 8,192 KB and that other memory is \"unlimited.\" This limited amount of stack memory is why it is so easy to fill it up and get a \"stack overflow.\"<\/p>\n<\/section>\n<section data-number=\"7.7.2\" id=\"calibre_link-334\">\n<h3 data-number=\"7.7.2\" class=\"calibre8\">Defining reference and value types<\/h3>\n<p class=\"rights\">There are three C# keywords that you can use to define object types: <code class=\"calibre9\">class<\/code>, <code class=\"calibre9\">record<\/code>, and <code class=\"calibre9\">struct<\/code>. All can have the same members, such as fields and methods. One difference between them is how memory is allocated:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">When you define a type using <code class=\"calibre9\">record<\/code> or <code class=\"calibre9\">class<\/code>, you define a <strong class=\"calibre2\">reference type<\/strong>. This means that the memory for the object itself is allocated on the heap, and only the memory address of the object (and a little overhead) is stored on the stack. Reference types always use a little stack memory.<\/li>\n<li class=\"calibre3\">When you define a type using <code class=\"calibre9\">record struct<\/code> or <code class=\"calibre9\">struct<\/code>, you define a <strong class=\"calibre2\">value type<\/strong>. This means that the memory for the object itself is allocated to the stack.<\/li>\n<\/ul>\n<p class=\"rights\">If a <code class=\"calibre9\">struct<\/code> uses field types that are not of the <code class=\"calibre9\">struct<\/code> type, then those fields will be stored on the heap, meaning the data for that object is stored in both the stack and the heap.These are the most common struct types:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Number <code class=\"calibre9\">System<\/code> types: <code class=\"calibre9\">byte<\/code>, <code class=\"calibre9\">sbyte<\/code>, <code class=\"calibre9\">short<\/code>, <code class=\"calibre9\">ushort<\/code>, <code class=\"calibre9\">int<\/code>, <code class=\"calibre9\">uint<\/code>, <code class=\"calibre9\">long<\/code>, <code class=\"calibre9\">ulong<\/code>, <code class=\"calibre9\">float<\/code>, <code class=\"calibre9\">double<\/code>, and <code class=\"calibre9\">decimal<\/code><\/li>\n<li class=\"calibre3\">Other <code class=\"calibre9\">System<\/code> types: <code class=\"calibre9\">char<\/code>, <code class=\"calibre9\">DateTime<\/code>, <code class=\"calibre9\">DateOnly<\/code>, <code class=\"calibre9\">TimeOnly<\/code>, and <code class=\"calibre9\">bool<\/code><\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">System.Drawing<\/code> types: <code class=\"calibre9\">Color<\/code>, <code class=\"calibre9\">Point<\/code>, <code class=\"calibre9\">PointF<\/code>, <code class=\"calibre9\">Size<\/code>, <code class=\"calibre9\">SizeF<\/code>, <code class=\"calibre9\">Rectangle<\/code>, and <code class=\"calibre9\">RectangleF<\/code><\/li>\n<\/ul>\n<p class=\"rights\">Almost all the other types are <code class=\"calibre9\">class<\/code> types, including <code class=\"calibre9\">string<\/code> aka <code class=\"calibre9\">System.String<\/code> and <code class=\"calibre9\">object<\/code> aka <code class=\"calibre9\">System.Object<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Apart from the difference in terms of where in memory the data for a type is stored, the other major differences are that you cannot inherit from a <code class=\"calibre9\">struct<\/code>, and <code class=\"calibre9\">struct<\/code> objects are compared for equality using values instead of memory addresses.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.7.3\" id=\"calibre_link-335\">\n<h3 data-number=\"7.7.3\" class=\"calibre8\">How reference and value types are stored in memory<\/h3>\n<p class=\"rights\">Imagine that you have a console app that calls some method that uses some reference and value type variables, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">void SomeMethod()\n{\n  int number1 = 49;\n  long number2 = 12;\n  System.Drawing.Point location = new(x: 4, y: 5);\n  Person kevin = new() { Name = \"Kevin\", \n    Born = new(1988, 9, 23, 0, 0, 0, TimeSpace.Zero) };\n  Person sally;\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Let's review what memory is allocated on the stack and heap when this method is executed, as shown in <em class=\"calibre10\">Figure 6.1<\/em> and as described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The <code class=\"calibre9\">number1<\/code> variable is a value type (also known as <code class=\"calibre9\">struct<\/code>), so it is allocated on the stack, and it uses 4 bytes of memory since it is a 32-bit integer. Its value, <code class=\"calibre9\">49<\/code>, is stored directly in the variable.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">number2<\/code> variable is also a value type, so it is also allocated on the stack, and it uses 8 bytes since it is a 64-bit integer.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">location<\/code> variable is also a value type, so it is allocated on the stack, and it uses 8 bytes since it is made up of two 32-bit integers, <code class=\"calibre9\">x<\/code> and <code class=\"calibre9\">y<\/code>.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">kevin<\/code> variable is a reference type (also known as <code class=\"calibre9\">class<\/code>), so 8 bytes for a 64-bit memory address (assuming a 64-bit operating system) are allocated on the stack, and enough bytes are allocated on the heap to store an instance of a <code class=\"calibre9\">Person<\/code>.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">sally<\/code> variable is a reference type, so 8 bytes for a 64-bit memory address are allocated on the stack. It is currently unassigned (<code class=\"calibre9\">null<\/code>), meaning no memory has yet been allocated for it on the heap. If we were to later assign <code class=\"calibre9\">kevin<\/code> to <code class=\"calibre9\">sally<\/code>, then the memory address of the <code class=\"calibre9\">Person<\/code> on the heap would be copied into <code class=\"calibre9\">sally<\/code>, as shown in the following code:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">sally = kevin; \/\/ Both variables point at the same Person on heap.<\/code><\/pre>\n<\/div>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 6.1: How value and reference types are allocated in the stack and heap\" height=\"1022\" src=\"\/images\/cs12\/000139.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 6.1: How value and reference types are allocated in the stack and heap<\/figcaption><\/figure>\n<p class=\"rights\">All the allocated memory for a reference type is stored on the heap except for its memory address on the stack. If a value type such as <code class=\"calibre9\">DateTimeOffset<\/code> is used for a field of a reference type like <code class=\"calibre9\">Person<\/code>, then the <code class=\"calibre9\">DateTimeOffset<\/code> value is stored on the heap, as shown in <em class=\"calibre10\">Figure 6.1<\/em>.If a value type has a field that is a reference type, then that part of the value type is stored on the heap. <code class=\"calibre9\">Point<\/code> is a value type that consists of two fields, both of which are themselves value types, so the entire object can be allocated on the stack. If the <code class=\"calibre9\">Point<\/code> value type had a field that was a reference type, like <code class=\"calibre9\">string<\/code>, then the <code class=\"calibre9\">string<\/code> bytes would be stored on the heap.When the method completes, all the stack memory is automatically released from the top of the stack. However, heap memory could still be allocated after a method returns. It is the .NET runtime garbage collector's responsibility to release this memory at a future date. Heap memory is not immediately released to improve performance. We will learn about the garbage collector later in this section.The console app might then call another method that needs some more stack memory to be allocated to it, and so on. Stack memory is literally a stack: memory is allocated at the top of the stack and removed from there when it is no longer needed.C# developers do not have control over the allocation or release of memory. Memory is automatically allocated when methods are called, and that memory is automatically released when the method returns. This is known as <strong class=\"calibre2\">verifiably safe code<\/strong>.C# developers can allocate and access raw memory using <strong class=\"calibre2\">unsafe code<\/strong>. The <code class=\"calibre9\">stackalloc<\/code> keyword is used to allocate a block of memory on the stack. Memory allocated is released automatically when the method that allocated it returns. This is an advanced feature not covered in this book. You can read about unsafe code and <code class=\"calibre9\">stackalloc<\/code> at the following links: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/unsafe-code\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/unsafe-code<\/a> and <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/operators\/stackalloc\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/operators\/stackalloc<\/a>.<\/p>\n<\/section>\n<section data-number=\"7.7.4\" id=\"calibre_link-336\">\n<h3 data-number=\"7.7.4\" class=\"calibre8\">Understanding boxing<\/h3>\n<p class=\"rights\">Boxing is nothing to do with being punched in the face, although for Unity game developers struggling to manage limited memory it can sometimes feel like it.Boxing in C# is when a value type is moved to heap memory and wrapped inside a <code class=\"calibre9\">System.Object<\/code> instance. Unboxing is when that value is moved back onto the stack. Unboxing happens explicitly. Boxing happens implicitly, so it can happen without the developer realizing. Boxing can take up to 20 times longer than without boxing.For example, an <code class=\"calibre9\">int<\/code> value can be boxed and then unboxed, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int n = 3;\nobject o = n; \/\/ Boxing happens implicitly.\nn = (int)o; \/\/ Unboxing only happens explicitly.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">A common scenario is passing value types to formatted strings, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string name = \"Hilda\";\nDateTime hired = new(2024, 2, 21);\nint days = 5;\n\/\/ hired and days are value types that will be boxed.\nConsole.WriteLine(\"{0} hired on {1} for {2} days.\", name, hired, days);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">name<\/code> variable is not boxed because <code class=\"calibre9\">string<\/code> is a reference type and is therefore already on the heap.Boxing and unboxing operations have a negative impact on performance. Although it can be useful for a .NET developer to be aware of and to avoid boxing, for most .NET project types and for many scenarios, boxing is not worth worrying too much about because the overhead is dwarfed by other factors like making a network call or updating the user interface.But for games developed for the Unity platform, its garbage collector does not release boxed values as quickly or automatically and therefore it is more critical to avoid boxing as much as possible. For this reason, JetBrains Rider with its Unity Support plugin will complain about boxing operations whenever they occur in your code. Unfortunately, it does not differentiate between Unity and other project types.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about boxing at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/types\/boxing-and-unboxing\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/types\/boxing-and-unboxing<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.7.5\" id=\"calibre_link-337\">\n<h3 data-number=\"7.7.5\" class=\"calibre8\">Equality of types<\/h3>\n<p class=\"rights\">It is common to compare two variables using the <code class=\"calibre9\">==<\/code> and <code class=\"calibre9\">!=<\/code> operators. The behavior of these two operators is different for reference types and value types.When you check the equality of two value type variables, .NET literally compares the <em class=\"calibre10\">values<\/em> of those two variables on the stack and returns <code class=\"calibre9\">true<\/code> if they are equal.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to declare two integers with equal values and then compare them, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int a = 3;\nint b = 3;\nWriteLine($\"a: {a}, b: {b}\");\nWriteLine($\"a == b: {a == b}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">a: 3, b: 3\na == b: True<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When you check the equality of two reference type variables, .NET compares the memory addresses of those two variables and returns <code class=\"calibre9\">true<\/code> if they are equal.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to declare two <code class=\"calibre9\">Person<\/code> instances with equal names, and then compare the variables and their names, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Person p1 = new() { Name = \"Kevin\" };\nPerson p2 = new() { Name = \"Kevin\" };\nWriteLine($\"p1: {p1}, p2: {p2}\");\nWriteLine($\"p1.Name: {p1.Name}, p2.Name: {p2.Name}\");\nWriteLine($\"p1 == p2: {p1 == p2}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">p1: Packt.Shared.Person, p2: Packt.Shared.Person\np1.Name: Kevin, p2.Name: Kevin\np1 == p2: False<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">This is because they are not the same object. If both variables literally pointed to the same object on the heap, then they would be equal.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to declare a third <code class=\"calibre9\">Person<\/code> object and assign <code class=\"calibre9\">p1<\/code> to it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Person p3 = p1;\nWriteLine($\"p3: {p3}\");\nWriteLine($\"p3.Name: {p3.Name}\");\nWriteLine($\"p1 == p3: {p1 == p3}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">p3: Packt.Shared.Person\np3.Name: Kevin\np1 == p3: True<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The one exception to this behavior of reference types is the <code class=\"calibre9\">string<\/code> type. It is a reference type, but the equality operators have been overridden to make them behave as if they were value types.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to compare the <code class=\"calibre9\">Name<\/code> properties of two <code class=\"calibre9\">Person<\/code> instances, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ string is the only class reference type implemented to \n\/\/ act like a value type for equality.\nWriteLine($\"p1.Name: {p1.Name}, p2.Name: {p2.Name}\");\nWriteLine($\"p1.Name == p2.Name: {p1.Name == p2.Name}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">p1.Name: Kevin, p2.Name: Kevin\np1.Name == p2.Name: True<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You can do the same as <code class=\"calibre9\">string<\/code> with your classes to override the equality operator <code class=\"calibre9\">==<\/code> to return <code class=\"calibre9\">true<\/code>, even if the two variables are not referencing the same object (the same memory address on the heap) but, instead, their fields have the same values. However, that is beyond the scope of this book.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Alternatively, use a <code class=\"calibre9\">record class<\/code> because one of its benefits is that it implements this equality behavior for you.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.7.6\" id=\"calibre_link-338\">\n<h3 data-number=\"7.7.6\" class=\"calibre8\">Defining struct types<\/h3>\n<p class=\"rights\">Let's explore defining your own value types:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibrary<\/code> project, add a file named <code class=\"calibre9\">DisplacementVector.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify the file, as shown in the following code, and note the following:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">The type is declared using <code class=\"calibre9\">struct<\/code> instead of <code class=\"calibre9\">class<\/code>.<\/li>\n<li class=\"calibre3\">It has two <code class=\"calibre9\">int<\/code> properties, named <code class=\"calibre9\">X<\/code> and <code class=\"calibre9\">Y<\/code>, that will auto-generate two private fields with the same data type, which will be allocated on the stack.<\/li>\n<li class=\"calibre3\">It has a constructor to set initial values for <code class=\"calibre9\">X<\/code> and <code class=\"calibre9\">Y<\/code>.<\/li>\n<li class=\"calibre3\">It has an operator to add two instances together that returns a new instance of the type, with <code class=\"calibre9\">X<\/code> added to <code class=\"calibre9\">X<\/code>, and <code class=\"calibre9\">Y<\/code> added to <code class=\"calibre9\">Y<\/code>:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic struct DisplacementVector\n{\n  public int X { get; set; }\n  public int Y { get; set; }\n  public DisplacementVector(int initialX, int initialY)\n  {\n    X = initialX;\n    Y = initialY;\n  }\n  public static DisplacementVector operator +(\n    DisplacementVector vector1,\n    DisplacementVector vector2)\n  {\n    return new(\n      vector1.X + vector2.X,\n      vector1.Y + vector2.Y);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to create two new instances of <code class=\"calibre9\">DisplacementVector<\/code>, add them together, and output the result, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">DisplacementVector dv1 = new(3, 5); \nDisplacementVector dv2 = new(-2, 7); \nDisplacementVector dv3 = dv1 + dv2;\nWriteLine($\"({dv1.X}, {dv1.Y}) + ({dv2.X}, {dv2.Y}) = ({dv3.X}, {dv3.Y})\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">(3, 5) + (-2, 7) = (1, 12)<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Value types always have a default constructor even if an explicit one is not defined because the values on the stack must be initialized, even if they are initialized to default values. For the two integer fields in <code class=\"calibre9\">DisplacementVector<\/code>, they will be initialized to <code class=\"calibre9\">0<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to create a new instance of <code class=\"calibre9\">DisplacementVector<\/code>, and output the object's properties, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">DisplacementVector dv4 = new();\nWriteLine($\"({dv4.X}, {dv4.Y})\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">(0, 0)<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to create a new instance of <code class=\"calibre9\">DisplacementVector<\/code>, and compare it to <code class=\"calibre9\">dv1<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">DisplacementVector dv5 = new(3, 5);\nWriteLine($\"dv1.Equals(dv5): {dv1.Equals(dv5)})\");\nWriteLine($\"dv1 == dv5: {dv1 == dv5})\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note that you cannot compare <code class=\"calibre9\">struct<\/code> variables using <code class=\"calibre9\">==<\/code>, but you can call the <code class=\"calibre9\">Equals<\/code> method, which has a default implementation that compares all fields within the <code class=\"calibre9\">struct<\/code> for equality. We could now make our <code class=\"calibre9\">struct<\/code> overload the <code class=\"calibre9\">==<\/code> operator ourselves, but an easier way is to use a feature introduced with C# 10: <code class=\"calibre9\">record<\/code> <code class=\"calibre9\">struct<\/code> types.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If the total memory used by all the fields in your type is 16 bytes or less, your type only uses value types for its fields, and you will never want to derive from your type, then Microsoft recommends that you use <code class=\"calibre9\">struct<\/code>. If your type uses more than 16 bytes of stack memory, it uses reference types for its fields, or you might want to inherit from it, then use <code class=\"calibre9\">class<\/code>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.7.7\" id=\"calibre_link-339\">\n<h3 data-number=\"7.7.7\" class=\"calibre8\">Defining record struct types<\/h3>\n<p class=\"rights\">C# 10 introduced the ability to use the <code class=\"calibre9\">record<\/code> keyword with <code class=\"calibre9\">struct<\/code> types as well as <code class=\"calibre9\">class<\/code> types. Let's see an example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">DisplacementVector<\/code> type, add the <code class=\"calibre9\">record<\/code> keyword, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public record struct DisplacementVector(int X, int Y);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, note that <code class=\"calibre9\">==<\/code> now does not have a compiler error.<\/li>\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dv1.Equals(dv5): True)\ndv1 == dv5: True)<\/code><\/pre>\n<\/div>\n<p class=\"rights\">A <code class=\"calibre9\">record<\/code> <code class=\"calibre9\">struct<\/code> has all the same benefits over a <code class=\"calibre9\">record<\/code> <code class=\"calibre9\">class<\/code> that a <code class=\"calibre9\">struct<\/code> has over a <code class=\"calibre9\">class<\/code>. One difference between <code class=\"calibre9\">record<\/code> <code class=\"calibre9\">struct<\/code> and <code class=\"calibre9\">record<\/code> <code class=\"calibre9\">class<\/code> declared using primary constructor syntax is that <code class=\"calibre9\">record<\/code> <code class=\"calibre9\">struct<\/code> is not immutable, unless you also apply the <code class=\"calibre9\">readonly<\/code> keyword to the <code class=\"calibre9\">record<\/code> <code class=\"calibre9\">struct<\/code> declaration. A <code class=\"calibre9\">struct<\/code> does not implement the <code class=\"calibre9\">==<\/code> and <code class=\"calibre9\">!=<\/code> operators, but they are automatically implemented with a <code class=\"calibre9\">record<\/code> <code class=\"calibre9\">struct<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: With this change, Microsoft recommends explicitly specifying <code class=\"calibre9\">class<\/code> if you want to define a <code class=\"calibre9\">record class<\/code>, even though the <code class=\"calibre9\">class<\/code> keyword is optional, as shown in the following code: <code class=\"calibre9\">public record class ImmutableAnimal(string Name);<\/code>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.7.8\" id=\"calibre_link-340\">\n<h3 data-number=\"7.7.8\" class=\"calibre8\">Releasing unmanaged resources<\/h3>\n<p class=\"rights\">In the previous chapter, we saw that constructors can be used to initialize fields and that a type may have multiple constructors. Imagine that a constructor allocates an <strong class=\"calibre2\">unmanaged resource<\/strong>, that is, anything that is not controlled by .NET, such as a file or mutex under the control of the operating system. The unmanaged resource must be manually released because .NET cannot do it for us using its automatic garbage collection feature.Garbage collection is an advanced topic, so for this topic, I will show some code examples, but you do not need to write the code yourself.Each type can have a single <strong class=\"calibre2\">finalizer<\/strong> that will be called by the .NET runtime when the resources need to be released. A finalizer has the same name as a constructor, that is, the name of the type, but it is prefixed with a tilde, <code class=\"calibre9\">~<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class ObjectWithUnmanagedResources\n{\n  public ObjectWithUnmanagedResources() \/\/ Constructor.\n  {\n    \/\/ Allocate any unmanaged resources.\n  }\n  ~ObjectWithUnmanagedResources() \/\/ Finalizer aka destructor.\n  {\n    \/\/ Deallocate any unmanaged resources.\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Do not confuse a finalizer (also known as a <strong class=\"calibre2\">destructor<\/strong>) with a <code class=\"calibre9\">Deconstruct<\/code> method. A destructor releases resources; in other words, it destroys an object in memory. A <code class=\"calibre9\">Deconstruct<\/code> method returns an object split up into its constituent parts and uses the C# deconstruction syntax, for example, when working with tuples. See <em class=\"calibre10\">Chapter 5<\/em>, <em class=\"calibre10\">Building Your Own Types with Object-Oriented Programming<\/em>, for details of <code class=\"calibre9\">Deconstruct<\/code> methods.The preceding code example is the minimum you should do when working with unmanaged resources. However, the problem with only providing a finalizer is that the .NET garbage collector requires two garbage collections to completely release the allocated resources for this type.Though optional, it is recommended to also provide a method to allow a developer who uses your type to explicitly release resources. This would allow the garbage collector to release managed parts of an unmanaged resource, such as a file, immediately and deterministically. This would mean it releases the managed memory part of the object in a single garbage collection instead of two rounds of garbage collection.There is a standard mechanism to do this by implementing the <code class=\"calibre9\">IDisposable<\/code> interface, as shown in the following example:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class ObjectWithUnmanagedResources : IDisposable\n{\n  public ObjectWithUnmanagedResources()\n  {\n    \/\/ Allocate unmanaged resource.\n  }\n  ~ObjectWithUnmanagedResources() \/\/ Finalizer.\n  {\n    Dispose(false);\n  }\n  bool disposed = false; \/\/ Indicates if resources have been released.\n  public void Dispose()\n  {\n    Dispose(true);\n    \/\/ Tell garbage collector it does not need to call the finalizer.\n    GC.SuppressFinalize(this); \n  }\n  protected virtual void Dispose(bool disposing)\n  {\n    if (disposed) return;\n    \/\/ Deallocate the *unmanaged* resource.\n    \/\/ ...\n    if (disposing)\n    {\n      \/\/ Deallocate any other *managed* resources.\n      \/\/ ...\n    }\n    disposed = true;\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">There are two <code class=\"calibre9\">Dispose<\/code> methods, one <code class=\"calibre9\">public<\/code> and one <code class=\"calibre9\">protected<\/code>:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The <code class=\"calibre9\">public void Dispose<\/code> method will be called by a developer using your type. When called, both unmanaged and managed resources need to be deallocated.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">protected virtual void Dispose<\/code> method with a <code class=\"calibre9\">bool<\/code> parameter is used internally to implement the deallocation of resources. It needs to check the <code class=\"calibre9\">disposing<\/code> parameter and <code class=\"calibre9\">disposed<\/code> field because if the finalizer thread has already run and called the <code class=\"calibre9\">~ObjectWithUnmanagedResources<\/code> method, then only managed resources need to be deallocated by the garbage collector.<\/li>\n<\/ul>\n<p class=\"rights\">The call to <code class=\"calibre9\">GC.SuppressFinalize(this)<\/code> is what notifies the garbage collector that it no longer needs to run the finalizer, removing the need for a second garbage collection.<\/p>\n<\/section>\n<section data-number=\"7.7.9\" id=\"calibre_link-341\">\n<h3 data-number=\"7.7.9\" class=\"calibre8\">Ensuring that Dispose is called<\/h3>\n<p class=\"rights\">When someone uses a type that implements <code class=\"calibre9\">IDisposable<\/code>, they can ensure that the public <code class=\"calibre9\">Dispose<\/code> method is called with the <code class=\"calibre9\">using<\/code> statement, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using (ObjectWithUnmanagedResources thing = new())\n{\n  \/\/ Code that uses thing.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The compiler converts your code into something like the following, which guarantees that even if an exception occurs, the <code class=\"calibre9\">Dispose<\/code> method will still be called:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ObjectWithUnmanagedResources thing = new(); \ntry\n{\n  \/\/ Code that uses thing.\n}\nfinally\n{\n  if (thing != null) thing.Dispose();\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When someone uses a type that implements <code class=\"calibre9\">IAsyncDisposable<\/code>, they can ensure that the public <code class=\"calibre9\">Dispose<\/code> method is called with the <code class=\"calibre9\">await<\/code> <code class=\"calibre9\">using<\/code> statement, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">await using (ObjectWithUnmanagedResources thing = new())\n{\n  \/\/ Code that uses async thing.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You will see practical examples of releasing unmanaged resources with <code class=\"calibre9\">IDisposable<\/code>, <code class=\"calibre9\">using<\/code> statements, and <code class=\"calibre9\">try<\/code>...<code class=\"calibre9\">finally<\/code> blocks in <em class=\"calibre10\">Chapter 9<\/em>, <em class=\"calibre10\">Working with Files, Streams, and Serialization<\/em>.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"7.8\" id=\"calibre_link-342\">\n<h2 data-number=\"7.8\" class=\"calibre5\">Working with null values<\/h2>\n<p class=\"rights\">You have seen how reference types are different from value types in how they are stored in memory, as well as how to store primitive values like numbers in <code class=\"calibre9\">struct<\/code> variables. But what if a variable does not yet have a value? How can we indicate that? C# has the concept of a <code class=\"calibre9\">null<\/code> value, which can be used to indicate that a variable has not been set.<\/p>\n<section data-number=\"7.8.1\" id=\"calibre_link-343\">\n<h3 data-number=\"7.8.1\" class=\"calibre8\">Making a value type nullable<\/h3>\n<p class=\"rights\">By default, <strong class=\"calibre2\">value types<\/strong> like <code class=\"calibre9\">int<\/code> and <code class=\"calibre9\">DateTime<\/code> must always have a <em class=\"calibre10\">value<\/em>, hence their name. Sometimes, for example, when reading values stored in a database that allows empty, missing, or <code class=\"calibre9\">null<\/code> values, it is convenient to allow a value type to be <code class=\"calibre9\">null<\/code>. We call this a <strong class=\"calibre2\">nullable value type<\/strong>.You can enable this by adding a question mark as a suffix to the type when declaring a variable.Let's see an example. We will create a new project because some of the null handling options are set at the project level:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">NullHandling<\/code> to the <code class=\"calibre9\">Chapter06<\/code> solution.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">NullHandling.csproj<\/code>, add an <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> to globally and statically import the <code class=\"calibre9\">System.Console<\/code> class.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, and then add statements to declare and assign values, including <code class=\"calibre9\">null<\/code>, to <code class=\"calibre9\">int<\/code> variables, one suffixed with <code class=\"calibre9\">?<\/code> and one not, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int thisCannotBeNull  = 4; \nthisCannotBeNull = null; \/\/ CS0037 compiler error!\nWriteLine(thisCannotBeNull);\nint? thisCouldBeNull = null;\nWriteLine(thisCouldBeNull);\nWriteLine(thisCouldBeNull.GetValueOrDefault());\nthisCouldBeNull = 7;\nWriteLine(thisCouldBeNull);\nWriteLine(thisCouldBeNull.GetValueOrDefault());<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the project and note the compile error, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Cannot convert null to 'int' because it is a non-nullable value type<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Comment out the statement that gives the compile error, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/thisCannotBeNull = null; \/\/ CS0037 compiler error!<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">4\n0\n7\n7<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The second line is blank because it outputs the <code class=\"calibre9\">null<\/code> value.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to use alternative syntax, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ The actual type of int? is Nullable&lt;int&gt;.\nNullable&lt;int&gt; thisCouldAlsoBeNull = null;\nthisCouldAlsoBeNull = 9;\nWriteLine(thisCouldAlsoBeNull);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Click on <code class=\"calibre9\">Nullable&lt;int&gt;<\/code> and press <span>F12<\/span>, or right-click and choose <strong class=\"calibre2\">Go To Definition<\/strong>.<\/li>\n<li class=\"calibre3\">Note that the generic value type, <code class=\"calibre9\">Nullable&lt;T&gt;<\/code>, must have a type <code class=\"calibre9\">T<\/code>, which is a <code class=\"calibre9\">struct<\/code>, aka a value type, and it has useful members like <code class=\"calibre9\">HasValue<\/code>, <code class=\"calibre9\">Value<\/code>, and <code class=\"calibre9\">GetValueOrDefault<\/code>, as shown in <em class=\"calibre10\">Figure 6.2<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 6.2: Revealing Nullable&lt;T&gt; members\" height=\"929\" src=\"\/images\/cs12\/000155.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 6.2: Revealing Nullable&lt;T&gt; members<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: When you append a <code class=\"calibre9\">?<\/code> after a <code class=\"calibre9\">struct<\/code> type, you change it to a different type. For example, <code class=\"calibre9\">DateTime?<\/code> becomes <code class=\"calibre9\">Nullable&lt;DateTime&gt;<\/code>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.8.2\" id=\"calibre_link-344\">\n<h3 data-number=\"7.8.2\" class=\"calibre8\">Understanding null-related initialisms<\/h3>\n<p class=\"rights\">Before we see some code, let's review some commonly used initialisms in <em class=\"calibre10\">Table 6.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Initialism<\/td>\n<td class=\"calibre21\">Meaning<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">NRT<\/td>\n<td class=\"calibre21\">Nullable Reference Type<\/td>\n<td class=\"calibre21\">A compiler feature introduced with C# 8 and enabled by default in new projects with C# 10, which performs static analysis of your code at design time and shows warnings of potential misuse of <code class=\"calibre9\">null<\/code> values for reference types.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">NRE<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">NullReferenceException<\/code><\/td>\n<td class=\"calibre21\">An exception thrown at runtime when <strong class=\"calibre2\">dereferencing<\/strong> a <code class=\"calibre9\">null<\/code> value, aka accessing a variable or member on an object that is <code class=\"calibre9\">null<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ANE<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">ArgumentNullException<\/code><\/td>\n<td class=\"calibre21\">An exception thrown at runtime by a method, property, or indexer invocation when an argument or value is <code class=\"calibre9\">null<\/code> , and when the business logic determines that it is not valid.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 6.3: Commonly used initialisms<br \/>\n<\/section>\n<section data-number=\"7.8.3\" id=\"calibre_link-345\">\n<h3 data-number=\"7.8.3\" class=\"calibre8\">Understanding nullable reference types<\/h3>\n<p class=\"rights\">The use of the <code class=\"calibre9\">null<\/code> value is so common, in so many languages, that many experienced programmers never question the need for its existence. However, there are many scenarios where we could write better, simpler code if a variable is not allowed to have a <code class=\"calibre9\">null<\/code> value.The most significant change to the C# 8 language compiler was the introduction of checks and warnings for nullable and non-nullable reference types. <em class=\"calibre10\">\"But wait!\"<\/em>, you are probably thinking, <em class=\"calibre10\">\"Reference types are already nullable!\"<\/em>And you would be right, but in C# 8 and later, reference types can be configured to warn you about <code class=\"calibre9\">null<\/code> values by setting a file- or project-level option, enabling this useful new feature. Since this is a big change for C#, Microsoft decided to make the feature an opt-in.It will take several years for this new C# language compiler feature to make an impact, since thousands of existing library packages and apps will expect the old behavior. Even Microsoft did not have time to fully implement this new feature in all the main .NET packages until .NET 6. Important libraries like <code class=\"calibre9\">Microsoft.Extensions<\/code> for logging, dependency injections, and configuration were not annotated until .NET 7.During the transition, you can choose between several approaches for your own projects:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Default<\/strong>: For projects created using .NET 5 or earlier, no changes are needed. Non-nullable reference types are not checked. For projects created using .NET 6 or later, nullability checks are enabled by default, but this can be disabled by either deleting the <code class=\"calibre9\">&lt;Nullable&gt;<\/code> entry in the project file or setting it to <code class=\"calibre9\">disable<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Opt-in project and opt-out files<\/strong>: Enable the feature at the project level, and for any files that need to remain compatible with old behavior, opt out. This was the approach Microsoft used internally while it updated its own packages to use this new feature.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\"><strong class=\"calibre2\">Opt-in files<\/strong>: Only enable the NRT feature for individual files.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> This NRT feature does not <em class=\"calibre10\">prevent<\/em> <code class=\"calibre9\">null<\/code> values &ndash; it just <em class=\"calibre10\">warns<\/em> you about them, and the warnings can be disabled, so you still need to be careful!<\/p>\n<\/blockquote>\n<pre class=\"calibre22\"><code class=\"calibre23\">string firstName; \/\/ Allows null but gives warning when potentially null.\nstring? lastName; \/\/ Allows null and does not give warning if null.<\/code><\/pre>\n<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"7.8.4\" id=\"calibre_link-346\">\n<h3 data-number=\"7.8.4\" class=\"calibre8\">Controlling the nullability warning check feature<\/h3>\n<p class=\"rights\">To enable the nullability warning check feature at the project level, have the <code class=\"calibre9\">&lt;Nullable&gt;<\/code> element set to <code class=\"calibre9\">enable<\/code> in your project file, as highlighted in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PropertyGroup&gt;\n  ...\n  &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n&lt;\/PropertyGroup&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To disable the nullability warning check feature at the project level, have the <code class=\"calibre9\">&lt;Nullable&gt;<\/code> element set to <code class=\"calibre9\">disable<\/code> in your project file, as highlighted in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PropertyGroup&gt;\n  ...\n  &lt;Nullable&gt;disable&lt;\/Nullable&gt;\n&lt;\/PropertyGroup&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You could also remove the <code class=\"calibre9\">&lt;Nullable&gt;<\/code> element completely because the default, if not explicitly set, is disabled.To disable the feature at the file level, add the following to the top of a code file:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#nullable disable<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To enable the feature at the file level, add the following to the top of a code file:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#nullable enable<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"7.8.5\" id=\"calibre_link-347\">\n<h3 data-number=\"7.8.5\" class=\"calibre8\">Disabling null and other compiler warnings<\/h3>\n<p class=\"rights\">You could decide to enable the nullability feature at the project or file level but then disable some of the 50+ warnings related to it. Some common nullability warnings are shown in <em class=\"calibre10\">Table 6.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Code<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">CS8600<\/code><\/td>\n<td class=\"calibre21\">Converting a null literal or a possible null value to a non-nullable type.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">CS8601<\/code><\/td>\n<td class=\"calibre21\">A possible null reference assignment.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">CS8602<\/code><\/td>\n<td class=\"calibre21\">A dereference of a possibly null reference.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">CS8603<\/code><\/td>\n<td class=\"calibre21\">A possible null reference return.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">CS8604<\/code><\/td>\n<td class=\"calibre21\">A possible null reference argument for a parameter.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">CS8618<\/code><\/td>\n<td class=\"calibre21\">A non-nullable field '&lt;field_name&gt;' must contain a non-null value when exiting a constructor. Consider declaring the field as nullable.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">CS8625<\/code><\/td>\n<td class=\"calibre21\">Cannot convert a null literal to a non-nullable reference type.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">CS8655<\/code><\/td>\n<td class=\"calibre21\">The switch expression does not handle some null inputs (it is not exhaustive).<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 6.4: Common nullability warnings<\/p>\n<p class=\"rights\">You can disable compiler warnings for a whole project. To do so, add a <code class=\"calibre9\">NoWarn<\/code> element with a semicolon-separated list of compiler warning codes, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;NoWarn&gt;CS8600;CS8602&lt;\/NoWarn&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To disable compiler warnings at the statement level, you can disable and then restore a specified compiler warning to temporarily suppress it for a block of statements, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#pragma warning disable CS8602\nWriteLine(firstName.Length);\nWriteLine(lastName.Length);\n#pragma warning restore CS8602<\/code><\/pre>\n<\/div>\n<p class=\"rights\">These techniques can be used for any compiler warnings, not just those related to nullability.<\/p>\n<\/section>\n<section data-number=\"7.8.6\" id=\"calibre_link-348\">\n<h3 data-number=\"7.8.6\" class=\"calibre8\">Declaring non-nullable variables and parameters<\/h3>\n<p class=\"rights\">If you enable NRTs and you want a reference type to be assigned the <code class=\"calibre9\">null<\/code> value, then you will have to use the same syntax to make a value type nullable, that is, adding a <code class=\"calibre9\">?<\/code> symbol after the type declaration.So, how do NRTs work? Let's look at an example. When storing information about an address, you might want to force a value for the street, city, and region, but the building can be left blank, that is, <code class=\"calibre9\">null<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">NullHandling<\/code> project, add a class file named <code class=\"calibre9\">Address.cs<\/code>.<\/li>\n<li class=\"calibre3\">in <code class=\"calibre9\">Address.cs<\/code>, delete any existing statements and then add statements to declare an <code class=\"calibre9\">Address<\/code> class with four fields, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class Address\n{\n  public string? Building; \n  public string Street; \n  public string City; \n  public string Region;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">After a few seconds, note the warnings about non-nullable fields, like <code class=\"calibre9\">Street<\/code> not being initialized, as shown in <em class=\"calibre10\">Figure 6.3<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 6.3: Warning messages about non-nullable fields in the Error List window\" height=\"949\" src=\"\/images\/cs12\/000104.png\" width=\"2161\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 6.3: Warning messages about non-nullable fields in the Error List window<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Assign the empty <code class=\"calibre9\">string<\/code> value to the <code class=\"calibre9\">Street<\/code> field, and define constructors to set the other fields that are non-nullable, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public string Street = string.Empty;\npublic string City;\npublic string Region;\npublic Address()\n{\n  City = string.Empty;\n  Region = string.Empty;\n}\n\/\/ Call the default parameterless constructor\n\/\/ to ensure that Region is also set.\npublic Address(string city) : this()\n{ \n  City = city;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, import the namespace to use <code class=\"calibre9\">Address<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Packt.Shared; \/\/ To use Address.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to instantiate an <code class=\"calibre9\">Address<\/code> and set its properties, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Address address = new(city: \"London\")\n{ \n  Building = null,\n  Street = null,\n  Region = \"UK\"\n};<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the <code class=\"calibre9\">Warning<\/code> <code class=\"calibre9\">CS8625<\/code> on setting the <code class=\"calibre9\">Street<\/code> but not the <code class=\"calibre9\">Building<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CS8625 Cannot convert null literal to non-nullable reference type.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Append an exclamation mark after <code class=\"calibre9\">null<\/code> when setting <code class=\"calibre9\">Street<\/code>, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Street = null!, \/\/ null-forgiving operator.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note that the warning disappears.<\/li>\n<li class=\"calibre3\">Add statements that will dereference the <code class=\"calibre9\">Building<\/code> and <code class=\"calibre9\">Street<\/code> properties, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(address.Building.Length);\nWriteLine(address.Street.Length);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the <code class=\"calibre9\">Warning CS8602<\/code> on setting the <code class=\"calibre9\">Building<\/code> but not the <code class=\"calibre9\">Street<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CS8602 Dereference of a possibly null reference.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">At runtime it is still possible for an exception to be thrown when working with <code class=\"calibre9\">Street<\/code>, but the compiler should continue to warn you of potential exceptions when working with <code class=\"calibre9\">Building<\/code> so that you can change your code to avoid them.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use the null-conditional operator to return <code class=\"calibre9\">null<\/code> instead of accessing the <code class=\"calibre9\">Length<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(address.Building?.Length);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app, and note that the statement that accesses the <code class=\"calibre9\">Length<\/code> of the <code class=\"calibre9\">Building<\/code> outputs a <code class=\"calibre9\">null<\/code> value (blank line), but a runtime exception occurs when we access the <code class=\"calibre9\">Length<\/code> of the <code class=\"calibre9\">Street<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Wrap the statement that accesses the <code class=\"calibre9\">Street<\/code> length in a null check, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (address.Street is not null)\n{\n  WriteLine(address.Street.Length);\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">It is worth reminding yourself that an NRT is only about asking the compiler to provide warnings about potential <code class=\"calibre9\">null<\/code> values that might cause problems. It does not actually change the behavior of your code. It performs a static analysis of your code at compile time.This explains why the new language feature is named nullable reference types. Starting with C# 8.0, unadorned reference types can become non-nullable, and the same syntax is used to make a reference type nullable, as it is used for value types.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Suffixing a reference type with <code class=\"calibre9\">?<\/code> does not change the type. This is different from suffixing a value type with <code class=\"calibre9\">?<\/code> that changes its type to <code class=\"calibre9\">Nullable&lt;T&gt;<\/code>. Reference types can already have <code class=\"calibre9\">null<\/code> values. All you do with <strong class=\"calibre2\">nullable reference types<\/strong> (<strong class=\"calibre2\">NRTs<\/strong>) is tell the compiler that you expect it to be <code class=\"calibre9\">null<\/code>, so the compiler does not need to warn you. However, this does not remove the need to perform <code class=\"calibre9\">null<\/code> checks throughout your code.<\/p>\n<\/blockquote>\n<p class=\"rights\">Now let's look at language features to work with <code class=\"calibre9\">null<\/code> values that change the behavior of your code and work well as a complement to NRTs.<\/p>\n<\/section>\n<section data-number=\"7.8.7\" id=\"calibre_link-349\">\n<h3 data-number=\"7.8.7\" class=\"calibre8\">Checking for null<\/h3>\n<p class=\"rights\">Checking whether a nullable reference type or nullable value type variable currently contains <code class=\"calibre9\">null<\/code> is important because if you do not, a <code class=\"calibre9\">NullReferenceException<\/code> can be thrown, which results in an error. You should check for a <code class=\"calibre9\">null<\/code> value before using a nullable variable, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Check that the variable is not null before using it.\nif (thisCouldBeNull != null)\n{\n  \/\/ Access a member of thisCouldBeNull.\n  int length = thisCouldBeNull.Length;\n  ...\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">C# 7 introduced <code class=\"calibre9\">is<\/code> combined with the <code class=\"calibre9\">!<\/code> (<code class=\"calibre9\">not<\/code>) operator as an alternative to <code class=\"calibre9\">!=<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (!(thisCouldBeNull is null))\n{<\/code><\/pre>\n<\/div>\n<p class=\"rights\">C# 9 introduced <code class=\"calibre9\">is not<\/code> as an even clearer alternative, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (thisCouldBeNull is not null)\n{<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Although you traditionally would use the expression <code class=\"calibre9\">(thisCouldBeNull != null)<\/code>, this is no longer considered good practice because the developer could have overloaded the <code class=\"calibre9\">!=<\/code> operator to change how it works. Using pattern matching with <code class=\"calibre9\">is null<\/code> and <code class=\"calibre9\">is not null<\/code> are the only guaranteed ways to check for <code class=\"calibre9\">null<\/code>. For many developers it is still instinctual to use <code class=\"calibre9\">!=<\/code>, so I apologize in advance if you catch me still using it!<\/p>\n<\/blockquote>\n<p class=\"rights\">If you try to use a member of a variable that might be <code class=\"calibre9\">null<\/code>, use the <strong class=\"calibre2\">null-conditional operator<\/strong>, <code class=\"calibre9\">?.<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string authorName = null;\nint? authorNameLength;\n\/\/ The following throws a NullReferenceException.\nauthorNameLength = authorName.Length;\n\/\/ Instead of throwing an exception, null is assigned.\nauthorNameLength = authorName?.Length;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Sometimes, you want to either assign a variable to a result or use an alternative value, such as <code class=\"calibre9\">3<\/code>, if the variable is <code class=\"calibre9\">null<\/code>. You do this using the <strong class=\"calibre2\">null-coalescing operator<\/strong>, <code class=\"calibre9\">??<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Result will be 25 if authorName?.Length is null.\nauthorNameLength = authorName?.Length ?? 25;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"7.8.8\" id=\"calibre_link-350\">\n<h3 data-number=\"7.8.8\" class=\"calibre8\">Checking for null in method parameters<\/h3>\n<p class=\"rights\">Even if you enable NRTs, when defining methods with parameters, it is good practice to check for <code class=\"calibre9\">null<\/code> values.In earlier versions of C#, you would have to write <code class=\"calibre9\">if<\/code> statements to check for <code class=\"calibre9\">null<\/code> parameter values and then throw an <code class=\"calibre9\">ArgumentNullException<\/code> for any parameter that is <code class=\"calibre9\">null<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public void Hire(Person manager, Person employee)\n{\n  if (manager is null)\n  {\n    throw new ArgumentNullException(paramName: nameof(manager));\n  }\n  if (employee is null)\n  {\n    throw new ArgumentNullException(paramName: nameof(employee));\n  }\n  ...\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">C# 10 introduced a convenience method to throw an exception if an argument is <code class=\"calibre9\">null<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public void Hire(Person manager, Person employee)\n{\n  ArgumentNullException.ThrowIfNull(manager);\n  ArgumentNullException.ThrowIfNull(employee);\n  ...\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">C# 11 previews proposed and introduced a new <code class=\"calibre9\">!!<\/code> operator that does this for you, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public void Hire(Person manager!!, Person employee!!)\n{\n  ...\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">if<\/code> statement and throwing of the exception would be done for you. The code is injected and executed before any statements that you write.This proposal was controversial within the C# developer community. Some would prefer the use of attributes to decorate parameters instead of a pair of characters. The .NET product team said they reduced the .NET libraries by more than 10,000 lines of code by using this feature. That sounds like a good reason to use it to me! And no one must use it if they choose not to. Unfortunately, the team eventually decided to remove the feature, so now we all have to write the null checks manually. If you're interested in this story, then you can read more about it at the following link:<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/csharp-11-preview-updates\/#remove-parameter-null-checking-from-c-11\">https:\/\/devblogs.microsoft.com\/dotnet\/csharp-11-preview-updates\/#remove-parameter-null-checking-from-c-11<\/a>I include this story in this book because I think it's an interesting example of Microsoft being transparent, by developing .NET in the open and listening to and responding to feedback from the community.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Always remember that nullable is a warning check, not an enforcement. You can read more about the compiler warnings relating to <code class=\"calibre9\">null<\/code> at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/compiler-messages\/nullable-warnings\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/compiler-messages\/nullable-warnings<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">That's more than enough talk about \"nothing\"! Let's look at the meat of this chapter, inheritance.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"7.9\" id=\"calibre_link-351\">\n<h2 data-number=\"7.9\" class=\"calibre5\">Inheriting from classes<\/h2>\n<p class=\"rights\">The <code class=\"calibre9\">Person<\/code> type we created earlier derived (inherited) from <code class=\"calibre9\">System.Object<\/code>. Now, we will create a subclass that inherits from <code class=\"calibre9\">Person<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibrary<\/code> project, add a new class file named <code class=\"calibre9\">Employee.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify its contents to define a class named <code class=\"calibre9\">Employee<\/code> that derives from <code class=\"calibre9\">Person<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class Employee : Person\n{\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PeopleApp<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, add statements to create an instance of the <code class=\"calibre9\">Employee<\/code> class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Employee john = new()\n{\n  Name = \"John Jones\",\n  Born = new(year: 1990, month: 7, day: 28,\n    hour: 0, minute: 0, second: 0, offset: TimeSpan.Zero))\n};\njohn.WriteToConsole();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">John Jones was born on a Saturday.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note that the <code class=\"calibre9\">Employee<\/code> class has inherited all the members of <code class=\"calibre9\">Person<\/code>.<\/p>\n<section data-number=\"7.9.1\" id=\"calibre_link-352\">\n<h3 data-number=\"7.9.1\" class=\"calibre8\">Extending classes to add functionality<\/h3>\n<p class=\"rights\">Now, we will add some employee-specific members to extend the class:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Employee.cs<\/code>, add statements to define two properties, for an employee code and the date they were hired (we do not need to know a start time, so we can use the <code class=\"calibre9\">DateOnly<\/code> type), as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public string? EmployeeCode { get; set; } \npublic DateOnly HireDate { get; set; }<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to set John's employee code and hire date, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">john.EmployeeCode = \"JJ001\";\njohn.HireDate = new(year: 2014, month: 11, day: 23); \nWriteLine($\"{john.Name} was hired on {john.HireDate:yyyy-MM-dd}.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">John Jones was hired on 2014-11-23.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"7.9.2\" id=\"calibre_link-353\">\n<h3 data-number=\"7.9.2\" class=\"calibre8\">Hiding members<\/h3>\n<p class=\"rights\">So far, the <code class=\"calibre9\">WriteToConsole<\/code> method is inherited from <code class=\"calibre9\">Person<\/code>, and it only outputs the employee's name and date and time of birth. We might want to change what this method does for an employee:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Employee.cs<\/code>, add statements to redefine the <code class=\"calibre9\">WriteToConsole<\/code> method, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class Employee : Person\n{\n  public string? EmployeeCode { get; set; }\n  public DateOnly HireDate { get; set; }\n  public void WriteToConsole()\n  {\n    WriteLine(format:\n      \"{0} was born on {1:dd\/MM\/yy} and hired on {2:dd\/MM\/yy}.\",\n      arg0: Name, arg1: Born, arg2: HireDate);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project, view the result, and note that the first line of output is before the employees were hired; hence, it has a default date, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">John Jones was born on 28\/07\/90 and hired on 01\/01\/01.\nJohn Jones was hired on 2014-11-23.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Your coding tool warns you that your method now hides the method from <code class=\"calibre9\">Person<\/code> by drawing a squiggle under the method name, the <strong class=\"calibre2\">PROBLEMS<\/strong>\/<strong class=\"calibre2\">Error List<\/strong> window includes more details, and the compiler will output a warning when you build and run the console application, as shown in <em class=\"calibre10\">Figure 6.4<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 6.4: Hidden method warning\" height=\"734\" src=\"\/images\/cs12\/000021.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 6.4: Hidden method warning<\/figcaption><\/figure>\n<p class=\"rights\">As the warning describes, you should hide this message by applying the <code class=\"calibre9\">new<\/code> keyword to the method, indicating that you are deliberately replacing the old method, as highlighted in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public new void WriteToConsole()<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Make this fix now.<\/p>\n<\/section>\n<section data-number=\"7.9.3\" id=\"calibre_link-354\">\n<h3 data-number=\"7.9.3\" class=\"calibre8\">Understanding this and base keywords<\/h3>\n<p class=\"rights\">There are two special C# keywords that can be used to refer to the current object instance or the base class that it inherits from:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">this<\/code>: Represents the current object instance. For example, in the <code class=\"calibre9\">Person<\/code> class instance members (but not in static members), you could use the expression <code class=\"calibre9\">this.Born<\/code> to access the <code class=\"calibre9\">Born<\/code> field of the current object instance. You rarely need to use it, since the expression <code class=\"calibre9\">Born<\/code> would also work. It is only when there is a local variable also named <code class=\"calibre9\">Born<\/code> that you would need to use <code class=\"calibre9\">this.Born<\/code>, to explicitly say you are referring to the field, not the local variable.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">base<\/code>: Represents the base class that the current object inherits from. For example, anywhere in the <code class=\"calibre9\">Person<\/code> class, you could use the expression <code class=\"calibre9\">base.ToString()<\/code> to call the base class implementation of that method.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You will (hopefully) remember from <em class=\"calibre10\">Chapter 5<\/em>, <em class=\"calibre10\">Building Your Own Types with Object-Oriented Programming<\/em>, that to access static members you must use the type name.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.9.4\" id=\"calibre_link-355\">\n<h3 data-number=\"7.9.4\" class=\"calibre8\">Overriding members<\/h3>\n<p class=\"rights\">Rather than hiding a method, it is usually better to <strong class=\"calibre2\">override<\/strong> it. You can only override it if the base class chooses to allow overriding, by applying the <code class=\"calibre9\">virtual<\/code> keyword to any methods that should allow overriding.Let's see an example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement to write the value of the <code class=\"calibre9\">john<\/code> variable to the console using its <code class=\"calibre9\">string<\/code> representation, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(john.ToString());<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and note that the <code class=\"calibre9\">ToString<\/code> method is inherited from <code class=\"calibre9\">System.Object<\/code>, so the implementation returns the namespace and type name, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Packt.Shared.Employee<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code> (not in the <code class=\"calibre9\">Employee<\/code> class!), override this behavior by adding a <code class=\"calibre9\">ToString<\/code> method to output the name of the person as well as the type name, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Overridden methods\npublic override string ToString()\n{\n  return $\"{Name} is a {base.ToString()}.\";\n}\n#endregion<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">base<\/code> keyword allows a subclass to access members of its superclass, that is, the <strong class=\"calibre2\">base class<\/strong> that it inherits or derives from.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result. Now, when the <code class=\"calibre9\">ToString<\/code> method is called, it outputs the person's name, as well as returning the base class's implementation of <code class=\"calibre9\">ToString<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\"> John Jones is a Packt.Shared.Employee.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Many real-world APIs, for example, Microsoft's Entity Framework Core, Castle's DynamicProxy, and Optimizely CMS's content models, require the properties that you define in your classes to be marked as <code class=\"calibre9\">virtual<\/code> so that they can be overridden. Carefully decide which of your method and property members should be marked as <code class=\"calibre9\">virtual<\/code>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.9.5\" id=\"calibre_link-356\">\n<h3 data-number=\"7.9.5\" class=\"calibre8\">Inheriting from abstract classes<\/h3>\n<p class=\"rights\">Earlier in this chapter, you learned about interfaces that can define a set of members that a type must have to meet a basic level of functionality. These are very useful, but their main limitation is that until C# 8 they could not provide any implementation of their own.This is a particular problem if you still need to create class libraries that will work with .NET Framework and other platforms that do not support .NET Standard 2.1.In those earlier platforms, you could use an <strong class=\"calibre2\">abstract class<\/strong> as a sort of halfway house between a pure interface and a fully implemented class.When a class is marked as <code class=\"calibre9\">abstract<\/code>, this means that it cannot be instantiated because you have indicated that the class is not complete. It needs more implementation before it can be instantiated. For example, the <code class=\"calibre9\">System.IO.Stream<\/code> class is <code class=\"calibre9\">abstract<\/code> because it implements common functionality that all streams would need but is not complete, and therefore, it is useless without more implementation that is specific to the type of stream, so you cannot instantiate it using <code class=\"calibre9\">new Stream()<\/code>.Let's compare the two types of interface and the two types of class, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public interface INoImplementation \/\/ C# 1 and later.\n{\n  void Alpha(); \/\/ Must be implemented by derived type.\n}\npublic interface ISomeImplementation \/\/ C# 8 and later.\n{\n  void Alpha(); \/\/ Must be implemented by derived type.\n  void Beta()\n  {\n    \/\/ Default implementation; can be overridden.\n  }\n}\npublic abstract class PartiallyImplemented \/\/ C# 1 and later.\n{\n  public abstract void Gamma(); \/\/ Must be implemented by derived type.\n  public virtual void Delta() \/\/ Can be overridden.\n  {\n    \/\/ Implementation.\n  }\n}\npublic class FullyImplemented : PartiallyImplemented, ISomeImplementation\n{\n  public void Alpha()\n  {\n    \/\/ Implementation.\n  }\n  public override void Gamma()\n  {\n    \/\/ Implementation.\n  }\n}\n\/\/ You can only instantiate the fully implemented class.\nFullyImplemented a = new();\n\/\/ All the other types give compile errors.\nPartiallyImplemented b = new(); \/\/ Compile error!\nISomeImplementation c = new(); \/\/ Compile error!\nINoImplementation d = new(); \/\/ Compile error!<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"7.9.6\" id=\"calibre_link-357\">\n<h3 data-number=\"7.9.6\" class=\"calibre8\">Choosing between an interface and an abstract class<\/h3>\n<p class=\"rights\">You have now seen examples of implementing the concept of abstraction using either an interface or an <code class=\"calibre9\">abstract<\/code> class. Which should you pick? Now that an interface can have default implementations for its members, is the <code class=\"calibre9\">abstract<\/code> keyword for a class obsolete?Well, let\u2019s think about a real example. <code class=\"calibre9\">Stream<\/code> is an <code class=\"calibre9\">abstract<\/code> class. Would or could the .NET team use an interface for that today? Every member of an interface must be <code class=\"calibre9\">public<\/code> (or at least match the interface's access level which could be <code class=\"calibre9\">internal<\/code> if it should only be used in the class library that it's defined in). An <code class=\"calibre9\">abstract<\/code> class has more flexibility in its members' access modifiers.Another advantage of an <code class=\"calibre9\">abstract<\/code> class over an interface is that serialization often does not work for an interface. So, no, we still need to be able to define abstract classes.<\/p>\n<\/section>\n<section data-number=\"7.9.7\" id=\"calibre_link-358\">\n<h3 data-number=\"7.9.7\" class=\"calibre8\">Preventing inheritance and overriding<\/h3>\n<p class=\"rights\">You can prevent another developer from inheriting from your class by applying the <code class=\"calibre9\">sealed<\/code> keyword to its definition. For example, no one can inherit from Scrooge McDuck, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public sealed class ScroogeMcDuck\n{\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">An example of <code class=\"calibre9\">sealed<\/code> in .NET is the <code class=\"calibre9\">string<\/code> class. Microsoft has implemented some extreme optimizations inside the <code class=\"calibre9\">string<\/code> class that could be negatively affected by your inheritance, so Microsoft prevents that.You can prevent someone from further overriding a <code class=\"calibre9\">virtual<\/code> method in your class by applying the <code class=\"calibre9\">sealed<\/code> keyword to the method. For example, no one can change the way Lady Gaga sings, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class Singer\n{\n  \/\/ Virtual allows this method to be overridden.\n  public virtual void Sing()\n  {\n    WriteLine(\"Singing...\");\n  }\n}\npublic class LadyGaga : Singer\n{\n  \/\/ The sealed keyword prevents overriding the method in subclasses.\n  public sealed override void Sing()\n  {\n    WriteLine(\"Singing with style...\");\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You can only seal an overridden method.<\/p>\n<\/section>\n<section data-number=\"7.9.8\" id=\"calibre_link-359\">\n<h3 data-number=\"7.9.8\" class=\"calibre8\">Understanding polymorphism<\/h3>\n<p class=\"rights\">You have now seen two ways to change the behavior of an inherited method. We can <em class=\"calibre10\">hide<\/em> it using the <code class=\"calibre9\">new<\/code> keyword (known as <strong class=\"calibre2\">non-polymorphic inheritance<\/strong>), or we can <em class=\"calibre10\">override<\/em> it (known as <strong class=\"calibre2\">polymorphic inheritance<\/strong>).Both ways can access members of the base or superclass by using the <code class=\"calibre9\">base<\/code> keyword, so what is the difference?It all depends on the type of variable holding a reference to the object. For example, a variable of the <code class=\"calibre9\">Person<\/code> type can hold a reference to a <code class=\"calibre9\">Person<\/code> class, or any type that derives from <code class=\"calibre9\">Person<\/code>.Let's see how this could affect your code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Employee.cs<\/code>, add statements to override the <code class=\"calibre9\">ToString<\/code> method so that it writes the employee's name and code to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public override string ToString()\n{\n  return $\"{Name}'s code is {EmployeeCode}.\";\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, write statements to create a new employee named Alice stored in a variable of type <code class=\"calibre9\">Employee<\/code>, also store Alice in a second variable of type <code class=\"calibre9\">Person<\/code>, and then call both variables' <code class=\"calibre9\">WriteToConsole<\/code> and <code class=\"calibre9\">ToString<\/code> methods, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Employee aliceInEmployee = new()\n  { Name = \"Alice\", EmployeeCode = \"AA123\" };\nPerson aliceInPerson = aliceInEmployee; \naliceInEmployee.WriteToConsole(); \naliceInPerson.WriteToConsole(); \nWriteLine(aliceInEmployee.ToString()); \nWriteLine(aliceInPerson.ToString());<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Alice was born on 01\/01\/01 and hired on 01\/01\/01 \nAlice was born on a Monday\nAlice's code is AA123 \nAlice's code is AA123<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When a method is hidden with <code class=\"calibre9\">new<\/code>, the compiler is not smart enough to know that the object is an <code class=\"calibre9\">Employee<\/code>, so it calls the <code class=\"calibre9\">WriteToConsole<\/code> method in <code class=\"calibre9\">Person<\/code>.When a method is overridden with <code class=\"calibre9\">virtual<\/code> and <code class=\"calibre9\">override<\/code>, the compiler is smart enough to know that although the variable is declared as a <code class=\"calibre9\">Person<\/code> class, the object itself is an <code class=\"calibre9\">Employee<\/code> class, and therefore, the <code class=\"calibre9\">Employee<\/code> implementation of <code class=\"calibre9\">ToString<\/code> is called.The member modifiers and the effect they have are summarized in the following table:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Variable type<\/td>\n<td class=\"calibre21\">Member modifier<\/td>\n<td class=\"calibre21\">Method executed<\/td>\n<td class=\"calibre21\">In class<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Person<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">WriteToConsole<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Person<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Employee<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">new<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">WriteToConsole<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Employee<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Person<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">virtual<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">ToString<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Employee<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Employee<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">override<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">ToString<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Employee<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"rights\">In my opinion, polymorphism is academic to most programmers. If you get the concept, that's cool; but, if not, I suggest that you don't worry about it. Some people like to make others feel inferior by saying understanding polymorphism is important for all C# programmers, but in my opinion, it's not. There are thousands of other topics that your time and effort will be better spent on.You can have a successful career with C# and never need to be able to explain polymorphism, just as a racing car driver doesn't need to explain the engineering behind fuel injection.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You should use <code class=\"calibre9\">virtual<\/code> and <code class=\"calibre9\">override<\/code> rather than <code class=\"calibre9\">new<\/code> to change the implementation of an inherited method whenever possible.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"7.10\" id=\"calibre_link-360\">\n<h2 data-number=\"7.10\" class=\"calibre5\">Casting within inheritance hierarchies<\/h2>\n<p class=\"rights\"><strong class=\"calibre2\">Casting<\/strong> between types is subtly different from converting between types. Casting is between similar types, like between a 16-bit integer and a 32-bit integer, or between a superclass and one of its subclasses. <strong class=\"calibre2\">Converting<\/strong> is between dissimilar types, such as between text and a number.For example, if you need to work with multiple types of <code class=\"calibre9\">stream<\/code>, then instead of declaring specific types of stream like <code class=\"calibre9\">MemoryStream<\/code> or <code class=\"calibre9\">FileStream<\/code>, you could declare an array of <code class=\"calibre9\">Stream<\/code>, the supertype of <code class=\"calibre9\">MemoryStream<\/code> and <code class=\"calibre9\">FileStream<\/code>.<\/p>\n<section data-number=\"7.10.1\" id=\"calibre_link-361\">\n<h3 data-number=\"7.10.1\" class=\"calibre8\">Implicit casting<\/h3>\n<p class=\"rights\">In the previous example, you saw how an instance of a derived type can be stored in a variable of its base type (or its base's base type, and so on). When we do this, it is called <strong class=\"calibre2\">implicit casting<\/strong>.<\/p>\n<\/section>\n<section data-number=\"7.10.2\" id=\"calibre_link-362\">\n<h3 data-number=\"7.10.2\" class=\"calibre8\">Explicit casting<\/h3>\n<p class=\"rights\">The opposite of implicit casting is explicit casting, and you must use parentheses around the type you want to cast into as a prefix to do it:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement to assign the <code class=\"calibre9\">aliceInPerson<\/code> variable to a new <code class=\"calibre9\">Employee<\/code> variable, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Employee explicitAlice = aliceInPerson;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Your coding tool displays a red squiggle and a compile error, as shown in <em class=\"calibre10\">Figure 6.5<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 6.5: A missing explicit cast compile error\" height=\"796\" src=\"\/images\/cs12\/000111.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 6.5: A missing explicit cast compile error<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Change the statement to prefix the assigned variable name with a cast to the <code class=\"calibre9\">Employee<\/code> type, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Employee explicitAlice = (Employee)aliceInPerson;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"7.10.3\" id=\"calibre_link-363\">\n<h3 data-number=\"7.10.3\" class=\"calibre8\">Avoiding casting exceptions<\/h3>\n<p class=\"rights\">The compiler is now happy; however, because <code class=\"calibre9\">aliceInPerson<\/code> might be a different derived type, like <code class=\"calibre9\">Student<\/code> instead of <code class=\"calibre9\">Employee<\/code>, we need to be careful. In a real application with more complex code, the current value of this variable could have been set to a <code class=\"calibre9\">Student<\/code> instance, and then this statement would throw an <code class=\"calibre9\">InvalidCastException<\/code> error at runtime.<\/p>\n<\/section>\n<section data-number=\"7.10.4\" id=\"calibre_link-364\">\n<h3 data-number=\"7.10.4\" class=\"calibre8\">Using is to check a type<\/h3>\n<p class=\"rights\">We can handle this by writing a <code class=\"calibre9\">try<\/code> statement, but there is a better way. We can check the type of an object using the <code class=\"calibre9\">is<\/code> keyword:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Wrap the explicit cast statement in an <code class=\"calibre9\">if<\/code> statement, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (aliceInPerson is Employee)\n{\n  WriteLine($\"{nameof(aliceInPerson)} is an Employee.\"); \n  Employee explicitAlice = (Employee)aliceInPerson;\n  \/\/ Safely do something with explicitAlice.\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">aliceInPerson is an Employee.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You could simplify the code further using a declaration pattern, and this will avoid the need to perform an explicit cast, as shown in the following code:<\/p>\n<\/blockquote>\n<pre class=\"calibre22\"><code class=\"calibre23\">if (aliceInPerson is Employee explicitAlice)  \n{\n  WriteLine($\"{nameof(aliceInPerson)} is an Employee.\");\n  \/\/ Safely do something with explicitAlice.\n}<\/code><\/pre>\n<p class=\"rights\">What if you want to execute a block of statements when Alice is <em class=\"calibre10\">not<\/em> an employee?In the past, you would have had to use the <code class=\"calibre9\">!<\/code> (not) operator, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (!(aliceInPerson is Employee))<\/code><\/pre>\n<\/div>\n<p class=\"rights\">With C# 9 and later, you can use the <code class=\"calibre9\">not<\/code> keyword, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (aliceInPerson is not Employee)<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"7.10.5\" id=\"calibre_link-365\">\n<h3 data-number=\"7.10.5\" class=\"calibre8\">Using as to cast a type<\/h3>\n<p class=\"rights\">Alternatively, you can use the <code class=\"calibre9\">as<\/code> keyword to cast a type. Instead of throwing an exception, the <code class=\"calibre9\">as<\/code> keyword returns <code class=\"calibre9\">null<\/code> if the type cannot be cast:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to cast Alice using the <code class=\"calibre9\">as<\/code> keyword, and then check whether the return value is not null, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Employee? aliceAsEmployee = aliceInPerson as Employee;\nif (aliceAsEmployee is not null)\n{\n  WriteLine($\"{nameof(aliceInPerson)} as an Employee.\");\n  \/\/ Safely do something with aliceAsEmployee.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Since accessing a member of a <code class=\"calibre9\">null<\/code> variable will throw a <code class=\"calibre9\">NullReferenceException<\/code> error, you should always check for <code class=\"calibre9\">null<\/code> before using the result.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">aliceInPerson as an Employee.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Use the <code class=\"calibre9\">is<\/code> and <code class=\"calibre9\">as<\/code> keywords to avoid throwing exceptions when casting between derived types. If you don't do this, you must write <code class=\"calibre9\">try<\/code>-<code class=\"calibre9\">catch<\/code> statements for <code class=\"calibre9\">InvalidCastException<\/code>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"7.11\" id=\"calibre_link-366\">\n<h2 data-number=\"7.11\" class=\"calibre5\">Inheriting and extending .NET types<\/h2>\n<p class=\"rights\">.NET has pre-built class libraries containing hundreds of thousands of types. Rather than creating your own completely new types, you can often get a head start by deriving from one of Microsoft's types to inherit some or all its behavior, and then overriding or extending it.<\/p>\n<section data-number=\"7.11.1\" id=\"calibre_link-367\">\n<h3 data-number=\"7.11.1\" class=\"calibre8\">Inheriting exceptions<\/h3>\n<p class=\"rights\">As an example of inheritance, we will derive a new type of exception:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibrary<\/code> project, add a new class file named <code class=\"calibre9\">PersonException.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify the contents of the file to define a class named <code class=\"calibre9\">PersonException<\/code> with three constructors, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class PersonException : Exception\n{\n  public PersonException() : base() { }\n  public PersonException(string message) : base(message) { }\n  public PersonException(string message, Exception innerException)\n    : base(message, innerException) { }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Unlike ordinary methods, constructors are not inherited, so we must explicitly declare and explicitly call the <code class=\"calibre9\">base<\/code> constructor implementations in <code class=\"calibre9\">System.Exception<\/code> (or whichever exception class you derived from) to make them available to programmers who might want to use those constructors with our custom exception.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add statements to define a method that throws an exception if a date\/time parameter is earlier than a person's date and time of birth, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public void TimeTravel(DateTime when)\n{\n  if (when &lt;= Born)\n  {\n    throw new PersonException(\"If you travel back in time to a date earlier than your own birth, then the universe will explode!\");\n  }\n  else\n  {\n    WriteLine($\"Welcome to {when:yyyy}!\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to test what happens when employee John Jones tries to time-travel too far back, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">try\n{\n  john.TimeTravel(when: new(1999, 12, 31));\n  john.TimeTravel(when: new(1950, 12, 25));\n}\ncatch (PersonException ex)\n{\n  WriteLine(ex.Message);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Welcome to 1999!\nIf you travel back in time to a date earlier than your own birth, then the universe will explode!<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: When defining your own exceptions, give them the same three constructors that explicitly call the built-in ones in <code class=\"calibre9\">System.Exception<\/code>. Other exceptions that you might inherit from may have more.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.11.2\" id=\"calibre_link-368\">\n<h3 data-number=\"7.11.2\" class=\"calibre8\">Extending types when you can't inherit<\/h3>\n<p class=\"rights\">Earlier, we saw how the <code class=\"calibre9\">sealed<\/code> modifier can be used to prevent inheritance.Microsoft has applied the <code class=\"calibre9\">sealed<\/code> keyword to the <code class=\"calibre9\">System.String<\/code> class so that no one can inherit and potentially break the behavior of strings.Can we still add new methods to strings? Yes, if we use a language feature named <strong class=\"calibre2\">extension methods<\/strong>, which was introduced with C# 3.0. To properly understand extension methods, we need to review static methods first.<\/p>\n<\/section>\n<section data-number=\"7.11.3\" id=\"calibre_link-369\">\n<h3 data-number=\"7.11.3\" class=\"calibre8\">Using static methods to reuse functionality<\/h3>\n<p class=\"rights\">Since the first version of C#, we've been able to create <code class=\"calibre9\">static<\/code> methods to reuse functionality, such as the ability to validate that a <code class=\"calibre9\">string<\/code> contains an email address. The implementation will use a regular expression that you will learn more about in <em class=\"calibre10\">Chapter 8<\/em>, <em class=\"calibre10\">Working with Common .NET Types<\/em>.Let's write some code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibrary<\/code> project, add a new class file named <code class=\"calibre9\">StringExtensions.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify <code class=\"calibre9\">StringExtensions.cs<\/code>, as shown in the following code, and note the following:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">The class imports a namespace to handle regular expressions.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">IsValidEmail<\/code> method is <code class=\"calibre9\">static<\/code>, and it uses the <code class=\"calibre9\">Regex<\/code> type to check for matches against a simple email pattern that looks for valid characters before and after the <code class=\"calibre9\">@<\/code> symbol:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Text.RegularExpressions; \/\/ To use Regex.\nnamespace Packt.Shared;\npublic class StringExtensions\n{\n  public static bool IsValidEmail(string input)\n  {\n    \/\/ Use a simple regular expression to check\n    \/\/ that the input string is a valid email.\n    return Regex.IsMatch(input,\n      @\"[a-zA-Z0-9\\.-_]+@[a-zA-Z0-9\\.-_]+\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to validate two examples of email addresses, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string email1 = \"pamela@test.com\"; \nstring email2 = \"ian&amp;test.com\";\nWriteLine(\"{0} is a valid e-mail address: {1}\", \n  arg0: email1,\n  arg1: StringExtensions.IsValidEmail(email1));\nWriteLine(\"{0} is a valid e-mail address: {1}\",\n  arg0: email2,\n  arg1: StringExtensions.IsValidEmail(email2));<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">pamela@test.com is a valid e-mail address: True \nian&amp;test.com is a valid e-mail address: False<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This works, but extension methods can reduce the amount of code we must type and simplify the usage of this function.<\/p>\n<\/section>\n<section data-number=\"7.11.4\" id=\"calibre_link-370\">\n<h3 data-number=\"7.11.4\" class=\"calibre8\">Using extension methods to reuse functionality<\/h3>\n<p class=\"rights\">It is easy to turn <code class=\"calibre9\">static<\/code> methods into extension methods:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">StringExtensions.cs<\/code>, add the <code class=\"calibre9\">static<\/code> modifier before the class, and then add the <code class=\"calibre9\">this<\/code> modifier before the <code class=\"calibre9\">string<\/code> type, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public static class StringExtensions\n{\n  public static bool IsValidEmail(this string input)\n  {<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: These two changes tell the compiler that it should treat the method as one that extends the <code class=\"calibre9\">string<\/code> type.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to use the extension method for <code class=\"calibre9\">string<\/code> values that need to be checked for valid email addresses, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(\"{0} is a valid e-mail address: {1}\",\n  arg0: email1,\n  arg1: email1.IsValidEmail());\nWriteLine(\"{0} is a valid e-mail address: {1}\", \n  arg0: email2,\n  arg1: email2.IsValidEmail());<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note the subtle simplification in the syntax to call the <code class=\"calibre9\">IsValidEmail<\/code> method. The older, longer syntax still works too.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">The <code class=\"calibre9\">IsValidEmail<\/code> extension method now appears to be a method just like all the actual instance methods of the <code class=\"calibre9\">string<\/code> type, such as <code class=\"calibre9\">IsNormalized<\/code>, except with a small down arrow on the method icon to indicate an extension method, as shown in <em class=\"calibre10\">Figure 6.6<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 6.6: Extension methods appear in IntelliSense alongside instance methods\" height=\"659\" src=\"\/images\/cs12\/000034.png\" width=\"2161\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 6.6: Extension methods appear in IntelliSense alongside instance methods<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Run the <code class=\"calibre9\">PeopleApp<\/code> project and view the result, which will be the same as before.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Extension methods cannot replace or override existing instance methods. You cannot, for example, redefine the <code class=\"calibre9\">Insert<\/code> method. The extension method will appear as an overload in IntelliSense, but an instance method will be called in preference to an extension method with the same name and signature.<\/p>\n<\/blockquote>\n<p class=\"rights\">Although extension methods might not seem to give a big benefit, in <em class=\"calibre10\">Chapter 11<\/em>, <em class=\"calibre10\">Querying and Manipulating Data Using LINQ<\/em>, you will see some extremely powerful uses of extension methods.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"7.12\" id=\"calibre_link-371\">\n<h2 data-number=\"7.12\" class=\"calibre5\">Summarizing custom type choices<\/h2>\n<p class=\"rights\">Now that we have covered OOP and the C# features that enable you to define your own types, let's summarize what you've learned.<\/p>\n<section data-number=\"7.12.1\" id=\"calibre_link-372\">\n<h3 data-number=\"7.12.1\" class=\"calibre8\">Categories of custom type and their capabilities<\/h3>\n<p class=\"rights\">Categories of custom type and their capabilities are summarized in the following table:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Type<\/td>\n<td class=\"calibre21\">Instantiation<\/td>\n<td class=\"calibre21\">Inheritance<\/td>\n<td class=\"calibre21\">Equality<\/td>\n<td class=\"calibre21\">Memory<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">class<\/code><\/td>\n<td class=\"calibre21\">Yes<\/td>\n<td class=\"calibre21\">Single<\/td>\n<td class=\"calibre21\">Reference<\/td>\n<td class=\"calibre21\">Heap<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">sealed<\/code> <code class=\"calibre9\">class<\/code><\/td>\n<td class=\"calibre21\">Yes<\/td>\n<td class=\"calibre21\">None<\/td>\n<td class=\"calibre21\">Reference<\/td>\n<td class=\"calibre21\">Heap<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">abstract<\/code> <code class=\"calibre9\">class<\/code><\/td>\n<td class=\"calibre21\">No<\/td>\n<td class=\"calibre21\">Single<\/td>\n<td class=\"calibre21\">Reference<\/td>\n<td class=\"calibre21\">Heap<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">record<\/code> or <code class=\"calibre9\">record<\/code> <code class=\"calibre9\">class<\/code><\/td>\n<td class=\"calibre21\">Yes<\/td>\n<td class=\"calibre21\">Single<\/td>\n<td class=\"calibre21\">Value<\/td>\n<td class=\"calibre21\">Heap<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">struct<\/code> or <code class=\"calibre9\">record<\/code> <code class=\"calibre9\">struct<\/code><\/td>\n<td class=\"calibre21\">Yes<\/td>\n<td class=\"calibre21\">None<\/td>\n<td class=\"calibre21\">Value<\/td>\n<td class=\"calibre21\">Stack<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">interface<\/code><\/td>\n<td class=\"calibre21\">No<\/td>\n<td class=\"calibre21\">Multiple<\/td>\n<td class=\"calibre21\">Reference<\/td>\n<td class=\"calibre21\">Heap<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"rights\">It is best to think about these differences by starting with the \"normal\" case and then spotting the differences in other cases. For example, a \"normal\" <code class=\"calibre9\">class<\/code> can be instantiated with <code class=\"calibre9\">new<\/code>, it supports single inheritance, it uses memory reference equality, and its state is stored in heap memory.Now let's highlight what is different about the more specialized types of classes:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A <code class=\"calibre9\">sealed<\/code> class does not support inheritance.<\/li>\n<li class=\"calibre3\">An <code class=\"calibre9\">abstract<\/code> class does not allow instantiation with <code class=\"calibre9\">new<\/code>.<\/li>\n<li class=\"calibre3\">A <code class=\"calibre9\">record<\/code> class uses value equality instead of reference equality.<\/li>\n<\/ul>\n<p class=\"rights\">We can do the same for other types compared to a \"normal\" class:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A <code class=\"calibre9\">struct<\/code> or <code class=\"calibre9\">record struct<\/code> does not support inheritance, it uses value equality instead of reference equality, and its state is stored in stack memory.<\/li>\n<li class=\"calibre3\">An <code class=\"calibre9\">interface<\/code> does not allow instantiation with <code class=\"calibre9\">new<\/code> and supports multiple inheritance.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"7.12.2\" id=\"calibre_link-373\">\n<h3 data-number=\"7.12.2\" class=\"calibre8\">Mutability and records<\/h3>\n<p class=\"rights\">A common misconception is that <code class=\"calibre9\">record<\/code> types are immutable, meaning its instance property and field values cannot be changed after initialization. However, the mutability of a <code class=\"calibre9\">record<\/code> type actually depends on how the <code class=\"calibre9\">record<\/code> is defined. Let's explore mutability:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PacktLibrary<\/code> project, add a new class file named <code class=\"calibre9\">Mutability.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify <code class=\"calibre9\">Mutability.cs<\/code>, as shown in the following code, and note the following:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\n\/\/ A mutable record class.\npublic record class C1\n{\n  public string? Name { get; set; }\n}\n\/\/ An immutable record class.\npublic record class C2(string? Name);\n\/\/ A mutable record struct.\npublic record struct S1\n{\n  public string? Name { get; set; }\n}\n\/\/ Another mutable record struct.\npublic record struct S2(string? Name);\n\/\/ An immutable record struct.\npublic readonly record struct S3(string? Name);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">PeopleApp<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, create an instance of each type, setting the initial <code class=\"calibre9\">Name<\/code> value to <code class=\"calibre9\">Bob<\/code>, and then modify the <code class=\"calibre9\">Name<\/code> property to <code class=\"calibre9\">Bill<\/code>, you will see the two types that are immutable after initialization because they will give the compiler error <code class=\"calibre9\">CS8852<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">C1 c1 = new() { Name = \"Bob\" };\nc1.Name = \"Bill\";\nC2 c2 = new(Name: \"Bob\");\nc2.Name = \"Bill\"; \/\/ CS8852: Init-only property.\nS1 s1 = new() { Name = \"Bob\" };\ns1.Name = \"Bill\";\nS2 s2 = new(Name: \"Bob\");\ns2.Name = \"Bill\";\nS3 s3 = new(Name: \"Bob\");\ns3.Name = \"Bill\"; \/\/ CS8852: Init-only property.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note that record <code class=\"calibre9\">C1<\/code> is mutable and <code class=\"calibre9\">C2<\/code> is immutable. Note that <code class=\"calibre9\">S1<\/code> and <code class=\"calibre9\">S2<\/code> are mutable and <code class=\"calibre9\">S3<\/code> is immutable.<\/li>\n<li class=\"calibre3\">Comment out the two statements that cause compiler errors.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Microsoft made some interesting design choices with records. Make sure you remember the subtle differences in behavior when combining record, class, struct and using different types of declaration of each.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"7.12.3\" id=\"calibre_link-374\">\n<h3 data-number=\"7.12.3\" class=\"calibre8\">Comparing inheritance and implementation<\/h3>\n<p class=\"rights\">For me, the terms <em class=\"calibre10\">inherit<\/em> and <em class=\"calibre10\">implement<\/em> are different, and in the early days of C# and .NET you could strictly apply them to classes and interfaces respectfully. For example, the <code class=\"calibre9\">FileStream<\/code> class inherits from the <code class=\"calibre9\">Stream<\/code> class, and the <code class=\"calibre9\">Int32<\/code> <code class=\"calibre9\">struct<\/code> implements the <code class=\"calibre9\">IComparable<\/code> interface.<em class=\"calibre10\">Inherit<\/em> implies some functionality that a subclass gets \"for free\" by inheriting from its <strong class=\"calibre2\">base<\/strong> aka <strong class=\"calibre2\">super class<\/strong>. <em class=\"calibre10\">Implement<\/em> implies some functionality that is NOT inherited but instead MUST be provided by the subclass. This is why I chose to title this chapter <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>.Before C# 8, interfaces were always purely contracts. There was no functionality in an interface that you could inherit. In those days, you could strictly use the term <em class=\"calibre10\">implement<\/em> for interfaces that represent a list of members that your type must implement, and use the term <em class=\"calibre10\">inherit<\/em> for classes with functionality that your type can inherit and potentially override.With C# 8, interfaces can now include default implementations, making them more like abstract classes, and the term <em class=\"calibre10\">inherit<\/em> for an interface that has default implementations does make sense. But I feel uncomfortable with this capability, as do many other .NET developers because it messes up what used to be a clean language design. Default interfaces also require changes to the underlying .NET runtime, so they cannot be used with legacy platforms like .NET Standard 2.0 class libraries and .NET Framework.Classes can also have abstract members, for example, methods or properties without any implementation, just like an interface could have. When a subclass inherits from this class, it MUST provide an implementation of those abstract members, and the base class must be decorated with the <code class=\"calibre9\">abstract<\/code> keyword to prevent it from being instantiated using <code class=\"calibre9\">new<\/code> because it is missing some functionality.<\/p>\n<\/section>\n<section data-number=\"7.12.4\" id=\"calibre_link-375\">\n<h3 data-number=\"7.12.4\" class=\"calibre8\">Reviewing illustrative code<\/h3>\n<p class=\"rights\">Let's review some example code that illustrates some of the important differences between types. Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">To simplify the code, I have left out access modifiers like <code class=\"calibre9\">private<\/code> and <code class=\"calibre9\">public<\/code>.<\/li>\n<li class=\"calibre3\">Instead of normal brace formatting, to save vertical space I have put all the method implementation on one statement, for example:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">void M1() { \/* implementation *\/ }<\/code><\/pre>\n<\/div>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Using \"I\" as a prefix for interfaces is a convention, not a requirement. It is useful to highlight interfaces using this prefix, since only interfaces support multiple inheritance.<\/li>\n<\/ul>\n<p class=\"rights\">Here's the code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ These are both \"classic\" interfaces in that they are pure contracts.\n\/\/ They have no functionality, just the signatures of members that \n\/\/ must be implemented.\ninterface IAlpha \n{ \n  \/\/ A method that must be implemented in any type that implements \n  \/\/ this interface.\n  void M1();\n}\ninterface IBeta \n{\n  void M2(); \/\/ Another method.\n} \n\/\/ A type (a struct in this case) implementing an interface.\n\/\/ \": IAlpha\" means Gamma promises to implement all members of IAlpha.\nstruct Gamma : IAlpha\n{\n  void M1() { \/* implementation *\/ }\n}\n\/\/ A type (a class in this case) implementing two interfaces.\nclass Delta : IAlpha, IBeta \n{\n  void M1() { \/* implementation *\/ }\n  void M2() { \/* implementation *\/ }\n}\n\/\/ A sub class inheriting from a base aka super class.\n\/\/ \": Delta\" means inherit all members from Delta.\nclass Episilon : Delta\n{\n  \/\/ This can be empty because this inherits M1 and M2 from Delta.\n  \/\/ You could also add new members here.\n}\n\/\/ A class with one inheritable method and one abstract method \n\/\/ that must be implemented in sub classes. A class with at least \n\/\/ one abstract member must be decorated with the abstract keyword \n\/\/ to prevent instantiation.\nabstract class Zeta\n{\n  \/\/ An implemented method would be inherited.\n  void M3() { \/* implementation *\/ }\n  \/\/ A method that must be implemented in any type that inherits \n  \/\/ this abstract class.\n  abstract void M4();\n}\n\/\/ A class inheriting the M3 method from Zeta but it must provide \n\/\/ an implementation for M4.\nclass Eta : Zeta \n{\n  void M4() { \/* implementation *\/ } \n}\n\/\/ In C# 8 and later, interfaces can have default implementations \n\/\/ as well as members that must be implemented.\n\/\/ Requires: .NET Standard 2.1, .NET Core 3.0 or later.\ninterface ITheta \n{\n  void M3() { \/* implementation *\/ }\n  void M4();\n}\n\/\/ A class inheriting the default implementation from an interface \n\/\/ and must provide an implementation for M4.\nclass Iota : ITheta \n{\n  void M4() { \/* implementation *\/ }\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"7.13\" id=\"calibre_link-376\">\n<h2 data-number=\"7.13\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring this chapter's topics with more in-depth research.<\/p>\n<section data-number=\"7.13.1\" id=\"calibre_link-377\">\n<h3 data-number=\"7.13.1\" class=\"calibre8\">Exercise 6.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is a delegate?<\/li>\n<li class=\"calibre3\">What is an event?<\/li>\n<li class=\"calibre3\">How are a base class and a derived class related, and how can the derived class access the base class?<\/li>\n<li class=\"calibre3\">What is the difference between <code class=\"calibre9\">is<\/code> and <code class=\"calibre9\">as<\/code> operators?<\/li>\n<li class=\"calibre3\">Which keyword is used to prevent a class from being derived from or a method from being further overridden?<\/li>\n<li class=\"calibre3\">Which keyword is used to prevent a class from being instantiated with the <code class=\"calibre9\">new<\/code> keyword?<\/li>\n<li class=\"calibre3\">Which keyword is used to allow a member to be overridden?<\/li>\n<li class=\"calibre3\">What's the difference between a destructor and a deconstruct method?<\/li>\n<li class=\"calibre3\">What are the signatures of the constructors that all exceptions should have?<\/li>\n<li class=\"calibre3\">What is an extension method, and how do you define one?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"7.13.2\" id=\"calibre_link-378\">\n<h3 data-number=\"7.13.2\" class=\"calibre8\">Exercise 6.2 &ndash; Practice creating an inheritance hierarchy<\/h3>\n<p class=\"rights\">Explore inheritance hierarchies by following these steps:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a new console app named <code class=\"calibre9\">Ch06Ex02Inheritance<\/code> to your <code class=\"calibre9\">Chapter06<\/code> solution.<\/li>\n<li class=\"calibre3\">Create a class named <code class=\"calibre9\">Shape<\/code> with properties named <code class=\"calibre9\">Height<\/code>, <code class=\"calibre9\">Width<\/code>, and <code class=\"calibre9\">Area<\/code>.<\/li>\n<li class=\"calibre3\">Add three classes that derive from it - <code class=\"calibre9\">Rectangle<\/code>, <code class=\"calibre9\">Square<\/code>, and <code class=\"calibre9\">Circle<\/code>&mdash;with any additional members you feel are appropriate and that override and implement the <code class=\"calibre9\">Area<\/code> property correctly.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to create one instance of each shape, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Rectangle r = new(height: 3, width: 4.5);\nWriteLine($\"Rectangle H: {r.Height}, W: {r.Width}, Area: {r.Area}\");\nSquare s = new(5);\nWriteLine($\"Square H: {s.Height}, W: {s.Width}, Area: {s.Area}\");\nCircle c = new(radius: 2.5);\nWriteLine($\"Circle H: {c.Height}, W: {c.Width}, Area: {c.Area}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app and ensure that the result looks like the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Rectangle H: 3, W: 4.5, Area: 13.5\nSquare H: 5, W: 5, Area: 25\nCircle H: 5, W: 5, Area: 19.6349540849362<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"7.13.3\" id=\"calibre_link-379\">\n<h3 data-number=\"7.13.3\" class=\"calibre8\">Exercise 6.3 &ndash; Writing better code<\/h3>\n<p class=\"rights\">Read the following online-only section to learn how to use analyzers to write better code: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch06-writing-better-code.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch06-writing-better-code.md<\/a>.<\/p>\n<\/section>\n<section data-number=\"7.13.4\" id=\"calibre_link-380\">\n<h3 data-number=\"7.13.4\" class=\"calibre8\">Exercise 6.4 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more about the topics covered in this chapter:<\/p>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-6---implementing-interfaces-and-inheriting-classes\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-6---implementing-interfaces-and-inheriting-classes<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"7.14\" id=\"calibre_link-381\">\n<h2 data-number=\"7.14\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned about:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Operators<\/li>\n<li class=\"calibre3\">Generic types<\/li>\n<li class=\"calibre3\">Delegates and events<\/li>\n<li class=\"calibre3\">Implementing interfaces<\/li>\n<li class=\"calibre3\">Memory usage differences between reference and value types<\/li>\n<li class=\"calibre3\">Working with null values<\/li>\n<li class=\"calibre3\">Deriving and casting types using inheritance<\/li>\n<li class=\"calibre3\">Base and derived classes, how to override a type member, and using polymorphism<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will learn how .NET is packaged and deployed, and in subsequent chapters, the types that it provides you with to implement common functionality, such as file handling and database access.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-935\">\n<div id=\"calibre_link-1933\" class=\"calibre1\">\n<section data-number=\"8\" id=\"calibre_link-382\">\n<h1 data-number=\"8\" class=\"title\">7 Packaging and Distributing .NET Types<\/h1>\n<section data-number=\"8.1\" id=\"calibre_link-383\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"8.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000002.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about how C# keywords are related to .NET types, and about the relationship between namespaces and assemblies. You'll become familiar with how to package and publish your .NET apps and libraries for cross-platform use. We also cover how to decompile .NET assemblies for learning purposes and why you cannot prevent others from decompiling your code.In an online-only section, <em class=\"calibre10\">Exercise 7.3 &ndash; Porting from .NET Framework to modern .NET<\/em>, you can learn how to use legacy .NET Framework libraries in .NET libraries and the possibility of porting legacy .NET Framework code bases to modern .NET. In another online-only section, <em class=\"calibre10\">Exercise 7.4 &ndash; Creating source generators<\/em>, you will learn how to create source generators that can dynamically add source code to your projects, a very powerful feature.This chapter covers the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The road to .NET 8<\/li>\n<li class=\"calibre3\">Understanding .NET components<\/li>\n<li class=\"calibre3\">Publishing your applications for deployment<\/li>\n<li class=\"calibre3\">Native ahead-of-time compilation<\/li>\n<li class=\"calibre3\">Decompiling .NET assemblies<\/li>\n<li class=\"calibre3\">Packaging your libraries for NuGet distribution<\/li>\n<li class=\"calibre3\">Working with preview features<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"8.2\" id=\"calibre_link-384\">\n<h2 data-number=\"8.2\" class=\"calibre5\">The road to .NET 8<\/h2>\n<p class=\"rights\">This part of the book is about the functionality in the <strong class=\"calibre2\">Base Class Library<\/strong> (<strong class=\"calibre2\">BCL<\/strong>) APIs provided by .NET and how to reuse functionality across all the different .NET platforms using .NET Standard.From .NET Core 2.0 onward, the support for a minimum of .NET Standard 2.0 is important because it provides many of the APIs that were missing from the first version of .NET Core. The 15 years' worth of libraries and applications that .NET Framework developers had available to them that are relevant for modern development have now been migrated to .NET and can run cross-platform on macOS and Linux variants, as well as on Windows..NET Standard 2.1 added about 3,000 new APIs. Some of those APIs need runtime changes that would break backward compatibility, so .NET Framework 4.8 only implements .NET Standard 2.0; .NET Core 3.0, Xamarin, Mono, and Unity implement .NET Standard 2.1..NET 5 removed the need for .NET Standard because all project types can now target a single version of .NET. The same applies to .NET 6 and later. Each version from .NET 5 onward is backward compatible with previous versions. This means a class library that targets .NET 5 can be used by any .NET 5 or later projects of any type. Now that .NET versions have been released with full support for mobile and desktop apps built using .NET MAUI, the need for .NET Standard has been further reduced.Since you might still need to create class libraries for legacy .NET Framework projects or legacy Xamarin mobile apps, there is still a need to create .NET Standard 2.0 class libraries. And currently, you must also use a .NET Standard 2.0 class library to create a source generator.To summarize the progress that .NET has made since the first version of .NET Core in 2016, I have compared the major .NET Core and modern .NET versions with the equivalent .NET Framework versions in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">.NET Core 1.x<\/strong>: Much smaller API compared to .NET Framework 4.6.1, which was the current version in March 2016.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">.NET Core 2.x<\/strong>: Reached API parity with .NET Framework 4.7.1 for modern APIs because they both implement .NET Standard 2.0.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">.NET Core 3.x<\/strong>: Larger API compared to .NET Framework for modern APIs because .NET Framework 4.8 does not implement .NET Standard 2.1.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">.NET 5<\/strong>: Even larger API compared to .NET Framework 4.8 for modern APIs, with much-improved performance.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">.NET 6<\/strong>: Continued improvements to performance and expanded APIs with optional support for mobile apps in .NET MAUI that was added in May 2022.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">.NET 7<\/strong>: Final unification with the support for mobile apps with .NET MAUI available as an optional workload. This book does not cover .NET MAUI development. Packt has multiple books that specialize in .NET MAUI, and you can find them by searching their website.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">.NET 8<\/strong>: Continues to improve the platform and should be used for all new development.<\/li>\n<\/ul>\n<section data-number=\"8.2.1\" id=\"calibre_link-385\">\n<h3 data-number=\"8.2.1\" class=\"calibre8\">.NET Core 1.0, June 2016<\/h3>\n<p class=\"rights\">Implemented an API suitable for building modern cross-platform apps, including web and cloud applications and services for Linux using ASP.NET Core.<\/p>\n<\/section>\n<section data-number=\"8.2.2\" id=\"calibre_link-386\">\n<h3 data-number=\"8.2.2\" class=\"calibre8\">.NET Core 1.1, November 2016<\/h3>\n<p class=\"rights\">Fixed bugs, increased the number of Linux distributions supported, supported .NET Standard 1.6, and improved performance, especially with ASP.NET Core for web apps and services.<\/p>\n<\/section>\n<section data-number=\"8.2.3\" id=\"calibre_link-387\">\n<h3 data-number=\"8.2.3\" class=\"calibre8\">.NET Core 2.0, August 2017<\/h3>\n<p class=\"rights\">Implemented .NET Standard 2.0, the ability to reference .NET Framework libraries, and added more performance improvements.<\/p>\n<\/section>\n<section data-number=\"8.2.4\" id=\"calibre_link-388\">\n<h3 data-number=\"8.2.4\" class=\"calibre8\">.NET Core 2.1, May 2018<\/h3>\n<p class=\"rights\">Focused on an extendable tooling system, added new types like <code class=\"calibre9\">Span&lt;T&gt;<\/code>, new APIs for cryptography and compression, a Windows Compatibility Pack with an additional 20,000 APIs to help port old Windows applications, Entity Framework Core value conversions, LINQ <code class=\"calibre9\">GroupBy<\/code> conversions, data seeding, query types, and even more performance improvements, including the topics listed in <em class=\"calibre10\">Table 7.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Spans<\/td>\n<td class=\"calibre21\">8<\/td>\n<td class=\"calibre21\">Working with spans, indexes, and ranges<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Brotli compression<\/td>\n<td class=\"calibre21\">9<\/td>\n<td class=\"calibre21\">Compressing with the Brotli algorithm<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">EF Core lazy loading<\/td>\n<td class=\"calibre21\">10<\/td>\n<td class=\"calibre21\">Enabling lazy loading<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">EF Core data seeding<\/td>\n<td class=\"calibre21\">10<\/td>\n<td class=\"calibre21\">Understanding data seeding<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.1: Features of .NET Core 2.1<br \/>\n<\/section>\n<section data-number=\"8.2.5\" id=\"calibre_link-389\">\n<h3 data-number=\"8.2.5\" class=\"calibre8\">.NET Core 2.2, December 2018<\/h3>\n<p class=\"rights\">Focused on diagnostic improvements for the runtime, optional tiered compilation, and added new features to ASP.NET Core and Entity Framework Core like spatial data support using types from the <strong class=\"calibre2\">NetTopologySuite<\/strong> (<strong class=\"calibre2\">NTS<\/strong>) library, query tags, and collections of owned entities.<\/p>\n<\/section>\n<section data-number=\"8.2.6\" id=\"calibre_link-390\">\n<h3 data-number=\"8.2.6\" class=\"calibre8\">.NET Core 3.0, September 2019<\/h3>\n<p class=\"rights\">Added support for building Windows desktop applications using Windows Forms (2001), <strong class=\"calibre2\">Windows Presentation Foundation<\/strong> (<strong class=\"calibre2\">WPF<\/strong>; 2006), and Entity Framework 6.3. Also introduced side-by-side and app-local deployments; a fast JSON reader; serial port access and other pinout access for <strong class=\"calibre2\">Internet of Things<\/strong> (<strong class=\"calibre2\">IoT<\/strong>) solutions; and tiered compilation by default, including the topics listed in <em class=\"calibre10\">Table 7.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Embedding .NET in-app<\/td>\n<td class=\"calibre21\">7<\/td>\n<td class=\"calibre21\">Publishing your applications for deployment<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Index and Range<\/td>\n<td class=\"calibre21\">8<\/td>\n<td class=\"calibre21\">Working with spans, indexes, and ranges<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Text.Json<\/code><\/td>\n<td class=\"calibre21\">9<\/td>\n<td class=\"calibre21\">High-performance JSON processing<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.2: Features of .NET Core 3.0<br \/>\n<\/section>\n<section data-number=\"8.2.7\" id=\"calibre_link-391\">\n<h3 data-number=\"8.2.7\" class=\"calibre8\">.NET Core 3.1, December 2019<\/h3>\n<p class=\"rights\">Added bug fixes and refinements so that it could be a <strong class=\"calibre2\">Long Term Support<\/strong> (<strong class=\"calibre2\">LTS<\/strong>) release.<\/p>\n<\/section>\n<section data-number=\"8.2.8\" id=\"calibre_link-392\">\n<h3 data-number=\"8.2.8\" class=\"calibre8\">.NET 5, November 2020<\/h3>\n<p class=\"rights\">Unified the various .NET platforms except mobile, refined the platform, and improved performance, including the topics listed in <em class=\"calibre10\">Table 7.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Half<\/code> type<\/td>\n<td class=\"calibre21\">8<\/td>\n<td class=\"calibre21\">Working with numbers<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Regular expression performance improvements<\/td>\n<td class=\"calibre21\">8<\/td>\n<td class=\"calibre21\">Regular expression performance improvements<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Text.Json<\/code> improvements<\/td>\n<td class=\"calibre21\">9<\/td>\n<td class=\"calibre21\">High-performance JSON processing<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">EF Core generated SQL<\/td>\n<td class=\"calibre21\">10<\/td>\n<td class=\"calibre21\">Getting the generated SQL<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">EF Core Filtered Include<\/td>\n<td class=\"calibre21\">10<\/td>\n<td class=\"calibre21\">Filtering included entities<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">EF Core <code class=\"calibre9\">Scaffold-DbContext<\/code> now singularizes using Humanizer<\/td>\n<td class=\"calibre21\">10<\/td>\n<td class=\"calibre21\">Scaffolding models using an existing database<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.3: Features of .NET 5<br \/>\n<\/section>\n<section data-number=\"8.2.9\" id=\"calibre_link-393\">\n<h3 data-number=\"8.2.9\" class=\"calibre8\">.NET 6, November 2021<\/h3>\n<p class=\"rights\">Added more features to EF Core for data management, new types for working with dates and times, and improved performance yet again, including the topics listed in <em class=\"calibre10\">Table 7.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Check .NET SDK status<\/td>\n<td class=\"calibre21\">7<\/td>\n<td class=\"calibre21\">Checking your .NET SDKs for updates<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Link trim mode as default<\/td>\n<td class=\"calibre21\">7<\/td>\n<td class=\"calibre21\">Reducing the size of apps using app trimming<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">EnsureCapacity<\/code> for <code class=\"calibre9\">List&lt;T&gt;<\/code><\/td>\n<td class=\"calibre21\">8<\/td>\n<td class=\"calibre21\">Improving performance by ensuring the capacity of a collection<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Low-level file API using <code class=\"calibre9\">RandomAccess<\/code><\/td>\n<td class=\"calibre21\">9<\/td>\n<td class=\"calibre21\">Reading and writing with random access handles<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">EF Core configuration conventions<\/td>\n<td class=\"calibre21\">10<\/td>\n<td class=\"calibre21\">Configuring preconvention models<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">New LINQ methods<\/td>\n<td class=\"calibre21\">11<\/td>\n<td class=\"calibre21\">Building LINQ expressions with the <code class=\"calibre9\">Enumerable<\/code> class<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">TryGetNonEnumeratedCount<\/code><\/td>\n<td class=\"calibre21\">11<\/td>\n<td class=\"calibre21\">Aggregating sequences<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.4: Features of .NET 6<br \/>\n<\/section>\n<section data-number=\"8.2.10\" id=\"calibre_link-394\">\n<h3 data-number=\"8.2.10\" class=\"calibre8\">.NET 7, November 2022<\/h3>\n<p class=\"rights\">Finally unified with the mobile platform, added more features like string syntax coloring and IntelliSense, support for creating and extracting Tar archives, and improving the performance of inserts and updates with EF Core, including the topics listed in <em class=\"calibre10\">Table 7.5<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[StringSyntax]<\/code> attribute<\/td>\n<td class=\"calibre21\">8<\/td>\n<td class=\"calibre21\">Activating regular expression syntax coloring<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[GeneratedRegex]<\/code> attribute<\/td>\n<td class=\"calibre21\">8<\/td>\n<td class=\"calibre21\">Improving regular expression performance with source generators<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Tar archive support<\/td>\n<td class=\"calibre21\">9<\/td>\n<td class=\"calibre21\">Exercise 9.3 &ndash; Working with Tar archives<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ExecuteUpdate<\/code> and <code class=\"calibre9\">ExecuteDelete<\/code><\/td>\n<td class=\"calibre21\">10<\/td>\n<td class=\"calibre21\">More efficient updates and deletes<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Order<\/code> and <code class=\"calibre9\">OrderDescending<\/code><\/td>\n<td class=\"calibre21\">11<\/td>\n<td class=\"calibre21\">Sorting by the item itself<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.5: Features of .NET 7<br \/>\n<\/section>\n<section data-number=\"8.2.11\" id=\"calibre_link-395\">\n<h3 data-number=\"8.2.11\" class=\"calibre8\">.NET 8, November 2023<\/h3>\n<p class=\"rights\">Improved native <strong class=\"calibre2\">AOT<\/strong> (<strong class=\"calibre2\">ahead-of-time<\/strong>) compilation support, and added some advanced features for library authors related to source generation, including the topics listed in <em class=\"calibre10\">Table 7.6<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Terminal logger for build output and changed default publish configuration<\/td>\n<td class=\"calibre21\">7<\/td>\n<td class=\"calibre21\">Managing projects using the dotnet CLI<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Simplified output paths<\/td>\n<td class=\"calibre21\">7<\/td>\n<td class=\"calibre21\">Controlling where build artifacts are created<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Improved native AOT support<\/td>\n<td class=\"calibre21\">7<\/td>\n<td class=\"calibre21\">Native ahead-of-time compilation<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">New <code class=\"calibre9\">Random<\/code> methods<\/td>\n<td class=\"calibre21\">8<\/td>\n<td class=\"calibre21\">Generating random numbers for games and similar apps<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">New array, collection, and span initialization syntax<\/td>\n<td class=\"calibre21\">8<\/td>\n<td class=\"calibre21\">Initializing collections using collection expressions<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Frozen collections<\/td>\n<td class=\"calibre21\">8<\/td>\n<td class=\"calibre21\">Read-only, immutable, and frozen collections<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">New data validation attributes<\/td>\n<td class=\"calibre21\">10<\/td>\n<td class=\"calibre21\">Using EF Core annotation attributes to define the model<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.6: Features of .NET 8<br \/>\n<\/section>\n<section data-number=\"8.2.12\" id=\"calibre_link-396\">\n<h3 data-number=\"8.2.12\" class=\"calibre8\">Checking your .NET SDKs for updates<\/h3>\n<p class=\"rights\">Introduced with .NET 6, Microsoft added a command to check the versions of .NET SDKs and runtimes that you have installed and warn you if any need updating. For example, enter the following command:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet sdk check<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You will see results, including the status of available updates, as shown in the following partial output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">.NET SDKs:\nVersion                         Status\n-----------------------------------------------------------------------------\n5.0.214                        .NET 5.0 is out of support.\n6.0.101                        Patch 6.0.119 is available.\n6.0.314                        Up to date.\n7.0.304                        Patch 7.0.305 is available.\n8.0.100                        Up to date.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: To maintain support from Microsoft, you must keep your .NET SDKs and .NET runtimes up to date with the latest patches.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"8.3\" id=\"calibre_link-397\">\n<h2 data-number=\"8.3\" class=\"calibre5\">Understanding .NET components<\/h2>\n<p class=\"rights\">.NET is made up of several pieces, which are shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Language compilers<\/strong>: These turn your source code written with languages such as C#, F#, and Visual Basic into <strong class=\"calibre2\">intermediate language<\/strong> (<strong class=\"calibre2\">IL<\/strong>) code stored in assemblies. With C# 6 and later, Microsoft switched to an open-source rewritten compiler known as <strong class=\"calibre2\">Roslyn<\/strong>, which is also used by Visual Basic.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Common Language Runtime<\/strong> (<strong class=\"calibre2\">CoreCLR<\/strong>): This runtime loads assemblies, compiles the IL code stored in them into native code instructions for your computer's CPU, and executes the code within an environment that manages resources such as threads and memory.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Base Class Libraries<\/strong> (<strong class=\"calibre2\">BCL or CoreFX<\/strong>): These are prebuilt assemblies of types packaged and distributed using NuGet for performing common tasks when building applications. You can use them to quickly build anything you want, rather like combining LEGO\u2122 pieces.<\/li>\n<\/ul>\n<section data-number=\"8.3.1\" id=\"calibre_link-398\">\n<h3 data-number=\"8.3.1\" class=\"calibre8\">Assemblies, NuGet packages, and namespaces<\/h3>\n<p class=\"rights\">An <strong class=\"calibre2\">assembly<\/strong> is where a type is stored in the filesystem. Assemblies are a mechanism for deploying code. For example, the <code class=\"calibre9\">System.Data.dll<\/code> assembly contains types for managing data. To use types in other assemblies, they must be referenced. Assemblies can be static (pre-created) or dynamic (generated at runtime). Dynamic assemblies are an advanced feature that we will not cover in this book. Assemblies can be compiled into a single file as a DLL (class library) or an EXE (console app).Assemblies are distributed as <strong class=\"calibre2\">NuGet packages<\/strong>, which are files that are downloadable from public online feeds and can contain multiple assemblies and other resources. You will also hear about <strong class=\"calibre2\">project SDKs<\/strong>, <strong class=\"calibre2\">workloads<\/strong>, and <strong class=\"calibre2\">platforms<\/strong>, which are combinations of NuGet packages.Microsoft's NuGet feed is found here: <a href=\"https:\/\/www.nuget.org\/\">https:\/\/www.nuget.org\/<\/a>.<\/p>\n<\/section>\n<section data-number=\"8.3.2\" id=\"calibre_link-399\">\n<h3 data-number=\"8.3.2\" class=\"calibre8\">What is a namespace?<\/h3>\n<p class=\"rights\">A namespace is the address of a type. Namespaces are a mechanism to uniquely identify a type by requiring a full address rather than just a short name. In the real world, <em class=\"calibre10\">Bob of 34 Sycamore Street<\/em> is different from <em class=\"calibre10\">Bob of 12 Willow Drive<\/em>.In .NET, the <code class=\"calibre9\">IActionFilter<\/code> interface of the <code class=\"calibre9\">System.Web.Mvc<\/code> namespace is different from the <code class=\"calibre9\">IActionFilter<\/code> interface of the <code class=\"calibre9\">System.Web.Http.Filters<\/code> namespace.<\/p>\n<\/section>\n<section data-number=\"8.3.3\" id=\"calibre_link-400\">\n<h3 data-number=\"8.3.3\" class=\"calibre8\">Dependent assemblies<\/h3>\n<p class=\"rights\">If an assembly is compiled as a class library and provides types for other assemblies to use, then it has the file extension <code class=\"calibre9\">.dll<\/code> (<strong class=\"calibre2\">dynamic link library<\/strong>), and it cannot be executed standalone.Likewise, if an assembly is compiled as an application, then it has the file extension <code class=\"calibre9\">.exe<\/code> (<strong class=\"calibre2\">executable<\/strong>) and can be executed standalone. Before .NET Core 3, console apps were compiled to <code class=\"calibre9\">.dll<\/code> files and had to be executed by the <code class=\"calibre9\">dotnet run<\/code> command or a host executable.Any assembly can reference one or more class library assemblies as dependencies, but you cannot have circular references. So, assembly <em class=\"calibre10\">B<\/em> cannot reference assembly <em class=\"calibre10\">A<\/em> if assembly <em class=\"calibre10\">A<\/em> already references assembly <em class=\"calibre10\">B<\/em>. The compiler will warn you if you attempt to add a dependency reference that would cause a circular reference. Circular references are often a warning sign of poor code design. If you are sure that you need a circular reference, then use an interface to solve it.<\/p>\n<\/section>\n<section data-number=\"8.3.4\" id=\"calibre_link-401\">\n<h3 data-number=\"8.3.4\" class=\"calibre8\">Microsoft .NET project SDKs<\/h3>\n<p class=\"rights\">By default, console applications have a dependency reference on the Microsoft .NET project SDK. This platform contains thousands of types in NuGet packages that almost all applications would need, such as the <code class=\"calibre9\">System.Int32<\/code> and <code class=\"calibre9\">System.String<\/code> types.When using .NET, you reference the dependency assemblies, NuGet packages, and platforms that your application needs in a project file.Let's explore the relationship between assemblies and namespaces:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to create a new project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">AssembliesAndNamespaces<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter07<\/code><\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Open <code class=\"calibre9\">AssembliesAndNamespaces.csproj<\/code> and note that it is a typical project file for a .NET application, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">After the <code class=\"calibre9\">&lt;PropertyGroup&gt;<\/code> section, add a new <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> section to statically import <code class=\"calibre9\">System.Console<\/code> for all C# files using the implicit usings .NET SDK feature, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"8.3.5\" id=\"calibre_link-402\">\n<h3 data-number=\"8.3.5\" class=\"calibre8\">Namespaces and types in assemblies<\/h3>\n<p class=\"rights\">Many common .NET types are in the <code class=\"calibre9\">System.Runtime.dll<\/code> assembly. There is not always a one-to-one mapping between assemblies and namespaces. A single assembly can contain many namespaces and a namespace can be defined in many assemblies. You can see the relationship between some assemblies and the namespaces that they supply types for, as shown in <em class=\"calibre10\">Table 7.7<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Assembly<\/td>\n<td class=\"calibre21\">Example namespaces<\/td>\n<td class=\"calibre21\">Example types<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Runtime.dll<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System<\/code> , <code class=\"calibre9\">System.Collections<\/code> , <code class=\"calibre9\">System.Collections.Generic<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Int32<\/code> , <code class=\"calibre9\">String<\/code> , <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Console.dll<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Console<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Threading.dll<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Threading<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Interlocked<\/code> , <code class=\"calibre9\">Monitor<\/code> , <code class=\"calibre9\">Mutex<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Xml.XDocument.dll<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Xml.Linq<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">XDocument<\/code> , <code class=\"calibre9\">XElement<\/code> , <code class=\"calibre9\">XNode<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.7: Examples of assemblies and their namespaces<br \/>\n<\/section>\n<section data-number=\"8.3.6\" id=\"calibre_link-403\">\n<h3 data-number=\"8.3.6\" class=\"calibre8\">NuGet packages<\/h3>\n<p class=\"rights\">.NET is split into a set of packages, distributed using a Microsoft-supported package management technology named NuGet. Each of these packages represents a single assembly of the same name. For example, the <code class=\"calibre9\">System.Collections<\/code> package contains the <code class=\"calibre9\">System.Collections.dll<\/code> assembly.The following are the benefits of packages:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Packages can be easily distributed on public feeds.<\/li>\n<li class=\"calibre3\">Packages can be reused.<\/li>\n<li class=\"calibre3\">Packages can ship on their own schedule.<\/li>\n<li class=\"calibre3\">Packages can be tested independently of other packages.<\/li>\n<li class=\"calibre3\">Packages can support different OSes and CPUs by including multiple versions of the same assembly built for different OSes and CPUs.<\/li>\n<li class=\"calibre3\">Packages can have dependencies specific to only one library.<\/li>\n<li class=\"calibre3\">Apps are smaller because unreferenced packages aren't part of the distribution. <em class=\"calibre10\">Table 7.8<\/em> lists some of the more important packages and their important types:<\/li>\n<\/ul>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Package<\/td>\n<td class=\"calibre21\">Important types<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Runtime<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Object<\/code> , <code class=\"calibre9\">String<\/code> , <code class=\"calibre9\">Int32<\/code> , <code class=\"calibre9\">Array<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Collections<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">List&lt;T&gt;<\/code> , <code class=\"calibre9\">Dictionary&lt;TKey, TValue&gt;<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Net.Http<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">HttpClient<\/code> , <code class=\"calibre9\">HttpResponseMessage<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.IO.FileSystem<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">File<\/code> , <code class=\"calibre9\">Directory<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Reflection<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Assembly<\/code> , <code class=\"calibre9\">TypeInfo<\/code> , <code class=\"calibre9\">MethodInfo<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.8: Some important packages and their important types<br \/>\n<\/section>\n<section data-number=\"8.3.7\" id=\"calibre_link-404\">\n<h3 data-number=\"8.3.7\" class=\"calibre8\">Understanding frameworks<\/h3>\n<p class=\"rights\">There is a two-way relationship between frameworks and packages. Packages define the APIs, while frameworks group packages. A framework without any packages would not define any APIs..NET packages each support a set of frameworks. For example, the <code class=\"calibre9\">System.IO.FileSystem<\/code> package version 4.3.0 supports the following frameworks:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">.NET Standard, version 1.3 or later.<\/li>\n<li class=\"calibre3\">.NET Framework, version 4.6 or later.<\/li>\n<li class=\"calibre3\">Six Mono and Xamarin platforms (for example, Xamarin.iOS).<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can read the details at the following link: <a href=\"https:\/\/www.nuget.org\/packages\/System.IO.FileSystem\/\">https:\/\/www.nuget.org\/packages\/System.IO.FileSystem\/ #supportedframeworks-body-tab<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"8.3.8\" id=\"calibre_link-405\">\n<h3 data-number=\"8.3.8\" class=\"calibre8\">Importing a namespace to use a type<\/h3>\n<p class=\"rights\">Let's explore how namespaces are related to assemblies and types:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">AssembliesAndNamespaces<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then enter the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">XDocument doc = new();<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Recent versions of code editors will often automatically add a namespace import statement to fix the problem I want you to see. Please delete the <code class=\"calibre9\">using<\/code> statement that your code editor writes for you.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the project and note the compiler error message, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CS0246 The type or namespace name 'XDocument' could not be found (are you missing a using directive or an assembly reference?)<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">XDocument<\/code> type is not recognized because we have not told the compiler what the namespace of the type is. Although this project already has a reference to the assembly that contains the type, we also need to either prefix the type name with its namespace, for example, <code class=\"calibre9\">System.Xml.Linq.XDocument<\/code>, or import the namespace.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Click inside the <code class=\"calibre9\">XDocument<\/code> class name. Your code editor displays a light bulb, showing that it recognizes the type and can automatically fix the problem for you.<\/li>\n<li class=\"calibre3\">Click the light bulb, and select <code class=\"calibre9\">using System.Xml.Linq;<\/code> from the menu.<\/li>\n<\/ol>\n<p class=\"rights\">This will <em class=\"calibre10\">import the namespace<\/em> by adding a <code class=\"calibre9\">using<\/code> statement to the top of the file. Once a namespace is imported at the top of a code file, then all the types within the namespace are available for use in that code file by just typing their name, without the type name needing to be fully qualified by prefixing it with its namespace.I like to add a comment after importing a namespace to remind me why I need to import that namespace, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Xml.Linq; \/\/ To use XDocument.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you do not comment your namespaces, you or other developers will not know why they are imported and might delete them, breaking the code. Or they might never delete imported namespaces \"just in case\" they are needed, potentially cluttering the code unnecessarily. This is why most modern code editors have features to remove unused namespaces. This technique also subconsciously trains you, while you are learning, to remember which namespace you need to import to use a particular type or extension method.<\/p>\n<\/section>\n<section data-number=\"8.3.9\" id=\"calibre_link-406\">\n<h3 data-number=\"8.3.9\" class=\"calibre8\">Relating C# keywords to .NET types<\/h3>\n<p class=\"rights\">One of the common questions I get from new C# programmers is, \"What is the difference between <code class=\"calibre9\">string<\/code> with a lowercase s and <code class=\"calibre9\">String<\/code> with an uppercase S?\"The short answer is easy: none. The long answer is that all C# keywords that represent types like <code class=\"calibre9\">string<\/code> or <code class=\"calibre9\">int<\/code> are aliases for a .NET type in a class library assembly.When you use the <code class=\"calibre9\">string<\/code> keyword, the compiler recognizes it as a <code class=\"calibre9\">System.String<\/code> type. When you use the <code class=\"calibre9\">int<\/code> type, the compiler recognizes it as a <code class=\"calibre9\">System.Int32<\/code> type.Let's see this in action with some code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, declare two variables to hold <code class=\"calibre9\">string<\/code> values, one using lowercase <code class=\"calibre9\">string<\/code> and one using uppercase <code class=\"calibre9\">String<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string s1 = \"Hello\"; \nString s2 = \"World\";\nWriteLine($\"{s1} {s2}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">AssembliesAndNamespaces<\/code> project and note that <code class=\"calibre9\">string<\/code> and <code class=\"calibre9\">String<\/code> both work and literally mean the same thing.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">AssembliesAndNamespaces.csproj<\/code>, add an entry to prevent the <code class=\"calibre9\">System<\/code> namespace from being globally imported, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Remove=\"System\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, and in the <strong class=\"calibre2\">Error List<\/strong> or <strong class=\"calibre2\">PROBLEMS<\/strong> window, note the compiler error message, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CS0246 The type or namespace name 'String' could not be found (are you missing a using directive or an assembly reference?)<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.cs<\/code>, import the <code class=\"calibre9\">System<\/code> namespace with a <code class=\"calibre9\">using<\/code> statement that will fix the error, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System; \/\/ To use String.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: When you have a choice, use the C# keyword instead of the actual type because the keywords do not need a namespace to be imported.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"8.3.10\" id=\"calibre_link-407\">\n<h3 data-number=\"8.3.10\" class=\"calibre8\">Mapping C# aliases to .NET types<\/h3>\n<p class=\"rights\"><em class=\"calibre10\">Table 7.9<\/em> shows the 18 C# type keywords along with their actual .NET types:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Keyword<\/td>\n<td class=\"calibre21\">.NET type<\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\">Keyword<\/td>\n<td class=\"calibre21\">.NET type<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">string<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.String<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">char<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Char<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">sbyte<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.SByte<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">byte<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Byte<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">short<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Int16<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">ushort<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.UInt16<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">int<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Int32<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">uint<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.UInt32<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">long<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Int64<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">ulong<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.UInt64<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">nint<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.IntPtr<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">nuint<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.UIntPtr<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">float<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Single<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">double<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Double<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">decimal<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Decimal<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">bool<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Boolean<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">object<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Object<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">dynamic<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">System.Dynamic.DynamicObject<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.9: C# type keywords and their actual .NET types<\/p>\n<p class=\"rights\">Other .NET programming language compilers can do the same thing. For example, the Visual Basic .NET language has a type named <code class=\"calibre9\">Integer<\/code>, which is its alias for <code class=\"calibre9\">System.Int32<\/code>.<\/p>\n<\/section>\n<section data-number=\"8.3.11\" id=\"calibre_link-408\">\n<h3 data-number=\"8.3.11\" class=\"calibre8\">Understanding native-sized integers<\/h3>\n<p class=\"rights\">C# 9 introduced the <code class=\"calibre9\">nint<\/code> and <code class=\"calibre9\">nuint<\/code> keyword aliases for <strong class=\"calibre2\">native-sized integers<\/strong>, meaning that the storage size for the integer value is platform-specific. They store a 32-bit integer in a 32-bit process and <code class=\"calibre9\">sizeof()<\/code> returns 4 bytes; they store a 64-bit integer in a 64-bit process and <code class=\"calibre9\">sizeof()<\/code> returns 8 bytes. The aliases represent pointers to the integer value in memory, which is why their .NET names are <code class=\"calibre9\">IntPtr<\/code> and <code class=\"calibre9\">UIntPtr<\/code>. The actual storage type will be either <code class=\"calibre9\">System.Int32<\/code> or <code class=\"calibre9\">System.Int64<\/code>, depending on the process.In a 64-bit process, the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine($\"Environment.Is64BitProcess = {Environment.Is64BitProcess}\");\nWriteLine($\"int.MaxValue = {int.MaxValue:N0}\");\nWriteLine($\"nint.MaxValue = {nint.MaxValue:N0}\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">produces this output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Environment.Is64BitProcess = True\nint.MaxValue = 2,147,483,647\nnint.MaxValue = 9,223,372,036,854,775,807<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"8.3.12\" id=\"calibre_link-409\">\n<h3 data-number=\"8.3.12\" class=\"calibre8\">Revealing the location of a type<\/h3>\n<p class=\"rights\">Code editors provide built-in documentation for .NET types. Let's start by making sure that you have the expected experience and then explore:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you are using Visual Studio 2022, then make sure you have disabled Source Link:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Tools<\/strong> | <strong class=\"calibre2\">Options<\/strong>.<\/li>\n<li class=\"calibre3\">In the search box, enter <code class=\"calibre9\">navigation in source<\/code>.<\/li>\n<li class=\"calibre3\">Select <strong class=\"calibre2\">Text Editor<\/strong> | <strong class=\"calibre2\">C#<\/strong> | <strong class=\"calibre2\">Advanced<\/strong>.<\/li>\n<li class=\"calibre3\">Clear the <strong class=\"calibre2\">Enable navigation to Source Link and Embedded sources<\/strong> checkbox, and then click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Right-click inside <code class=\"calibre9\">XDocument<\/code> and choose <strong class=\"calibre2\">Go to Definition<\/strong>.<\/li>\n<li class=\"calibre3\">Navigate to the top of the code file, expand the collapsed region, and note the assembly filename is <code class=\"calibre9\">System.Xml.XDocument.dll<\/code>, but the class is in the <code class=\"calibre9\">System.Xml.Linq<\/code> namespace, as shown in the following code and in <em class=\"calibre10\">Figure 7.1<\/em>:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Assembly System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\n\/\/ C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\8.0.0\\ref\\net8.0\\System.Runtime.dll\n#endregion<\/code><\/pre>\n<\/div>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 7.1: Assembly and namespace that contains the XDocument type\" height=\"740\" src=\"\/images\/cs12\/000154.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 7.1: Assembly and namespace that contains the XDocument type<\/figcaption><\/figure>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close the <strong class=\"calibre2\">XDocument [from metadata]<\/strong> tab.<\/li>\n<li class=\"calibre3\">Right-click inside <code class=\"calibre9\">string<\/code> or <code class=\"calibre9\">String<\/code> and choose <strong class=\"calibre2\">Go to Definition<\/strong>.<\/li>\n<li class=\"calibre3\">Navigate to the top of the code file, expand the collapsed region, and note the assembly filename is <code class=\"calibre9\">System.Runtime.dll<\/code> but the class is in the <code class=\"calibre9\">System<\/code> namespace.<\/li>\n<\/ol>\n<p class=\"rights\">Your code editor is technically lying to you. If you remember when we wrote code in <em class=\"calibre10\">Chapter 2<\/em>, <em class=\"calibre10\">Speaking C#<\/em>, when we revealed the extent of the C# vocabulary, we discovered that the <code class=\"calibre9\">System.Runtime.dll<\/code> assembly contains zero types.What the <code class=\"calibre9\">System.Runtime.dll<\/code> assembly does contain are type-forwarders. These are special types that appear to exist in an assembly but are implemented elsewhere. In this case, they are implemented deep inside the .NET runtime using highly optimized code.You might want to use a type-forwarder if you refactor a type to move it from its original assembly to a different one. Without defining a type-forwarder, any projects that reference the original assembly will not find the type in it and a runtime exception will be thrown. You can read more about this contrived example at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/assembly\/type-forwarding\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/assembly\/type-forwarding<\/a>.<\/p>\n<\/section>\n<section data-number=\"8.3.13\" id=\"calibre_link-410\">\n<h3 data-number=\"8.3.13\" class=\"calibre8\">Sharing code with legacy platforms using .NET Standard<\/h3>\n<p class=\"rights\">Before .NET Standard, there were <strong class=\"calibre2\">Portable Class Libraries<\/strong> (<strong class=\"calibre2\">PCLs<\/strong>). With PCLs, you could create a library of code and explicitly specify which platforms you want the library to support, such as Xamarin, Silverlight, and Windows 8. Your library could then use the intersection of APIs that are supported by the specified platforms.Microsoft realized that this was unsustainable, so they created .NET Standard&mdash;a single API that all future .NET platforms would support. There are older versions of .NET Standard, but .NET Standard 2.0 was an attempt to unify all important recent .NET platforms. .NET Standard 2.1 was released in late 2019 but only .NET Core 3.0 and that year's version of Xamarin support its new features. For the rest of this book, I will use the term .NET Standard to mean .NET Standard 2.0..NET Standard is like HTML5 in that they are both standards that a platform should support. Just as Google's Chrome browser and Microsoft's Edge browser implement the HTML5 standard, .NET Core, .NET Framework, and Xamarin all implement .NET Standard. If you want to create a library of types that will work across variants of legacy .NET, you can do so most easily with .NET Standard.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Since many of the API additions in .NET Standard 2.1 required runtime changes, and .NET Framework is Microsoft's legacy platform that needs to remain as unchanging as possible, .NET Framework 4.8 remained on .NET Standard 2.0 rather than implementing .NET Standard 2.1. If you need to support .NET Framework customers, then you should create class libraries on .NET Standard 2.0, even though it is not the latest and does not support all the recent language and BCL new features.<\/p>\n<\/blockquote>\n<p class=\"rights\">Your choice of which .NET Standard version to target comes down to a balance between maximizing platform support and available functionality. A lower version supports more platforms but has a smaller set of APIs. A higher version supports fewer platforms but has a larger set of APIs. Generally, you should choose the lowest version that supports all the APIs that you need.<\/p>\n<\/section>\n<section data-number=\"8.3.14\" id=\"calibre_link-411\">\n<h3 data-number=\"8.3.14\" class=\"calibre8\">Understanding defaults for class libraries with different SDKs<\/h3>\n<p class=\"rights\">When using the <code class=\"calibre9\">dotnet<\/code> SDK tool to create a class library, it might be useful to know which target framework will be used by default, as shown in <em class=\"calibre10\">Table 7.10<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">SDK<\/td>\n<td class=\"calibre21\">Default target framework for new class libraries<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">.NET Core 3.1<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">netstandard2.0<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">.NET 6<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">net6.0<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">.NET 7<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">net7.0<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">.NET 8<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">net8.0<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.10: .NET SDKs and their default target framework for new class libraries<\/p>\n<p class=\"rights\">Of course, just because a class library targets a specific version of .NET by default, it does not mean you cannot change it after creating a class library project using the default template.You can manually set the target framework to a value that supports the projects that need to reference that library, as shown in <em class=\"calibre10\">Table 7.11<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Class library target framework<\/td>\n<td class=\"calibre21\">Can be used by projects that target<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">netstandard2.0<\/code><\/td>\n<td class=\"calibre21\">.NET Framework 4.6.1 or later, .NET Core 2 or later, .NET 5 or later, Mono 5.4 or later, Xamarin.Android 8 or later, and Xamarin.iOS 10.14 or later.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">netstandard2.1<\/code><\/td>\n<td class=\"calibre21\">.NET Core 3 or later, .NET 5 or later, Mono 6.4 or later, Xamarin.Android 10 or later, and Xamarin.iOS 12.16 or later.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">net6.0<\/code><\/td>\n<td class=\"calibre21\">.NET 6 or later.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">net7.0<\/code><\/td>\n<td class=\"calibre21\">.NET 7 or later.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">net8.0<\/code><\/td>\n<td class=\"calibre21\">.NET 8 or later.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.11: Class library target frameworks and the projects that can use them<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Always check the target framework of a class library and then manually change it to something more appropriate if necessary. Make a conscious decision about what it should be rather than accepting the default.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"8.3.15\" id=\"calibre_link-412\">\n<h3 data-number=\"8.3.15\" class=\"calibre8\">Creating a .NET Standard class library<\/h3>\n<p class=\"rights\">We will create a class library using .NET Standard 2.0 so that it can be used across all important .NET legacy platforms and cross-platform on Windows, macOS, and Linux operating systems, while also having access to a wide set of .NET APIs:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Class Library<\/strong> \/ <code class=\"calibre9\">classlib<\/code> project named <code class=\"calibre9\">SharedLibrary<\/code> that targets .NET Standard 2.0 to the <code class=\"calibre9\">Chapter07<\/code> solution:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">If you use Visual Studio 2022, when prompted for the <strong class=\"calibre2\">Target Framework<\/strong>, select <strong class=\"calibre2\">.NET Standard 2.0<\/strong>, and then configure the startup project for the solution to the current selection.<\/li>\n<li class=\"calibre3\">If you use Visual Studio Code, include a switch to target .NET Standard 2.0, as shown in the following command:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new classlib -f netstandard2.0<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If you need to create types that use new features in .NET 8, as well as types that only use .NET Standard 2.0 features, then you can create two separate class libraries: one targeting .NET Standard 2.0 and one targeting .NET 8.<\/p>\n<\/blockquote>\n<p class=\"rights\">An alternative to manually creating two class libraries is to create one that supports <strong class=\"calibre2\">multi-targeting<\/strong>. If you would like me to add a section about multi-targeting to the next edition, please let me know. You can read about multi-targeting here: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/library-guidance\/cross-platform-targeting#multi-targeting\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/library-guidance\/cross-platform-targeting#multi-targeting<\/a>.<\/p>\n<\/section>\n<section data-number=\"8.3.16\" id=\"calibre_link-413\">\n<h3 data-number=\"8.3.16\" class=\"calibre8\">Controlling the .NET SDK<\/h3>\n<p class=\"rights\">By default, executing <code class=\"calibre9\">dotnet<\/code> commands uses the highest version installed .NET SDK. There may be times when you want to control which SDK is used.For example, once .NET 9 is available in preview starting in February 2024, or the final version in November 2024, you might install it. But you would probably want your experience to match the book steps that use the .NET 8 SDK. But once you install a .NET 9 SDK, then it will be used by default. You can control the .NET SDK used by default by using a <code class=\"calibre9\">global.json<\/code> file, which contains the version to use. The <code class=\"calibre9\">dotnet<\/code> command searches the current folder and then each ancestor folder in turn for a <code class=\"calibre9\">global.json<\/code> file to see if it should use a different .NET SDK version.You do not need to complete the following steps, but if you want to try and do not already have .NET 6 SDK installed, then you can install it from the following link:<a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet\/6.0\">https:\/\/dotnet.microsoft.com\/download\/dotnet\/6.0<\/a><\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Create a subdirectory\/folder in the <code class=\"calibre9\">Chapter07<\/code> folder named <code class=\"calibre9\">ControlSDK<\/code>.<\/li>\n<li class=\"calibre3\">On Windows, start <strong class=\"calibre2\">Command Prompt<\/strong> or <strong class=\"calibre2\">Windows Terminal<\/strong>. On macOS, start <strong class=\"calibre2\">Terminal<\/strong>. If you are using Visual Studio Code, then you can use the integrated terminal.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">ControlSDK<\/code> folder, at the command prompt or terminal, enter a command to list the installed .NET SDKs, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet --list-sdks<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the results and the version number of the latest .NET 6 SDK installed, as shown highlighted in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">5.0.214 [C:\\Program Files\\dotnet\\sdk]\n6.0.314 [C:\\Program Files\\dotnet\\sdk]\n7.0.304 [C:\\Program Files\\dotnet\\sdk]\n8.0.100 [C:\\Program Files\\dotnet\\sdk]<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Create a <code class=\"calibre9\">global.json<\/code> file that forces the use of the latest .NET Core 6.0 SDK that you have installed (which might be later than mine), as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new globaljson --sdk-version 6.0.314<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">The template \"global.json file\" was created successfully.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to open the <code class=\"calibre9\">global.json<\/code> file and review its contents, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"sdk\": {\n    \"version\": \"6.0.314\"\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">For example, to open it with Visual Studio Code, enter the command: <code class=\"calibre9\">code global.json<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">ControlSDK<\/code> folder, at the command prompt or terminal, enter a command to create a class library project, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new classlib<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you do not have the .NET 6 SDK installed, then you will see an error, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Could not execute because the application was not found or a compatible .NET SDK is not installed.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you do have the .NET 6 SDK installed, then a class library project will be created that targets .NET 6 by default, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;TargetFramework&gt;net6.0&lt;\/TargetFramework&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"8.3.17\" id=\"calibre_link-414\">\n<h3 data-number=\"8.3.17\" class=\"calibre8\">Mixing SDKs and framework targets<\/h3>\n<p class=\"rights\">Many organizations decide to target a long-term support version of .NET to get up to three years of support from Microsoft. Doing this does not mean you lose the benefits of improvements to the C# language during the lifetime of the .NET runtime that you need to target.You can easily continue to target the .NET 8 runtime while installing and using future C# compilers, as shown in <em class=\"calibre10\">Figure 7.2<\/em> and illustrated in the following list:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\"><strong class=\"calibre2\">November 2023<\/strong>: Install .NET SDK 8.0.100 and use it to build projects that target .NET 8 and use the C# 12 compiler by default. Every month, update to .NET 8 SDK patches on the development computer and update to .NET 8 runtime patches on any deployment computers.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">February 2024<\/strong>: Optionally, install .NET SDK 9 Preview 1 to explore the new C# language and .NET library features. Note that you won't be able to use new library features while targeting .NET 8. Previews are released monthly between February and October each year. Read the monthly announcement blog posts to find out about the new features in that preview.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">November 2024<\/strong>: Install .NET SDK 9.0.100 and use it to build projects that continue to target .NET 8 and use the C# 13 compiler for its new features. You will be using a fully supported SDK and fully supported runtime. You can also use new features in EF Core 9 because it will continue to target .NET 8.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">February 2025<\/strong>: Optionally, install .NET 10 previews to explore new C# language and .NET library features. Start planning if any new library and ASP.NET Core features in .NET 9 and .NET 10 can be applied to your .NET 8 projects when you are ready to migrate.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">November 2025<\/strong>: Install .NET 10.0.100 SDK and use it to build projects that target .NET 8 and use the C# 14 compiler. Migrate your .NET 8 projects to .NET 10 since it is an LTS release. You have until November 2026 to complete the migration when .NET 8 reaches end-of-life.<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 7.2: Targeting .NET 8 for long-term support while using the latest C# compilers\" height=\"1099\" src=\"\/images\/cs12\/000138.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 7.2: Targeting .NET 8 for long-term support while using the latest C# compilers<\/figcaption><\/figure>\n<p class=\"rights\">When deciding to install a .NET SDK, remember that the latest is used by default to build any .NET projects. Once you've installed a .NET 9 SDK preview, it will be used by default for all projects, unless you force the use of an older, fully supported SDK version like 8.0.100 or a later patch.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"8.4\" id=\"calibre_link-415\">\n<h2 data-number=\"8.4\" class=\"calibre5\">Publishing your code for deployment<\/h2>\n<p class=\"rights\">If you write a novel and you want other people to read it, you must publish it.Most developers write code for other developers to use in their own projects, or for users to run as an app. To do so, you must publish your code as packaged class libraries or executable applications.There are three ways to publish and deploy a .NET application. They are:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Framework-dependent deployment<\/strong> (<strong class=\"calibre2\">FDD<\/strong>)<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Framework-dependent executable<\/strong> (<strong class=\"calibre2\">FDE<\/strong>)<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Self-contained<\/strong><\/li>\n<\/ul>\n<p class=\"rights\">If you choose to deploy your application and its package dependencies, but not .NET itself, then you rely on .NET already being on the target computer. This works well for web applications deployed to a server because .NET and lots of other web applications are likely already on the server.FDD means you deploy a DLL that must be executed by the <code class=\"calibre9\">dotnet<\/code> command-line tool. FDE means you deploy an EXE that can be run directly from the command line. Both require the appropriate version of the .NET runtime to be installed on the system.Sometimes, you want to be able to give someone a USB stick containing your application built for their operating system and know that it can execute on their computer. You would want to perform a self-contained deployment. While the size of the deployment files will be larger, you'll know that it will work.<\/p>\n<section data-number=\"8.4.1\" id=\"calibre_link-416\">\n<h3 data-number=\"8.4.1\" class=\"calibre8\">Creating a console app to publish<\/h3>\n<p class=\"rights\">Let's explore how to publish a console app:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">DotNetEverywhere<\/code> to the <code class=\"calibre9\">Chapter07<\/code> solution. Make sure you target .NET 8.<\/li>\n<li class=\"calibre3\">Modify the project file to statically import the <code class=\"calibre9\">System.Console<\/code> class in all C# files.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, and then add a statement to output a message saying the console app can run everywhere and some information about the operating system, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(\"I can run everywhere!\");\nWriteLine($\"OS Version is {Environment.OSVersion}.\");\nif (OperatingSystem.IsMacOS())\n{\n  WriteLine(\"I am macOS.\");\n}\nelse if (OperatingSystem.IsWindowsVersionAtLeast(major: 10, build: 22000))\n{\n  WriteLine(\"I am Windows 11.\");\n}\nelse if (OperatingSystem.IsWindowsVersionAtLeast(major: 10))\n{\n  WriteLine(\"I am Windows 10.\");\n}\nelse\n{\n  WriteLine(\"I am some other mysterious OS.\");\n}\nWriteLine(\"Press any key to stop me.\");\nReadKey(intercept: true); \/\/ Do not output the key that was pressed.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">DotNetEverywhere<\/code> project and note the results when run on Windows 11, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">I can run everywhere!\nOS Version is Microsoft Windows NT 10.0.22000.0.\nI am Windows 11.\nPress any key to stop me.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">DotNetEverywhere.csproj<\/code>, add the <strong class=\"calibre2\">runtime identifiers (RIDs)<\/strong> to target three operating systems inside the <code class=\"calibre9\">&lt;PropertyGroup&gt;<\/code> element, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n    &lt;RuntimeIdentifiers&gt;\n      win10-x64;osx-x64;osx.11.0-arm64;linux-x64;linux-arm64\n    &lt;\/RuntimeIdentifiers&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The <code class=\"calibre9\">win10-x64<\/code> RID value means Windows 10 or Windows Server 2016 64-bit. You could also use the <code class=\"calibre9\">win10-arm64<\/code> RID value to deploy to a Microsoft Surface Pro X.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">osx-x64<\/code> RID value means macOS Sierra 10.12 or later. You can also specify version-specific RID values like <code class=\"calibre9\">osx.10.15-x64<\/code> (Catalina), <code class=\"calibre9\">osx.11.0-x64<\/code> (Big Sur on Intel), or <code class=\"calibre9\">osx.11.0-arm64<\/code> (Big Sur on Apple Silicon).<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">linux-x64<\/code> RID value means most desktop distributions of Linux, like Ubuntu, CentOS, Debian, or Fedora. Use <code class=\"calibre9\">linux-arm<\/code> for Raspbian or Raspberry Pi OS 32-bit. Use <code class=\"calibre9\">linux-arm64<\/code> for a Raspberry Pi running Ubuntu 64-bit.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">There are two elements that you can use to specify runtime identifiers. Use <code class=\"calibre9\">&lt;RuntimeIdentifier&gt;<\/code> if you only need to specify one. Use <code class=\"calibre9\">&lt;RuntimeIdentifiers&gt;<\/code> if you need to specify multiple, as we did in the preceding example. If you use the wrong one, then the compiler will give an error and it can be difficult to understand why with only one character difference!<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"8.4.2\" id=\"calibre_link-417\">\n<h3 data-number=\"8.4.2\" class=\"calibre8\">Understanding dotnet commands<\/h3>\n<p class=\"rights\">When you install the .NET SDK, it includes a <strong class=\"calibre2\">command-line interface<\/strong> (<strong class=\"calibre2\">CLI<\/strong>) named <code class=\"calibre9\">dotnet<\/code>.The .NET CLI has commands that work on the current folder to create a new project using templates:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">On Windows, start <strong class=\"calibre2\">Command Prompt<\/strong> or <strong class=\"calibre2\">Windows Terminal<\/strong>. On macOS, start <strong class=\"calibre2\">Terminal<\/strong>. If you prefer to use Visual Studio 2022 or Visual Studio Code, then you can use the integrated terminal.<\/li>\n<li class=\"calibre3\">Enter the <code class=\"calibre9\">dotnet new list<\/code> (or <code class=\"calibre9\">dotnet new -l<\/code> or <code class=\"calibre9\">dotnet new --list<\/code> with older SDKs) command to list your currently installed templates, the most common of which are shown in <em class=\"calibre10\">Table 7.12<\/em>:<\/li>\n<\/ol>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Template Name<\/td>\n<td class=\"calibre21\">Short Name<\/td>\n<td class=\"calibre21\">Language<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">.NET MAUI App<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">maui<\/code><\/td>\n<td class=\"calibre21\">C#<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">.NET MAUI Blazor App<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">maui-blazor<\/code><\/td>\n<td class=\"calibre21\">C#<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ASP.NET Core Empty<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">web<\/code><\/td>\n<td class=\"calibre21\">C#, F#<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ASP.NET Core gRPC Service<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">grpc<\/code><\/td>\n<td class=\"calibre21\">C#<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ASP.NET Core Web API<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">webapi<\/code><\/td>\n<td class=\"calibre21\">C#, F#<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ASP.NET Core Web API (native AOT)<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">api<\/code><\/td>\n<td class=\"calibre21\">C#<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ASP.NET Core Web App (Model-View-Controller)<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">mvc<\/code><\/td>\n<td class=\"calibre21\">C#, F#<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Blazor Web App<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">blazor<\/code><\/td>\n<td class=\"calibre21\">C#<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Class Library<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">classlib<\/code><\/td>\n<td class=\"calibre21\">C#, F#, VB<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Console App<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">console<\/code><\/td>\n<td class=\"calibre21\">C#, F#, VB<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">EditorConfig<\/code> File<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">editorconfig<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">global.json<\/code> File<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">globaljson<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Solution File<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">sln<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">xUnit Test Project<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">xunit<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.12: Project template full and short names<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">.NET MAUI projects are not supported for Linux. The team has said they have left that work to the open source community. If you need to create a truly cross-platform graphical app, then take a look at Avalonia at the following link: <a href=\"https:\/\/avaloniaui.net\/\">https:\/\/avaloniaui.net\/<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"8.4.3\" id=\"calibre_link-418\">\n<h3 data-number=\"8.4.3\" class=\"calibre8\">Getting information about .NET and its environment<\/h3>\n<p class=\"rights\">It is useful to see what .NET SDKs and runtimes are currently installed, alongside information about the operating system, as shown in the following command:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet --info<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the results, as shown in the following partial output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">.NET SDK (reflecting any global.json):\n Version:   8.0.100\n Commit:    3fe444af72\nRuntime Environment:\n OS Name:     Windows\n OS Version:  10.0.22621\n OS Platform: Windows\n RID:         win10-x64\n Base Path:   C:\\Program Files\\dotnet\\sdk\\8.0.100\\\n.NET workloads installed:\nThere are no installed workloads to display.\nHost (useful for support):\n  Version: 8.0.0\n  Commit:  bc78804f5d\n.NET SDKs installed:\n  5.0.214 [C:\\Program Files\\dotnet\\sdk]\n  6.0.317 [C:\\Program Files\\dotnet\\sdk]\n  7.0.401 [C:\\Program Files\\dotnet\\sdk]\n  8.0.100 [C:\\Program Files\\dotnet\\sdk]\n.NET runtimes installed:\n  Microsoft.AspNetCore.App 5.0.17 [...\\dotnet\\shared\\Microsoft.AspNetCore.All]\n...<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"8.4.4\" id=\"calibre_link-419\">\n<h3 data-number=\"8.4.4\" class=\"calibre8\">Managing projects using the dotnet CLI<\/h3>\n<p class=\"rights\">The .NET CLI has the following commands that work on the project in the current folder, to manage the project:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet help<\/code>: This shows the command-line help.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet new<\/code>: This creates a new .NET project or file.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet tool<\/code>: This installs or manages tools that extend the .NET experience.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet workload<\/code>: This manages optional workloads like .NET MAUI.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet restore<\/code>: This downloads dependencies for the project.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet build<\/code>: This builds, aka compiles, a .NET project. A new switch introduced with .NET 8 is <code class=\"calibre9\">--tl<\/code> (meaning terminal logger), which provides a modern output. For example, it provides real-time information about what the build is doing. You can learn more at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/tools\/dotnet-build#options\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/tools\/dotnet-build#options<\/a>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet build-server<\/code>: This interacts with servers started by a build.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet msbuild<\/code>: This runs MS Build Engine commands.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet clean<\/code>: This removes the temporary outputs from a build.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet test<\/code>: This builds and then runs unit tests for the project.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet run<\/code>: This builds and then runs the project.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet pack<\/code>: This creates a NuGet package for the project.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet publish<\/code>: This builds and then publishes the project, either with dependencies or as a self-contained application. In .NET 7 and earlier, this published the <code class=\"calibre9\">Debug<\/code> configuration by default. In .NET 8 and later, it now publishes the <code class=\"calibre9\">Release<\/code> configuration by default.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet add<\/code>: This adds a reference to a package or class library to the project.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet remove<\/code>: This removes a reference to a package or class library from the project.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">dotnet list<\/code>: This lists the package or class library references for the project.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"8.4.5\" id=\"calibre_link-420\">\n<h3 data-number=\"8.4.5\" class=\"calibre8\">Publishing a self-contained app<\/h3>\n<p class=\"rights\">Now that you have seen some example <code class=\"calibre9\">dotnet<\/code> tool commands, we can publish our cross-platform console app:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the command prompt or terminal, make sure that you are in the <code class=\"calibre9\">DotNetEverywhere<\/code> folder.<\/li>\n<li class=\"calibre3\">Enter a command to build and publish the self-contained release version of the console application for Windows 10, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet publish -c Release -r win10-x64 --self-contained<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the build engine restores any needed packages, compiles the project source code into an assembly DLL, and creates a <code class=\"calibre9\">publish<\/code> folder, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">MSBuild version 17.8.0+14c24b2d3 for .NET\n  Determining projects to restore...\n  All projects are up-to-date for restore.\n  DotNetEverywhere -&gt; C:\\cs12dotnet8\\Chapter07\\DotNetEverywhere\\bin\\Release\\net8.0\\win10-x64\\DotNetEverywhere.dll\n  DotNetEverywhere -&gt; C:\\cs12dotnet8\\Chapter07\\DotNetEverywhere\\bin\\Release\\net8.0\\win10-x64\\publish\\<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Enter the following commands to build and publish the release versions for macOS and Linux variants:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet publish -c Release -r osx-x64 --self-contained\ndotnet publish -c Release -r osx.11.0-arm64 --self-contained\ndotnet publish -c Release -r linux-x64 --self-contained\ndotnet publish -c Release -r linux-arm64 --self-contained<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You could automate these commands by using a scripting language like PowerShell and execute the script file on any operating system using the cross-platform PowerShell Core. I have done this for you at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/scripts\/publish-scripts\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/scripts\/publish-scripts<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Open Windows <strong class=\"calibre2\">File Explorer<\/strong> or a macOS <strong class=\"calibre2\">Finder<\/strong> window, navigate to <code class=\"calibre9\">DotNetEverywhere\\bin\\Release\\net8.0<\/code>, and note the output folders for the five operating systems.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">win10-x64<\/code> folder, open the <code class=\"calibre9\">publish<\/code> folder, and note all the supporting assemblies, like <code class=\"calibre9\">Microsoft.CSharp.dll<\/code>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Select the <code class=\"calibre9\">DotNetEverywhere<\/code> executable file, and note it is 154 KB, as shown in <em class=\"calibre10\">Figure 7.3<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 7.3: The DotNetEverywhere executable file for Windows 10 64-bit\" height=\"619\" src=\"\/images\/cs12\/000070.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 7.3: The DotNetEverywhere executable file for Windows 10 64-bit<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">If you are on Windows, then double-click to execute the program and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">I can run everywhere!\nOS Version is Microsoft Windows NT 10.0.22621.0.\nI am Windows 11.\nPress any key to stop me.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Press any key to close the console app and its window.<\/li>\n<li class=\"calibre3\">Note that the total size of the <code class=\"calibre9\">publish<\/code> folder and all its files is 68.3 MB.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">osx.11.0-arm64<\/code> folder, select the <code class=\"calibre9\">publish<\/code> folder, note all the supporting assemblies, and then select the <code class=\"calibre9\">DotNetEverywhere<\/code> executable file. Note that the executable is 125 KB, and the <code class=\"calibre9\">publish<\/code> folder is about 73.9 MB. There is no <code class=\"calibre9\">.exe<\/code> file extension for published applications on macOS, so the filename will not have an extension.<\/li>\n<\/ol>\n<p class=\"rights\">If you copy any of those <code class=\"calibre9\">publish<\/code> folders to the appropriate operating system, the console app will run; this is because it is a self-contained deployable .NET application. For example, here it is on macOS with Intel:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">I can run everywhere!\nOS Version is Unix 13.5.2\nI am macOS.\nPress any key to stop me.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This example used a console app, but you could just as easily create an ASP.NET Core website or web service, or a Windows Forms or WPF app. Of course, you can only deploy Windows desktop apps to Windows computers, not Linux or macOS.<\/p>\n<\/section>\n<section data-number=\"8.4.6\" id=\"calibre_link-421\">\n<h3 data-number=\"8.4.6\" class=\"calibre8\">Publishing a single-file app<\/h3>\n<p class=\"rights\">If you can assume that .NET is already installed on the computer on which you want to run your app, then you can use the extra flags when you publish your app for release to say that it does not need to be self-contained and that you want to publish it as a single file (if possible), as shown in the following command (which must be entered on a single line):<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet publish -r win10-x64 -c Release --no-self-contained\n\/p:PublishSingleFile=true<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This will generate two files: <code class=\"calibre9\">DotNetEverywhere.exe<\/code> and <code class=\"calibre9\">DotNetEverywhere.pdb<\/code>. The <code class=\"calibre9\">.exe<\/code> file is the executable. The <code class=\"calibre9\">.pdb<\/code> file is a <strong class=\"calibre2\">program debug database<\/strong> file that stores debugging information.If you prefer the <code class=\"calibre9\">.pdb<\/code> file to be embedded in the <code class=\"calibre9\">.exe<\/code> file, for example, to ensure it is deployed with its assembly, then add a <code class=\"calibre9\">&lt;DebugType&gt;<\/code> element to the <code class=\"calibre9\">&lt;PropertyGroup&gt;<\/code> element in your <code class=\"calibre9\">.csproj<\/code> file and set it to <code class=\"calibre9\">embedded<\/code>, as shown highlighted in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PropertyGroup&gt;\n  &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n  &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n  &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n  &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n  &lt;RuntimeIdentifiers&gt;\n    win10-x64;osx-x64;osx.11.0-arm64;linux-x64;linux-arm64\n  &lt;\/RuntimeIdentifiers&gt;\n  &lt;DebugType&gt;embedded&lt;\/DebugType&gt;\n&lt;\/PropertyGroup&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you cannot assume that .NET is already installed on a computer, then although Linux also only generates the two files, expect the following additional files for Windows: <code class=\"calibre9\">coreclr.dll<\/code>, <code class=\"calibre9\">clrjit.dll<\/code>, <code class=\"calibre9\">clrcompression.dll<\/code>, and <code class=\"calibre9\">mscordaccore.dll<\/code>.Let's see an example for Windows:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the command prompt or terminal, in the <code class=\"calibre9\">DotNetEverywhere<\/code> folder, enter the command to build the self-contained release version of the console app for Windows 10, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet publish -c Release -r win10-x64 --self-contained \/p:PublishSingleFile=true<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to the <code class=\"calibre9\">DotNetEverywhere\\bin\\Release\\net8.0\\win10-x64\\publish<\/code> folder and select the <code class=\"calibre9\">DotNetEverywhere<\/code> executable file. Note that the executable is now 62.6 MB, and there is also a <code class=\"calibre9\">.pdb<\/code> file that is 11 KB. The sizes of these files on your system will vary.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"8.4.7\" id=\"calibre_link-422\">\n<h3 data-number=\"8.4.7\" class=\"calibre8\">Reducing the size of apps using app trimming<\/h3>\n<p class=\"rights\">One of the problems with deploying a .NET app as a self-contained app is that the .NET libraries take up a lot of space. One of the biggest needs is to reduce the size of Blazor WebAssembly components because all the .NET libraries need to be downloaded to the browser.Luckily, you can reduce this size by not packaging unused assemblies with your deployments. Introduced with .NET Core 3, the app trimming system can identify the assemblies needed by your code and remove those that are not needed. This was known as <code class=\"calibre9\">copyused<\/code> trim mode.With .NET 5, the trimming went further by removing individual types, and even members, like methods from within an assembly if they are not used. For example, with a <strong class=\"calibre2\">Hello World<\/strong> console app, the <code class=\"calibre9\">System.Console.dll<\/code> assembly is trimmed from 61.5 KB to 31.5 KB. This was known as <code class=\"calibre9\">link<\/code> trim mode, but it was not enabled by default.With .NET 6, Microsoft added annotations to their libraries to indicate how they can be safely trimmed so the trimming of types and members was made the default.With .NET 7, Microsoft renamed <code class=\"calibre9\">link<\/code> to <code class=\"calibre9\">full<\/code> and <code class=\"calibre9\">copyused<\/code> to <code class=\"calibre9\">partial<\/code>.The catch is how well the trimming identifies unused assemblies, types, and members. If your code is dynamic, perhaps using reflection, then it might not work correctly, so Microsoft also allows manual control.There are two ways to enable type-level and member-level, aka <code class=\"calibre9\">full<\/code>, trimming. Since this level of trimming is the default with .NET 6 or later, all we need to do is enable trimming without setting a trim level or mode.The first way is to add an element in the project file, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PublishTrimmed&gt;true&lt;\/PublishTrimmed&gt; &lt;!--Enable trimming.--&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The second way is to add a flag when publishing, as shown highlighted in the following command:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet publish ... -p:PublishTrimmed=True<\/code><\/pre>\n<\/div>\n<p class=\"rights\">There are two ways to enable assembly-level, aka <code class=\"calibre9\">partial<\/code>, trimming.The first way is to add two elements in the project file, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PublishTrimmed&gt;true&lt;\/PublishTrimmed&gt; &lt;!--Enable trimming.--&gt;\n&lt;TrimMode&gt;partial&lt;\/TrimMode&gt; &lt;!--Set assembly-level trimming.--&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The second way is to add two flags when publishing, as shown highlighted in the following command:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet publish ... -p:PublishTrimmed=True -p:TrimMode=partial<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"8.4.8\" id=\"calibre_link-423\">\n<h3 data-number=\"8.4.8\" class=\"calibre8\">Controlling where build artifacts are created<\/h3>\n<p class=\"rights\">Traditionally, each project has its own <code class=\"calibre9\">bin<\/code> and <code class=\"calibre9\">obj<\/code> subfolders where temporary files are created during the build process. When you publish, the files are created in the <code class=\"calibre9\">bin<\/code> folder.You might prefer to put all these temporary files and folders somewhere else. Introduced with .NET 8 is the ability to control where build artifacts are created. Let's see how:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the command prompt or terminal for the <code class=\"calibre9\">Chapter07<\/code> folder, enter the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new buildprops --use-artifacts<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the success message, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">The template \"MSBuild Directory.Build.props file\" was created successfully.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">We could have created this file in the <code class=\"calibre9\">cs12dotnet8<\/code> folder, and it would then affect all projects in all chapters.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Chapter07<\/code> folder, open the <code class=\"calibre9\">Directory.Build.props<\/code> file, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project&gt;\n  &lt;!-- See https:\/\/aka.ms\/dotnet\/msbuild\/customize for more details on customizing your build --&gt;\n  &lt;PropertyGroup&gt;\n    &lt;ArtifactsPath&gt;$(MSBuildThisFileDirectory)artifacts&lt;\/ArtifactsPath&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build any project or the whole solution.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Chapter07<\/code> folder, note there is now an <code class=\"calibre9\">artifacts<\/code> folder that contains subfolders for any recently built projects.<\/li>\n<li class=\"calibre3\">Optionally, but recommended, is to delete this file or rename it to something like <code class=\"calibre9\">Directory.Build.props.disabled<\/code> so that it does not affect the rest of this chapter.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> If you leave this build configuration enabled, then remember that your build artifacts are now created in this new folder structure.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"8.5\" id=\"calibre_link-424\">\n<h2 data-number=\"8.5\" class=\"calibre5\">Native ahead-of-time compilation<\/h2>\n<p class=\"rights\">Native AOT produces assemblies that are:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Self-contained<\/strong>, meaning they can run on systems that do not have the .NET runtime installed.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Ahead-of-time (AOT) compiled to native code<\/strong>, meaning a faster startup time and a potentially smaller memory footprint.<\/li>\n<\/ul>\n<p class=\"rights\">Native AOT compiles IL code to native code at the time of publishing, rather than at runtime using the <strong class=\"calibre2\">Just In Time (JIT)<\/strong> compiler. But native AOT assemblies must target a specific runtime environment like Windows x64 or Linux Arm.Since native AOT happens at publish time, you should remember that while you are debugging and live working on a project in your code editor, it is still using the runtime JIT compiler, not native AOT, even if you have AOT enabled in the project! However, some features that are incompatible with native AOT will be disabled or throw exceptions, and a source analyzer is enabled to show warnings about potential code incompatibilities.<\/p>\n<section data-number=\"8.5.1\" id=\"calibre_link-425\">\n<h3 data-number=\"8.5.1\" class=\"calibre8\">Limitations of native AOT<\/h3>\n<p class=\"rights\">Native AOT has limitations, some of which are shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">No dynamic loading of assemblies.<\/li>\n<li class=\"calibre3\">No runtime code generation, for example, using <code class=\"calibre9\">System.Reflection.Emit<\/code>.<\/li>\n<li class=\"calibre3\">It requires trimming, which has its own limitations, as we covered in the previous section.<\/li>\n<li class=\"calibre3\">They must be self-contained, so they must embed any libraries they call, which increases their size.<\/li>\n<\/ul>\n<p class=\"rights\">Although your own assemblies might not use the features listed above, major parts of .NET itself do. For example, ASP.NET Core MVC (including Web API services that use controllers) and EF Core do runtime code generation to implement their functionality.The .NET teams are hard at work making as much of .NET compatible with native AOT as possible, as soon as possible. But .NET 8 only includes basic support for ASP.NET Core if you use Minimal APIs, and no support for EF Core.My guess is that .NET 9 will include support for ASP.NET Core MVC and some parts of EF Core, but it could take until .NET 10 before we can all confidently use most of .NET and know we can build our assemblies with native AOT to gain the benefits.The native AOT publishing process includes code analyzers to warn you if you use any features that are not supported, but not all packages have been annotated to work well with this yet.The most common annotation used to indicate that a type or member does not support AOT is the <code class=\"calibre9\">[RequiresDynamicCode]<\/code> attribute.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about AOT warnings at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/deploying\/native-aot\/fixing-warnings\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/deploying\/native-aot\/fixing-warnings<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"8.5.2\" id=\"calibre_link-426\">\n<h3 data-number=\"8.5.2\" class=\"calibre8\">Reflection and native AOT<\/h3>\n<p class=\"rights\">Reflection is frequently used for runtime inspection of type metadata, dynamic invocation of members, and code generation.Native AOT does allow some reflection features, but the trimming performed during the native AOT compilation process cannot statically determine when a type has members that might be only accessed via reflection. These members would be removed by AOT, which would then cause a runtime exception.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Developers must annotate their types with <code class=\"calibre9\">[DynamicallyAccessedMembers]<\/code> to indicate a member that is only dynamically accessed via reflection and should therefore be left untrimmed.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"8.5.3\" id=\"calibre_link-427\">\n<h3 data-number=\"8.5.3\" class=\"calibre8\">Requirements for native AOT<\/h3>\n<p class=\"rights\">There are additional requirements for different operating systems:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">On Windows, you must install the Visual Studio 2022 <strong class=\"calibre2\">Desktop development with C++<\/strong> workload with all default components.<\/li>\n<li class=\"calibre3\">On Linux, you must install the compiler toolchain and developer packages for libraries that the .NET runtime depends on. For example, for Ubuntu 18.04 or later: <code class=\"calibre9\">sudo apt-get install clang zlib1g-dev<\/code>.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Cross-platform native AOT publishing is not supported. This means that you must run the publish on the operating system that you will deploy to. For example, you cannot publish a native AOT project on Linux to later run on Windows, and vice versa.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"8.5.4\" id=\"calibre_link-428\">\n<h3 data-number=\"8.5.4\" class=\"calibre8\">Enabling native AOT for a project<\/h3>\n<p class=\"rights\">To enable native AOT publishing in a project, add the <code class=\"calibre9\">&lt;PublishAot&gt;<\/code> element to the project file, as shown highlighted in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">  &lt;PropertyGroup&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;PublishAot&gt;true&lt;\/PublishAot&gt;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"8.5.5\" id=\"calibre_link-429\">\n<h3 data-number=\"8.5.5\" class=\"calibre8\">Building a native AOT project<\/h3>\n<p class=\"rights\">Now let's see a practical example using the new AOT option for a console app:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">In the solution named <code class=\"calibre9\">Chapter07<\/code>, add a native AOT-compatible console app project, as defined in the following list:<\/p>\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console --aot<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter07<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">AotConsole<\/code><\/li>\n<li class=\"calibre3\">Do not use top-level statements: Cleared<\/li>\n<li class=\"calibre3\">Enable native AOT publish: Selected<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If your code editor does not yet provide the option for AOT, then create a traditional console app and then you will need to manually enable AOT as shown in step 2, or use the <code class=\"calibre9\">dotnet<\/code> CLI.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">In the project file, note that native AOT publishing is enabled, as well as invariant globalization, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk.Web\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n    &lt;PublishAot&gt;true&lt;\/PublishAot&gt;\n    &lt;InvariantGlobalization&gt;true&lt;\/InvariantGlobalization&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Explicitly setting invariant globalization to <code class=\"calibre9\">true<\/code> is new in the <strong class=\"calibre2\">Console App<\/strong> project template with .NET 8. It is designed to make a console app non-culture-specific so it can be deployed anywhere in the world and have the same behavior. If you set this property to <code class=\"calibre9\">false<\/code>, or if the element is missing, then the console app will default to the culture of the current computer it is hosted on. You can read more about invariant globalization mode at the following link: <a href=\"https:\/\/github.com\/dotnet\/runtime\/blob\/main\/docs\/design\/features\/globalization-invariant-mode.md\">https:\/\/github.com\/dotnet\/runtime\/blob\/main\/docs\/design\/features\/globalization-invariant-mode.md<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the project file to statically import the <code class=\"calibre9\">System.Console<\/code> class in all C# files.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete any existing statements, and then add statements to output the current culture and OS version, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Globalization; \/\/ To use CultureInfo.\nWriteLine(\"This is an ahead-of-time (AOT) compiled console app.\");\nWriteLine(\"Current culture: {0}\", CultureInfo.CurrentCulture.DisplayName);\nWriteLine(\"OS version: {0}\", Environment.OSVersion);\nWrite(\"Press any key to exit.\");\nReadKey(intercept: true); \/\/ Do not output the key that was pressed.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app project and note the culture is invariant, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">This is an ahead-of-time (AOT) compiled console app.\nCurrent culture: Invariant Language (Invariant Country)\nOS version: Microsoft Windows NT 10.0.22621.0<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> At the moment, the console app is not being AOT compiled; it is still currently JIT-compiled.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"8.5.6\" id=\"calibre_link-430\">\n<h3 data-number=\"8.5.6\" class=\"calibre8\">Publishing a native AOT project<\/h3>\n<p class=\"rights\">A console app that functions correctly during development when the code is untrimmed and JIT-compiled could still fail once you publish it using native AOT because then the code is trimmed and JIT-compiled and, therefore, it is a different code with different behavior. You should therefore perform a publish before assuming your project will work.If your project does not produce any AOT warnings at publish time, you can then be confident that your service will work after publishing for AOT.Let's review the source-generated code and publish our web service:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the command prompt or terminal for the <code class=\"calibre9\">AotConsole<\/code> project, publish the console app using native AOT, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet publish<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the message about generating native code, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">MSBuild version 17.8.0+4ce2ff1f8 for .NET\n  Determining projects to restore...\n  Restored C:\\cs12dotnet8\\Chapter07\\AotConsole\\AotConsole.csproj (in 173 ms).\n  AotConsole -&gt; C:\\cs12dotnet8\\Chapter07\\AotConsole\\bin\\Release\\net8.0\\win-x64\\AotConsole.dll\n  Generating native code\n  AotConsole -&gt; C:\\cs12dotnet8\\Chapter07\\AotConsole\\bin\\Release\\net8.0\\win-x64\\publish\\<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start <strong class=\"calibre2\">File Explorer<\/strong>, open the <code class=\"calibre9\">bin\\Release\\net8.0\\win-x64\\publish<\/code> folder, and note the <code class=\"calibre9\">AotConsole.exe<\/code> file is about 1.2 MB. The <code class=\"calibre9\">AotConsole.pdb<\/code> file is only needed if debugging.<\/li>\n<li class=\"calibre3\">Run the <code class=\"calibre9\">AotConsole.exe<\/code> and note the console app has the same behavior as before.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, import namespaces to work with dynamic code assemblies, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Reflection; \/\/ To use AssemblyName.\nusing System.Reflection.Emit; \/\/ To use AssemblyBuilder.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, create a dynamic assembly builder, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(\n  new AssemblyName(\"MyAssembly\"), AssemblyBuilderAccess.Run);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the command prompt or terminal for the <code class=\"calibre9\">AotConsole<\/code> project, publish the console app using native AOT, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet publish<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the warning about calling the <code class=\"calibre9\">DefineDynamicAssembly<\/code> method, which the .NET team has decorated with the <code class=\"calibre9\">[RequiresDynamicCode]<\/code> attribute, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">C:\\cs12dotnet8\\Chapter07\\AotConsole\\Program.cs(9,22): warning IL3050: Using member 'System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly(AssemblyName, AssemblyBuilderAccess)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. Defining a dynamic assembly requires dynamic code. [C:\\cs12dotnet8\\Chapter07\\AotConsole\\AotConsole.csproj]<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Comment out the statement that we cannot use in an AOT project.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about native AOT at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/deploying\/native-aot\/\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/deploying\/native-aot\/<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"8.6\" id=\"calibre_link-431\">\n<h2 data-number=\"8.6\" class=\"calibre5\">Decompiling .NET assemblies<\/h2>\n<p class=\"rights\">One of the best ways to learn how to code for .NET is to see how professionals do it. Most code editors have an extension for decompiling .NET assemblies. Visual Studio 2022 and Visual Studio Code can use the <strong class=\"calibre2\">ILSpy<\/strong> extension. JetBrains Rider has a built-in <strong class=\"calibre2\">IL Viewer<\/strong> tool.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You could decompile someone else's assemblies for non-learning purposes, like copying their code for use in your own production library or application, but remember that you are viewing their intellectual property, so please respect that.<\/p>\n<\/blockquote>\n<section data-number=\"8.6.1\" id=\"calibre_link-432\">\n<h3 data-number=\"8.6.1\" class=\"calibre8\">Decompiling using the ILSpy extension for Visual Studio 2022<\/h3>\n<p class=\"rights\">For learning purposes, you can decompile any .NET assembly with a tool like ILSpy:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Visual Studio 2022, navigate to <strong class=\"calibre2\">Extensions<\/strong> | <strong class=\"calibre2\">Manage Extensions<\/strong>.<\/li>\n<li class=\"calibre3\">In the search box, enter <code class=\"calibre9\">ilspy<\/code>.<\/li>\n<li class=\"calibre3\">For the <strong class=\"calibre2\">ILSpy 2022<\/strong> extension, click <strong class=\"calibre2\">Download<\/strong>.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Close<\/strong>.<\/li>\n<li class=\"calibre3\">Close Visual Studio to allow the extension to be installed.<\/li>\n<li class=\"calibre3\">Restart Visual Studio and reopen the <code class=\"calibre9\">Chapter07<\/code> solution.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, right-click the <strong class=\"calibre2\">DotNetEverywhere<\/strong> project and select <strong class=\"calibre2\">Open output in ILSpy<\/strong>.<\/li>\n<li class=\"calibre3\">In ILSpy, in the toolbar, make sure that <strong class=\"calibre2\">C#<\/strong> is selected in the drop-down list of languages to decompile into.<\/li>\n<li class=\"calibre3\">In ILSpy, in the <strong class=\"calibre2\">Assemblies<\/strong> navigation tree on the left, expand <strong class=\"calibre2\">DotNetEverywhere (1.0.0.0, .NETCoreApp, v8.0)<\/strong>.<\/li>\n<li class=\"calibre3\">In ILSpy, in the <strong class=\"calibre2\">Assemblies<\/strong> navigation tree on the left, expand <strong class=\"calibre2\">{ }<\/strong> and then expand <strong class=\"calibre2\">Program<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Select <strong class=\"calibre2\">&lt;Main&gt;$(string[]) : void<\/strong> to show the statements in the compiler-generated <code class=\"calibre9\">Program<\/code> class and its <code class=\"calibre9\">&lt;Main&gt;$<\/code> method, as shown in <em class=\"calibre10\">Figure 7.4<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 7.4: Revealing the &lt;Main&gt;$ method using ILSpy\" height=\"756\" src=\"\/images\/cs12\/000099.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 7.4: Revealing the &lt;Main&gt;$ method using ILSpy<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">In ILSpy, navigate to <strong class=\"calibre2\">File<\/strong> | <strong class=\"calibre2\">Open\u2026<\/strong>.<\/li>\n<li class=\"calibre3\">Navigate to the following folder:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">cs12dotnet8\/Chapter07\/DotNetEverywhere\/bin\/Release\/net8.0\/linux-x64<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Select the <code class=\"calibre9\">System.Linq.dll<\/code> assembly and click <strong class=\"calibre2\">Open<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Assemblies<\/strong> tree, expand the <strong class=\"calibre2\">System.Linq (8.0.0.0, .NETCoreApp, v8.0)<\/strong> assembly, expand the <strong class=\"calibre2\">System.Linq<\/strong> namespace, expand the <strong class=\"calibre2\">Enumerable<\/strong> class, and then click the <strong class=\"calibre2\">Count&lt;TSource&gt;(this IEnumerable&lt;TSource&gt;) : int<\/strong> method.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <code class=\"calibre9\">Count<\/code> method, note the good practice of checking the <code class=\"calibre9\">source<\/code> parameter and throwing an <code class=\"calibre9\">ArgumentNullException<\/code> if it is <code class=\"calibre9\">null<\/code>, checking for interfaces that the source might implement with their own <code class=\"calibre9\">Count<\/code> properties that would be more efficient to read, and finally, the last resort of enumerating through all the items in the source and incrementing a counter, which would be the least efficient implementation, as shown in <em class=\"calibre10\">Figure 7.5<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 7.5: Decompiled Count method of Enumerable class\" height=\"1255\" src=\"\/images\/cs12\/000033.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 7.5: Decompiled Count method of Enumerable class<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Different decompiler tools are likely to produce slightly different code, for example, variable names, but the functionality will be the same.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Review the C# source code for the <code class=\"calibre9\">Count<\/code> method, as shown in the following code, in preparation for reviewing the same code in <strong class=\"calibre2\">IL<\/strong>:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public static int Count&lt;TSource&gt;(this IEnumerable&lt;TSource&gt; source)\n{\n  if (source == null)\n  {\n    ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);\n  }\n  if (source is ICollection&lt;TSource&gt; collection)\n  {\n    return collection.Count;\n  }\n  if (source is IIListProvider&lt;TSource&gt; iIListProvider)\n  {\n    return iIListProvider.GetCount(onlyIfCheap: false);\n  }\n  if (source is ICollection collection2)\n  {\n    return collection2.Count;\n  }\n  int num = 0;\n  using IEnumerator&lt;TSource&gt; enumerator = source.GetEnumerator();\n  while (enumerator.MoveNext())\n  {\n    num = checked(num + 1);\n  }\n  return num;\n} <\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You will often see LinkedIn posts and blog articles warning you to always use the <code class=\"calibre9\">Count<\/code> property of a sequence instead of calling the LINQ <code class=\"calibre9\">Count()<\/code> extension method. As you can see above, this advice is unnecessary because the <code class=\"calibre9\">Count()<\/code> method always checks if the sequence implements <code class=\"calibre9\">ICollection&lt;T&gt;<\/code> or <code class=\"calibre9\">ICollection<\/code> and then uses the <code class=\"calibre9\">Count<\/code> property anyway. What it doesn't do is check if the sequence is an array and then use the <code class=\"calibre9\">Length<\/code> property. If you have an array of any type, avoid <code class=\"calibre9\">Count()<\/code> in favor of the <code class=\"calibre9\">Length<\/code> property.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The final part of the <code class=\"calibre9\">Count<\/code> method implementation shows how the <code class=\"calibre9\">foreach<\/code> statement works internally. It calls the <code class=\"calibre9\">GetEnumerator<\/code> method and then calls the <code class=\"calibre9\">MoveNext<\/code> method in a <code class=\"calibre9\">while<\/code> loop. To calculate the count, the loop increments an <code class=\"calibre9\">int<\/code> value. It does all this in a <code class=\"calibre9\">checked<\/code> statement so that an exception will be thrown in the case of an overflow. The <code class=\"calibre9\">Count<\/code> method can therefore only count sequences with up to about 2 billion items.<\/p>\n<\/blockquote>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">In the ILSpy toolbar, click the <strong class=\"calibre2\">Select language to decompile<\/strong> dropdown and select <strong class=\"calibre2\">IL<\/strong>, and then review the IL source code of the <code class=\"calibre9\">Count<\/code> method. To save two pages in this book, I have not shown the code here.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: The IL code is not especially useful unless you get very advanced with C# and .NET development, when knowing how the C# compiler translates your source code into IL code can be important. The much more useful edit windows contain the equivalent C# source code written by Microsoft experts. You can learn a lot of good practices from seeing how professionals implement types. For example, the <code class=\"calibre9\">Count<\/code> method shows how to check arguments for <code class=\"calibre9\">null<\/code>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Close ILSpy.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can learn how to use the ILSpy extension for Visual Studio Code at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/code-editors\/vscode.md#decompiling-using-the-ilspy-extension-for-visual-studio-code\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/code-editors\/vscode.md#decompiling-using-the-ilspy-extension-for-visual-studio-code<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"8.6.2\" id=\"calibre_link-433\">\n<h3 data-number=\"8.6.2\" class=\"calibre8\">Viewing source links with Visual Studio 2022<\/h3>\n<p class=\"rights\">Instead of decompiling, Visual Studio 2022 has a feature that allows you to view the original source code using source links. This feature is not available in Visual Studio Code.Let's see how it works:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Visual Studio 2022, enable Source Link:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Tools<\/strong> | <strong class=\"calibre2\">Options<\/strong>.<\/li>\n<li class=\"calibre3\">In the search box, enter <code class=\"calibre9\">navigation in source<\/code>.<\/li>\n<li class=\"calibre3\">Select <strong class=\"calibre2\">Text Editor<\/strong> | <strong class=\"calibre2\">C#<\/strong> | <strong class=\"calibre2\">Advanced<\/strong>.<\/li>\n<li class=\"calibre3\">Select the <strong class=\"calibre2\">Enable navigation to Source Link and Embedded sources<\/strong> check box, and then click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In Visual Studio 2022, add a new <strong class=\"calibre2\">Console App<\/strong> project to the <code class=\"calibre9\">Chapter07<\/code> solution named <code class=\"calibre9\">SourceLinks<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements. Add statements to declare a <code class=\"calibre9\">string<\/code> variable and then output its value and the number of characters it has, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string name = \"Timoth\u00e9e Chalamet\";\nint length = name.Count();\nConsole.WriteLine($\"{name} has {length} characters.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Right-click in the <code class=\"calibre9\">Count()<\/code> method and select <strong class=\"calibre2\">Go To Implementation<\/strong>.<\/li>\n<li class=\"calibre3\">Note the source code file is named <code class=\"calibre9\">Count.cs<\/code> and it defines a partial <code class=\"calibre9\">Enumerable<\/code> class with implementations of five count-related methods, as shown in <em class=\"calibre10\">Figure 7.6<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 7.6: Viewing the original source file for LINQ&apos;s Count method implementation\" height=\"940\" src=\"\/images\/cs12\/000153.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 7.6: Viewing the original source file for LINQ's Count method implementation<\/figcaption><\/figure>\n<p class=\"rights\">You can learn more from viewing source links than decompiling because they show best practices for situations like how to divide up a class into partial classes for easier management. When we used the ILSpy compiler, all it could do was show all the hundreds of methods of the <code class=\"calibre9\">Enumerable<\/code> class.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can learn more about how source link works and how any NuGet package can support it at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/library-guidance\/sourcelink\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/library-guidance\/sourcelink<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you prefer decompiling, then you can disable the source link feature now.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"8.6.3\" id=\"calibre_link-434\">\n<h3 data-number=\"8.6.3\" class=\"calibre8\">No, you cannot technically prevent decompilation<\/h3>\n<p class=\"rights\">I sometimes get asked if there is a way to protect compiled code to prevent decompilation. The quick answer is no, and if you think about it, you'll see why this must be the case. You can make it harder using obfuscation tools like <strong class=\"calibre2\">Dotfuscator<\/strong>, but ultimately, you cannot completely prevent it.All compiled applications contain instructions for the platform, operating system, and hardware on which it runs. Those instructions must be functionally the same as the original source code but are just harder for a human to read. Those instructions must be readable to execute your code; therefore, they must be readable to be decompiled. If you were to protect your code from decompilation using some custom technique, then you would also prevent your code from running!Virtual machines simulate hardware and so can capture all interaction between your running application and the software and hardware that it thinks it is running on.If you could protect your code, then you would also prevent attaching to it with a debugger and stepping through it. If the compiled application has a <code class=\"calibre9\">pdb<\/code> file, then you can attach a debugger and step through the statements line-by-line. Even without the <code class=\"calibre9\">pdb<\/code> file, you can still attach a debugger and get some idea of how the code works.This is true for all programming languages. Not just .NET languages like C#, Visual Basic, and F#, but also C, C++, Delphi, and assembly language: all can be attached to for debugging or to be disassembled or decompiled. Some tools used by professionals are shown in <em class=\"calibre10\">Table 7.13<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Type<\/td>\n<td class=\"calibre21\">Product<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Virtual Machine<\/td>\n<td class=\"calibre21\">VMware<\/td>\n<td class=\"calibre21\">Professionals like malware analysts always run software inside a VM.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Debugger<\/td>\n<td class=\"calibre21\">SoftICE<\/td>\n<td class=\"calibre21\">Runs underneath the operating system, usually in a VM.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Debugger<\/td>\n<td class=\"calibre21\">WinDbg<\/td>\n<td class=\"calibre21\">Useful for understanding Windows internals because it knows more about Windows data structures than other debuggers.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Disassembler<\/td>\n<td class=\"calibre21\">IDA Pro<\/td>\n<td class=\"calibre21\">Used by professional malware analysts.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Decompiler<\/td>\n<td class=\"calibre21\">HexRays<\/td>\n<td class=\"calibre21\">Decompiles C apps. Plugin for IDA Pro.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Decompiler<\/td>\n<td class=\"calibre21\">DeDe<\/td>\n<td class=\"calibre21\">Decompiles Delphi apps.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Decompiler<\/td>\n<td class=\"calibre21\">dotPeek<\/td>\n<td class=\"calibre21\">.NET decompiler from JetBrains.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 7.13: Professional debugger, decompiler, and disassembler tools<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Debugging, disassembling, and decompiling someone else's software is likely against its license agreement and illegal in many jurisdictions. Instead of trying to protect your intellectual property with a technical solution, the law is sometimes your only recourse.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"8.7\" id=\"calibre_link-435\">\n<h2 data-number=\"8.7\" class=\"calibre5\">Packaging your libraries for NuGet distribution<\/h2>\n<p class=\"rights\">Before we learn how to create and package our own libraries, we will review how a project can use an existing package.<\/p>\n<section data-number=\"8.7.1\" id=\"calibre_link-436\">\n<h3 data-number=\"8.7.1\" class=\"calibre8\">Referencing a NuGet package<\/h3>\n<p class=\"rights\">Let's say that you want to add a package created by a third-party developer, for example, <code class=\"calibre9\">Newtonsoft.Json<\/code>, a popular package for working with the <strong class=\"calibre2\">JavaScript Object Notation<\/strong> (<strong class=\"calibre2\">JSON<\/strong>) serialization format:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">AssembliesAndNamespaces<\/code> project, add a reference to the <code class=\"calibre9\">Newtonsoft.Json<\/code> NuGet package, either using the GUI for Visual Studio 2022 or the <code class=\"calibre9\">dotnet add package<\/code> command for Visual Studio Code.<\/li>\n<li class=\"calibre3\">Open the <code class=\"calibre9\">AssembliesAndNamespaces.csproj<\/code> file and note that a package reference has been added, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.3\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you have a more recent version of the <code class=\"calibre9\">Newtonsoft.Json<\/code> package, then it has been updated since this chapter was written.<\/p>\n<\/section>\n<section data-number=\"8.7.2\" id=\"calibre_link-437\">\n<h3 data-number=\"8.7.2\" class=\"calibre8\">Fixing dependencies<\/h3>\n<p class=\"rights\">To consistently restore packages and write reliable code, it's important that you <strong class=\"calibre2\">fix dependencies<\/strong>. Fixing dependencies means you are using the same family of packages released for a specific version of .NET, for example, SQLite for .NET 8, as shown highlighted in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n  &lt;\/PropertyGroup&gt;\n  &lt;ItemGroup&gt;\n    &lt;PackageReference Version=\"8.0.0\"\n      Include=\"Microsoft.EntityFrameworkCore.Sqlite\" \/&gt;\n  &lt;\/ItemGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To fix dependencies, every package should have a single version with no additional qualifiers. Additional qualifiers include betas (<code class=\"calibre9\">beta1<\/code>), release candidates (<code class=\"calibre9\">rc4<\/code>), and wildcards (<code class=\"calibre9\">*<\/code>).Wildcards allow future versions to be automatically referenced and used because they always represent the most recent release. But wildcards are therefore dangerous because they could result in the use of future incompatible packages that break your code.This can be worth the risk while writing a book where new preview versions are released every month and you do not want to keep updating the preview package references, as I did during 2023, and as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PackageReference Version=\"8.0.0-preview.*\"\n  Include=\"Microsoft.EntityFrameworkCore.Sqlite\" \/&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To also automatically use the release candidates that arrive in September and October each year, you can make the pattern even more flexible, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PackageReference Version=\"8.0-*\"\n  Include=\"Microsoft.EntityFrameworkCore.Sqlite\" \/&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you use the <code class=\"calibre9\">dotnet add package<\/code> command or Visual Studio's <strong class=\"calibre2\">Manage NuGet Packages<\/strong>, then it will by default use the latest specific version of a package. But if you copy and paste configuration from a blog article or manually add a reference yourself, you might include wildcard qualifiers.The following dependencies are examples of NuGet package references that are <em class=\"calibre10\">not<\/em> fixed and therefore should be avoided unless you know the implications:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PackageReference Include=\"System.Net.Http\" Version=\"4.1.0-*\" \/&gt;\n&lt;PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.2-beta1\" \/&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Microsoft guarantees that if you fix your dependencies to what ships with a specific version of .NET, for example, <code class=\"calibre9\">8.0.0<\/code>, those packages will all work together. Almost always fix your dependencies, especially in production deployments.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"8.7.3\" id=\"calibre_link-438\">\n<h3 data-number=\"8.7.3\" class=\"calibre8\">Packaging a library for NuGet<\/h3>\n<p class=\"rights\">Now, let's package the <code class=\"calibre9\">SharedLibrary<\/code> project that you created earlier:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">SharedLibrary<\/code> project, note that the class library targets .NET Standard 2.0 and therefore, by default, uses the C# 7.3 compiler. Explicitly specify the C# 12 compiler, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;TargetFramework&gt;netstandard2.0&lt;\/TargetFramework&gt;\n    &lt;LangVersion&gt;12&lt;\/LangVersion&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">SharedLibrary<\/code> project, rename the <code class=\"calibre9\">Class1.cs<\/code> file to <code class=\"calibre9\">StringExtensions.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify its contents to provide some useful extension methods for validating various text values using regular expressions, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Text.RegularExpressions; \/\/ To use Regex.\nnamespace Packt.Shared;\npublic static class StringExtensions\n{\n  public static bool IsValidXmlTag(this string input)\n  {\n    return Regex.IsMatch(input,\n      @\"^&lt;([a-z]+)([^&lt;]+)*(?:&gt;(.*)&lt;\\\/\\1&gt;|\\s+\\\/&gt;)$\");\n  }\n  public static bool IsValidPassword(this string input)\n  {\n    \/\/ Minimum of eight valid characters.\n    return Regex.IsMatch(input, \"^[a-zA-Z0-9_-]{8,}$\");\n  }\n  public static bool IsValidHex(this string input)\n  {\n    \/\/ Three or six valid hex number characters.\n    return Regex.IsMatch(input,\n      \"^#?([a-fA-F0-9]{3}|[a-fA-F0-9]{6})$\");\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You will learn how to write regular expressions in <em class=\"calibre10\">Chapter 8<\/em>, <em class=\"calibre10\">Working with Common .NET Types<\/em>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">SharedLibrary.csproj<\/code>, modify its contents, as shown highlighted in the following markup, and note the following:\n<ul class=\"calibre16\">\n<li class=\"calibre3\"><code class=\"calibre9\">PackageId<\/code> must be globally unique, so you must use a different value if you want to publish this NuGet package to the <a href=\"https:\/\/www.nuget.org\/\">https:\/\/www.nuget.org\/<\/a> public feed for others to reference and download.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\"><code class=\"calibre9\">PackageLicenseExpression<\/code> must be a value from <a href=\"https:\/\/spdx.org\/licenses\/\">https:\/\/spdx.org\/licenses\/<\/a>, or you could specify a custom license.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> If you rely on IntelliSense to edit the file, then it could mislead you to use deprecated tag names. For example, <code class=\"calibre9\">&lt;PackageIconUrl&gt;<\/code> is deprecated in favor of <code class=\"calibre9\">&lt;PackageIcon&gt;<\/code>. Sometimes, you cannot trust automated tools to help you correctly! The recommended tag names are documented in the <strong class=\"calibre2\">MSBuild Property<\/strong> column in the table found at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/nuget\/reference\/msbuild-targets#pack-target\">https:\/\/learn.microsoft.com\/en-us\/nuget\/reference\/msbuild-targets#pack-target<\/a>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">All the other elements are self-explanatory:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;TargetFramework&gt;netstandard2.0&lt;\/TargetFramework&gt;\n    &lt;LangVersion&gt;12&lt;\/LangVersion&gt;\n    &lt;GeneratePackageOnBuild&gt;true&lt;\/GeneratePackageOnBuild&gt;\n    &lt;PackageId&gt;Packt.CSdotnet.SharedLibrary&lt;\/PackageId&gt;\n    &lt;PackageVersion&gt;8.0.0.0&lt;\/PackageVersion&gt;\n    &lt;Title&gt;C# 12 and .NET 8 Shared Library&lt;\/Title&gt;\n    &lt;Authors&gt;Mark J Price&lt;\/Authors&gt;\n    &lt;PackageLicenseExpression&gt;\n      MS-PL\n    &lt;\/PackageLicenseExpression&gt;\n    &lt;PackageProjectUrl&gt;\n      https:\/\/github.com\/markjprice\/cs12dotnet8\n    &lt;\/PackageProjectUrl&gt;\n    &lt;PackageReadmeFile&gt;readme.md&lt;\/PackageReadmeFile&gt;\n    &lt;PackageIcon&gt;packt-csdotnet-sharedlibrary.png&lt;\/PackageIcon&gt;\n    &lt;PackageRequireLicenseAcceptance&gt;true&lt;\/PackageRequireLicenseAcceptance&gt;\n    &lt;PackageReleaseNotes&gt;\n      Example shared library packaged for NuGet.\n    &lt;\/PackageReleaseNotes&gt;\n    &lt;Description&gt;\n      Three extension methods to validate a string value.\n    &lt;\/Description&gt;\n    &lt;Copyright&gt;\n      Copyright \u00a9 2016-2023 Packt Publishing Limited\n    &lt;\/Copyright&gt;\n    &lt;PackageTags&gt;string extensions packt csharp dotnet&lt;\/PackageTags&gt;\n  &lt;\/PropertyGroup&gt;\n  &lt;ItemGroup&gt;\n    &lt;None Include=\"packt-csdotnet-sharedlibrary.png\" \n          PackagePath=\"\\\" Pack=\"true\" \/&gt;\n    &lt;None Include=\"readme.md\"\n          PackagePath=\"\\\" Pack=\"true\" \/&gt;\n  &lt;\/ItemGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">&lt;None&gt;<\/code> represents a file that does not participate in the build process. <code class=\"calibre9\">Pack=\"true\"<\/code> means the file will be included in the NuGet package created in the specified package path location. You can learn more at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/nuget\/reference\/msbuild-targets#packing-an-icon-image-file\">https:\/\/learn.microsoft.com\/en-us\/nuget\/reference\/msbuild-targets#packing-an-icon-image-file<\/a>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Configuration property values that are <code class=\"calibre9\">true<\/code> or <code class=\"calibre9\">false<\/code> values cannot have any whitespace, so the <code class=\"calibre9\">&lt;PackageRequireLicenseAcceptance&gt;<\/code> entry cannot have a carriage return and indentation, as shown in the preceding markup.<\/p>\n<\/blockquote>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Download the icon file and save it in the <code class=\"calibre9\">SharedLibrary<\/code> project folder from the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/Chapter07\/SharedLibrary\/packt-csdotnet-sharedlibrary.png\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/Chapter07\/SharedLibrary\/packt-csdotnet-sharedlibrary.png<\/a>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">SharedLibrary<\/code> project folder, create a file named <code class=\"calibre9\">readme.md<\/code>, with some basic information about the package, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\"># README for C# 12 and .NET 8 Shared Library\nThis is a shared library that readers build in the book, \n*C# 12 and .NET 8 - Modern Cross-Platform Development Fundamentals*.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the release assembly:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">In Visual Studio 2022, select <strong class=\"calibre2\">Release<\/strong> in the toolbar, and then navigate to <strong class=\"calibre2\">Build<\/strong> | <strong class=\"calibre2\">Build SharedLibrary<\/strong>.<\/li>\n<li class=\"calibre3\">In Visual Studio Code, in <strong class=\"calibre2\">Terminal<\/strong>, enter <code class=\"calibre9\">dotnet build -c Release<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p class=\"rights\">If we had not set <code class=\"calibre9\">&lt;GeneratePackageOnBuild&gt;<\/code> to <code class=\"calibre9\">true<\/code> in the project file, then we would have to create a NuGet package manually using the following additional steps:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">In Visual Studio 2022, navigate to <strong class=\"calibre2\">Build<\/strong> | <strong class=\"calibre2\">Pack SharedLibrary<\/strong>.<\/li>\n<li class=\"calibre3\">In Visual Studio Code, in <strong class=\"calibre2\">Terminal<\/strong>, enter <code class=\"calibre9\">dotnet pack -c Release<\/code>.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"8.7.4\" id=\"calibre_link-439\">\n<h3 data-number=\"8.7.4\" class=\"calibre8\">Publishing a package to a public NuGet feed<\/h3>\n<p class=\"rights\">If you want everyone to be able to download and use your NuGet package, then you must upload it to a public NuGet feed like Microsoft's:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start your favorite browser and navigate to the following link: <a href=\"https:\/\/www.nuget.org\/packages\/manage\/upload\">https:\/\/www.nuget.org\/packages\/manage\/upload<\/a>.<\/li>\n<li class=\"calibre3\">You will need to sign up for, and then sign in with, a Microsoft account at <a href=\"https:\/\/www.nuget.org\/\">https:\/\/www.nuget.org\/<\/a> if you want to upload a NuGet package for other developers to reference as a dependency package.<\/li>\n<li class=\"calibre3\">Click the <strong class=\"calibre2\">Browse...<\/strong> button and select the <code class=\"calibre9\">.nupkg<\/code> file that was created by generating the NuGet package. The folder path should be <code class=\"calibre9\">cs12dotnet8\\Chapter07\\SharedLibrary\\bin\\Release<\/code> and the file is named <code class=\"calibre9\">Packt.CSdotnet.SharedLibrary.8.0.0.nupkg<\/code>.<\/li>\n<li class=\"calibre3\">Verify that the information you entered in the <code class=\"calibre9\">SharedLibrary.csproj<\/code> file has been correctly filled in, and then click <strong class=\"calibre2\">Submit<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Wait a few seconds, and you will see a success message showing that your package has been uploaded, as shown in <em class=\"calibre10\">Figure 7.7<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 7.7: A NuGet package upload message\" height=\"710\" src=\"\/images\/cs12\/000128.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 7.7: A NuGet package upload message<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If you get an error, then review the project file for mistakes, or read more information about the <code class=\"calibre9\">PackageReference<\/code> format at <a href=\"https:\/\/learn.microsoft.com\/en-us\/nuget\/reference\/msbuild-targets\">https:\/\/learn.microsoft.com\/en-us\/nuget\/reference\/msbuild-targets<\/a>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Click the <strong class=\"calibre2\">Frameworks<\/strong> tab, and note that because we targeted .NET Standard 2.0, our class library can be used by every .NET platform, as shown in <em class=\"calibre10\">Figure 7.8<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 7.8: .NET Standard 2.0 class library package can be used by all .NET platforms\" height=\"832\" src=\"\/images\/cs12\/000145.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 7.8: .NET Standard 2.0 class library package can be used by all .NET platforms<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"8.7.5\" id=\"calibre_link-440\">\n<h3 data-number=\"8.7.5\" class=\"calibre8\">Publishing a package to a private NuGet feed<\/h3>\n<p class=\"rights\">Organizations can host their own private NuGet feeds. This can be a handy way for many developer teams to share work. You can read more at the following link:<a href=\"https:\/\/learn.microsoft.com\/en-us\/nuget\/hosting-packages\/overview\">https:\/\/learn.microsoft.com\/en-us\/nuget\/hosting-packages\/overview<\/a><\/p>\n<\/section>\n<section data-number=\"8.7.6\" id=\"calibre_link-441\">\n<h3 data-number=\"8.7.6\" class=\"calibre8\">Exploring NuGet packages with a tool<\/h3>\n<p class=\"rights\">A handy tool named <strong class=\"calibre2\">NuGet Package Explorer<\/strong> for opening and reviewing more details about a NuGet package was created by Uno Platform. As well as being a website, it can be installed as a cross-platform app. Let's see what it can do:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start your favorite browser and navigate to the following link: <a href=\"https:\/\/nuget.info\">https:\/\/nuget.info<\/a>.<\/li>\n<li class=\"calibre3\">In the search box, enter <code class=\"calibre9\">Packt.CSdotnet.SharedLibrary<\/code>.<\/li>\n<li class=\"calibre3\">Select the package <strong class=\"calibre2\">v8.0.0<\/strong> published by <strong class=\"calibre2\">Mark J Price<\/strong> and then click the <strong class=\"calibre2\">Open<\/strong> button.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Contents<\/strong> section, expand the <code class=\"calibre9\">lib<\/code> folder and the <code class=\"calibre9\">netstandard2.0<\/code> folder.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Select <code class=\"calibre9\">SharedLibrary.dll<\/code>, and note the details, as shown in <em class=\"calibre10\">Figure 7.9<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 7.9: Exploring my package using NuGet Package Explorer from Uno Platform\" height=\"776\" src=\"\/images\/cs12\/000161.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 7.9: Exploring my package using NuGet Package Explorer from Uno Platform<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">If you want to use this tool locally in the future, click the install button in your browser.<\/li>\n<li class=\"calibre3\">Close your browser.<\/li>\n<\/ol>\n<p class=\"rights\">Not all browsers support installing web apps like this. I recommend Chrome for testing and development.<\/p>\n<\/section>\n<section data-number=\"8.7.7\" id=\"calibre_link-442\">\n<h3 data-number=\"8.7.7\" class=\"calibre8\">Testing your class library package<\/h3>\n<p class=\"rights\">You will now test your uploaded package by referencing it in the <code class=\"calibre9\">AssembliesAndNamespaces<\/code> project:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">AssembliesAndNamespaces<\/code> project, add a reference to your (or my) package, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.3\" \/&gt;\n  &lt;PackageReference Include=\"Packt.CSdotnet.SharedLibrary\" \n                    Version=\"8.0.0\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">AssembliesAndNamespaces<\/code> project.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, import the <code class=\"calibre9\">Packt.Shared<\/code> namespace.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, prompt the user to enter some <code class=\"calibre9\">string<\/code> values, and then validate them using the extension methods in the package, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Write(\"Enter a color value in hex: \"); \nstring? hex = ReadLine();\nWriteLine(\"Is {0} a valid color value? {1}\",\n  arg0: hex, arg1: hex.IsValidHex());\nWrite(\"Enter a XML element: \"); \nstring? xmlTag = ReadLine();\nWriteLine(\"Is {0} a valid XML element? {1}\", \n  arg0: xmlTag, arg1: xmlTag.IsValidXmlTag());\nWrite(\"Enter a password: \"); \nstring? password = ReadLine();\nWriteLine(\"Is {0} a valid password? {1}\",\n  arg0: password, arg1: password.IsValidPassword());<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">AssembliesAndNamespaces<\/code> project, enter some values as prompted, and view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter a color value in hex: 00ffc8 \nIs 00ffc8 a valid color value? True\nEnter an XML element: &lt;h1 class=\"&lt;\" \/&gt;\nIs &lt;h1 class=\"&lt;\" \/&gt; a valid XML element? False \nEnter a password: secretsauce\nIs secretsauce a valid password? True<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"8.8\" id=\"calibre_link-443\">\n<h2 data-number=\"8.8\" class=\"calibre5\">Working with preview features<\/h2>\n<p class=\"rights\">It is a challenge for Microsoft to deliver some new features that have cross-cutting effects across many parts of .NET like the runtime, language compilers, and API libraries. It is the classic chicken and egg problem. What do you do first?From a practical perspective, it means that although Microsoft might have completed most of the work needed for a feature, the whole thing might not be ready until very late in their now annual cycle of .NET releases, too late for proper testing in \"the wild.\"So, from .NET 6 onward, Microsoft will include preview features in <strong class=\"calibre2\">general availability<\/strong> (<strong class=\"calibre2\">GA<\/strong>) releases. Developers can opt into these preview features and provide Microsoft with feedback. In a later GA release, they can be enabled for everyone.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">It is important to note that this topic is about <em class=\"calibre10\">preview features<\/em>. This is different from a preview version of .NET or a preview version of Visual Studio 2022. Microsoft releases preview versions of Visual Studio and .NET while developing them to get feedback from developers and then do a final GA release. At GA, the feature is available for everyone. Before GA, the only way to get the new functionality is to install a preview version. <em class=\"calibre10\">Preview features<\/em> are different because they are installed with GA releases and must be optionally enabled.<\/p>\n<\/blockquote>\n<p class=\"rights\">For example, when Microsoft released .NET SDK 6.0.200 in February 2022, it included the C# 11 compiler as a preview feature. This meant that .NET 6 developers could optionally set the language version to <code class=\"calibre9\">preview<\/code>, and then start exploring C# 11 features like raw string literals and the <code class=\"calibre9\">required<\/code> keyword.Once .NET SDK 7.0.100 was released in November 2022, any .NET 6 developer who wanted to continue to use the C# 11 compiler would then need to use the .NET 7 SDK for their .NET 6 projects and set the target framework to <code class=\"calibre9\">net6.0<\/code> with a <code class=\"calibre9\">&lt;LangVersion&gt;<\/code> set to <code class=\"calibre9\">11<\/code>. This way, they use the supported .NET 7 SDK with the supported C# 11 compiler to build .NET 6 projects.In November 2024, Microsoft is likely to release .NET 9 SDK with a C# 13 compiler. You can then install and use the .NET 9 SDK to gain the benefits of whatever new features are available in C# 13, while still targeting .NET 8 for long-term support, as shown highlighted in the following <code class=\"calibre9\">Project<\/code> file:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;LangVersion&gt;13&lt;\/LangVersion&gt; &lt;!--Requires .NET 9 SDK GA--&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Preview features are not supported in production code. Preview features are likely to have breaking changes before the final release. Enable preview features at your own risk. Switch to a GA release future SDK like .NET 9 to use new compiler features while still targeting older but longer supported versions of .NET like .NET 8.<\/p>\n<\/blockquote>\n<section data-number=\"8.8.1\" id=\"calibre_link-444\">\n<h3 data-number=\"8.8.1\" class=\"calibre8\">Requiring preview features<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">[RequiresPreviewFeatures]<\/code> attribute is used to indicate assemblies, types, or members that use and therefore require warnings about preview features. A code analyzer then scans for this assembly and generates warnings if needed. If your code does not use any preview features, you will not see any warnings. If you use any preview features, then your code should warn consumers of your code that you use preview features.<\/p>\n<\/section>\n<section data-number=\"8.8.2\" id=\"calibre_link-445\">\n<h3 data-number=\"8.8.2\" class=\"calibre8\">Enabling preview features<\/h3>\n<p class=\"rights\">In the <code class=\"calibre9\">Project<\/code> file, add an element to enable preview features and an element to enable preview language features, as shown highlighted in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n    &lt;EnablePreviewFeatures&gt;true&lt;\/EnablePreviewFeatures&gt;\n    &lt;LangVersion&gt;preview&lt;\/LangVersion&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"8.8.3\" id=\"calibre_link-446\">\n<h3 data-number=\"8.8.3\" class=\"calibre8\">Method interceptors<\/h3>\n<p class=\"rights\">An interceptor is a method that substitutes for a call to an interceptable method with a call to itself. They are an advanced feature most commonly used in source generators. If readers are interested, then I might add a section about them to the ninth edition.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about interceptors at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/whats-new\/csharp-12#interceptors\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/whats-new\/csharp-12#interceptors<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"8.9\" id=\"calibre_link-447\">\n<h2 data-number=\"8.9\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring with deeper research into the topics of this chapter.<\/p>\n<section data-number=\"8.9.1\" id=\"calibre_link-448\">\n<h3 data-number=\"8.9.1\" class=\"calibre8\">Exercise 7.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between a namespace and an assembly?<\/li>\n<li class=\"calibre3\">How do you reference another project in a <code class=\"calibre9\">.csproj<\/code> file?<\/li>\n<li class=\"calibre3\">What is the benefit of a tool like ILSpy?<\/li>\n<li class=\"calibre3\">Which .NET type does the C# <code class=\"calibre9\">float<\/code> alias represent?<\/li>\n<li class=\"calibre3\">When porting an application from .NET Framework to .NET 6, what tool should you run before porting, and what tool could you run to perform much of the porting work?<\/li>\n<li class=\"calibre3\">What is the difference between framework-dependent and self-contained deployments of .NET applications?<\/li>\n<li class=\"calibre3\">What is a RID?<\/li>\n<li class=\"calibre3\">What is the difference between the <code class=\"calibre9\">dotnet pack<\/code> and <code class=\"calibre9\">dotnet publish<\/code> commands?<\/li>\n<li class=\"calibre3\">What types of applications written for the .NET Framework can be ported to modern .NET?<\/li>\n<li class=\"calibre3\">Can you use packages written for .NET Framework with modern .NET?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"8.9.2\" id=\"calibre_link-449\">\n<h3 data-number=\"8.9.2\" class=\"calibre8\">Exercise 7.2 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more details about the topics covered in this chapter:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-7---packaging-and-distributing-net-types\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-7---packaging-and-distributing-net-types<\/a><\/p>\n<\/section>\n<section data-number=\"8.9.3\" id=\"calibre_link-450\">\n<h3 data-number=\"8.9.3\" class=\"calibre8\">Exercise 7.3 &ndash; Porting from .NET Framework to modern .NET<\/h3>\n<p class=\"rights\">If you are interested in porting legacy projects from .NET Framework to modern .NET, then I have written an online-only section at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch07-porting.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch07-porting.md<\/a><\/p>\n<\/section>\n<section data-number=\"8.9.4\" id=\"calibre_link-451\">\n<h3 data-number=\"8.9.4\" class=\"calibre8\">Exercise 7.4 &ndash; Creating source generators<\/h3>\n<p class=\"rights\">If you are interested in creating source generators, then I have written an online-only section at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch07-source-generators.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch07-source-generators.md<\/a>You can find examples of source generators at the following link:<a href=\"https:\/\/github.com\/amis92\/csharp-source-generators\">https:\/\/github.com\/amis92\/csharp-source-generators<\/a><\/p>\n<\/section>\n<section data-number=\"8.9.5\" id=\"calibre_link-452\">\n<h3 data-number=\"8.9.5\" class=\"calibre8\">Exercise 7.5 &ndash; Explore PowerShell<\/h3>\n<p class=\"rights\">PowerShell is Microsoft's scripting language for automating tasks on every operating system. Microsoft recommends Visual Studio Code with the PowerShell extension for writing PowerShell scripts.Since PowerShell is its own extensive language, there is not enough space in this book to cover it. You can learn about some key concepts from a Microsoft training module at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/training\/modules\/introduction-to-powershell\/\">https:\/\/learn.microsoft.com\/en-us\/training\/modules\/introduction-to-powershell\/<\/a>You can read the official documentation at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/\">https:\/\/learn.microsoft.com\/en-us\/powershell\/<\/a>.<\/p>\n<\/section>\n<section data-number=\"8.9.6\" id=\"calibre_link-453\">\n<h3 data-number=\"8.9.6\" class=\"calibre8\">Exercise 7.6 &ndash; Improving performance in .NET<\/h3>\n<p class=\"rights\">Microsoft has made significant improvements to performance in the past few years. You should review the blog posts written by Stephen Toub to learn what the team changed and why. His posts are famously long, detailed, and brilliant!You can find the posts about the improvements at the following links:<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-core\/\">https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-core\/<\/a> - 25 pages<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-core-2-1\/\">https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-core-2-1\/<\/a> - 20 pages<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-core-3-0\/\">https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-core-3-0\/<\/a> - 41 pages<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-5\/\">https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-5\/<\/a> - 43 pages<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-6\/\">https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-6\/<\/a> - 100 pages<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/performance_improvements_in_net_7\/\">https:\/\/devblogs.microsoft.com\/dotnet\/performance_improvements_in_net_7\/<\/a> - 156 pages<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-8\/\">https:\/\/devblogs.microsoft.com\/dotnet\/performance-improvements-in-net-8\/<\/a> - 218 pagesGet ready for .NET 9's article being almost 300 pages. \ud83d\ude09<\/p>\n<\/section>\n<\/section>\n<section data-number=\"8.10\" id=\"calibre_link-454\">\n<h2 data-number=\"8.10\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, we:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Reviewed the journey to .NET 8 for BCL functionality.<\/li>\n<li class=\"calibre3\">Explored the relationship between assemblies and namespaces.<\/li>\n<li class=\"calibre3\">Saw options for publishing an app for distribution to multiple operating systems.<\/li>\n<li class=\"calibre3\">Learned how to publish to native AOT for faster startup and smaller memory footprint.<\/li>\n<li class=\"calibre3\">Learned how to decompile .NET assemblies for educational purposes.<\/li>\n<li class=\"calibre3\">Packaged and distributed a class library.<\/li>\n<li class=\"calibre3\">Learned how to activate preview features.<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will learn about some common BCL types that are included with modern .NET.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-8\">\n<div id=\"calibre_link-1934\" class=\"calibre1\">\n<section data-number=\"9\" id=\"calibre_link-455\">\n<h1 data-number=\"9\" class=\"title\">8 Working with Common .NET Types<\/h1>\n<section data-number=\"9.1\" id=\"calibre_link-456\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"9.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000077.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about some common types that are included with .NET. These include types for manipulating numbers, text, and collections; improving working with spans, indexes, and ranges; and in an optional online-only section, working with network resources.This chapter covers the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Working with numbers<\/li>\n<li class=\"calibre3\">Working with text<\/li>\n<li class=\"calibre3\">Pattern matching with regular expressions<\/li>\n<li class=\"calibre3\">Storing multiple objects in collections<\/li>\n<li class=\"calibre3\">Working with spans, indexes, and ranges<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"9.2\" id=\"calibre_link-457\">\n<h2 data-number=\"9.2\" class=\"calibre5\">Working with numbers<\/h2>\n<p class=\"rights\">One of the most common types of data is numbers. The most common types in .NET for working with numbers are shown in <em class=\"calibre10\">Table 8.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Namespace<\/td>\n<td class=\"calibre21\">Example type(s)<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">SByte<\/code> , <code class=\"calibre9\">Int16<\/code> , <code class=\"calibre9\">Int32<\/code> , <code class=\"calibre9\">Int64<\/code> , <code class=\"calibre9\">Int128<\/code><\/td>\n<td class=\"calibre21\">Integers; that is, zero, and positive and negative whole numbers.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Byte<\/code> , <code class=\"calibre9\">UInt16<\/code> , <code class=\"calibre9\">UInt32<\/code> , <code class=\"calibre9\">UInt64<\/code> , <code class=\"calibre9\">UInt128<\/code><\/td>\n<td class=\"calibre21\">Cardinals; that is, zero and positive whole numbers.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Half<\/code> , <code class=\"calibre9\">Single<\/code> , <code class=\"calibre9\">Double<\/code><\/td>\n<td class=\"calibre21\">Reals; that is, floating-point numbers.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Decimal<\/code><\/td>\n<td class=\"calibre21\">Accurate reals; that is, for use in science, engineering, or financial scenarios.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Numerics<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">BigInteger<\/code> , <code class=\"calibre9\">Complex<\/code> , <code class=\"calibre9\">Quaternion<\/code><\/td>\n<td class=\"calibre21\">Arbitrarily large integers, complex numbers, and quaternion numbers.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.1: Common .NET number types<\/p>\n<p class=\"rights\">.NET has had the 32-bit float and 64-bit double types since .NET Framework 1.0 was released in 2002. The IEEE 754 specification also defines a 16-bit floating-point standard. Machine learning and other algorithms would benefit from this smaller, lower-precision number type, so Microsoft introduced the <code class=\"calibre9\">System.Half<\/code> type with .NET 5 and later. Currently, the C# language does not define a <code class=\"calibre9\">half<\/code> alias, so you must use the .NET type <code class=\"calibre9\">System.Half<\/code>. This might change in the future.<code class=\"calibre9\">System.Int128<\/code> and <code class=\"calibre9\">System.UInt128<\/code> were introduced with .NET 7, and they too do not yet have a C# alias keyword.<\/p>\n<section data-number=\"9.2.1\" id=\"calibre_link-458\">\n<h3 data-number=\"9.2.1\" class=\"calibre8\">Working with big integers<\/h3>\n<p class=\"rights\">The largest whole number that can be stored in .NET types that have a C# alias is about eighteen and a half quintillion, stored in an unsigned 64-bit integer using <code class=\"calibre9\">ulong<\/code>. But what if you need to store numbers larger than that?Let's explore numerics:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to create a new project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">WorkingWithNumbers<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter08<\/code><\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In the project file, add an element to statically and globally import the <code class=\"calibre9\">System.Console<\/code> class.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then add a statement to import <code class=\"calibre9\">System.Numerics<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Numerics; \/\/ To use BigInteger.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to output the maximum value of the <code class=\"calibre9\">ulong<\/code> type, and a number with 30 digits using <code class=\"calibre9\">BigInteger<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">const int width = 40;\nWriteLine(\"ulong.MaxValue vs a 30-digit BigInteger\");\nWriteLine(new string('-', width));\nulong big = ulong.MaxValue;\nWriteLine($\"{big,width:N0}\");\nBigInteger bigger =\n  BigInteger.Parse(\"123456789012345678901234567890\");\nWriteLine($\"{bigger,width:N0}\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">width<\/code> constant with the value <code class=\"calibre9\">40<\/code> in the format code means \u201cright-align 40 characters,\u201d so both numbers are lined up to the right-hand edge. The <code class=\"calibre9\">N0<\/code> means \u201cuse thousand separators and zero decimal places.\u201d<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ulong.MaxValue vs a 30-digit BigInteger\n----------------------------------------\n              18,446,744,073,709,551,615\n 123,456,789,012,345,678,901,234,567,890<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.2.2\" id=\"calibre_link-459\">\n<h3 data-number=\"9.2.2\" class=\"calibre8\">Working with complex numbers<\/h3>\n<p class=\"rights\">A complex number can be expressed as <em class=\"calibre10\">a + bi<\/em>, where <em class=\"calibre10\">a<\/em> and <em class=\"calibre10\">b<\/em> are real numbers and <em class=\"calibre10\">i<\/em> is an imaginary unit, where <em class=\"calibre10\">i<\/em><sup class=\"calibre26\">2<\/sup> <em class=\"calibre10\">= \u22121<\/em>. If the real part <em class=\"calibre10\">a<\/em> is zero, it is a pure imaginary number. If the imaginary part <em class=\"calibre10\">b<\/em> is zero, it is a real number.Complex numbers have practical applications in many <strong class=\"calibre2\">STEM<\/strong> (<strong class=\"calibre2\">science, technology, engineering, and mathematics<\/strong>) fields of study. They are added by separately adding the real and imaginary parts of the summands; consider this:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">(a + bi) + (c + di) = (a + c) + (b + d)i<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Let's explore complex numbers:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to add two complex numbers, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Complex c1 = new(real: 4, imaginary: 2);\nComplex c2 = new(real: 3, imaginary: 7);\nComplex c3 = c1 + c2;\n\/\/ Output using the default ToString implementation.\nWriteLine($\"{c1} added to {c2} is {c3}\");\n\/\/ Output using a custom format.\nWriteLine(\"{0} + {1}i added to {2} + {3}i is {4} + {5}i\",\n  c1.Real, c1.Imaginary, \n  c2.Real, c2.Imaginary,\n  c3.Real, c3.Imaginary);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;4; 2&gt; added to &lt;3; 7&gt; is &lt;7; 9&gt;\n4 + 2i added to 3 + 7i is 7 + 9i<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">.NET 6 and earlier used a different default format for complex numbers: <code class=\"calibre9\">(4, 2) added to (3, 7) is (7, 9)<\/code>. In .NET 7 and later, the default format was changed to use angle brackets and semi-colons because some cultures use round brackets to indicate negative numbers and use commas for decimal numbers. At the time of writing, the official documentation has not been updated to use the new format, as shown at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.numerics.complex.tostring\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.numerics.complex.tostring<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"9.2.3\" id=\"calibre_link-460\">\n<h3 data-number=\"9.2.3\" class=\"calibre8\">Generating random numbers for games and similar apps<\/h3>\n<p class=\"rights\">In scenarios that don't need truly random numbers like games, you can create an instance of the <code class=\"calibre9\">Random<\/code> class, as shown in the following code example:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Random r = new();<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><code class=\"calibre9\">Random<\/code> has a constructor with a parameter for specifying a seed value used to initialize its pseudo-random number generator, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Random r = new(Seed: 46378);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">As you learned in <em class=\"calibre10\">Chapter 2<\/em>, <em class=\"calibre10\">Speaking C#<\/em>, parameter names should use <em class=\"calibre10\">camel case<\/em>. The developer who defined the constructor for the <code class=\"calibre9\">Random<\/code> class broke this convention. The parameter name should be <code class=\"calibre9\">seed<\/code>, not <code class=\"calibre9\">Seed<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Shared seed values act as a secret key, so if you use the same random number generation algorithm with the same seed value in two applications, then they can generate the same \"random\" sequences of numbers. Sometimes this is necessary, for example, when synchronizing a GPS receiver with a satellite, or when a game needs to randomly generate the same level. But usually, you want to keep your seed secret.<\/p>\n<\/blockquote>\n<p class=\"rights\">To avoid allocating more memory than necessary, .NET 6 introduced a shared static instance of <code class=\"calibre9\">Random<\/code> that you can access instead of creating your own.The <code class=\"calibre9\">Random<\/code> class has commonly used methods for generating random numbers, as described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Next<\/code>: This method returns a random <code class=\"calibre9\">int<\/code> (whole number) and it takes two parameters, <code class=\"calibre9\">minValue<\/code> and <code class=\"calibre9\">maxValue<\/code>, but <code class=\"calibre9\">maxValue<\/code> is not the maximum value that the method returns! It is an <em class=\"calibre10\">exclusive upper bound<\/em>, meaning <code class=\"calibre9\">maxValue<\/code> is one more than the maximum value returned. Use the <code class=\"calibre9\">NextInt64<\/code> method to return a <code class=\"calibre9\">long<\/code> integer.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">NextDouble<\/code>: This method returns a number that is greater than or equal to <code class=\"calibre9\">0.0<\/code> and less than and never equal to <code class=\"calibre9\">1.0<\/code>. Use the <code class=\"calibre9\">NextSingle<\/code> method to return a <code class=\"calibre9\">float<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">NextBytes<\/code>: This method populates an array of any size with random <code class=\"calibre9\">byte<\/code> (<code class=\"calibre9\">0<\/code> to <code class=\"calibre9\">255<\/code>) values. It is common to format <code class=\"calibre9\">byte<\/code> values as hexadecimal, for example, <code class=\"calibre9\">00<\/code> to <code class=\"calibre9\">FF<\/code>.<\/li>\n<\/ul>\n<p class=\"rights\">Let's see some examples of generating pseudo-random numbers:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to access the shared <code class=\"calibre9\">Random<\/code> instance, and then call its methods to generate random numbers, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Random r = Random.Shared;\n\/\/ minValue is an inclusive lower bound i.e. 1 is a possible value.\n\/\/ maxValue is an exclusive upper bound i.e. 7 is not a possible value.\nint dieRoll = r.Next(minValue: 1, maxValue: 7); \/\/ Returns 1 to 6.\nWriteLine($\"Random die roll: {dieRoll}\");\ndouble randomReal = r.NextDouble(); \/\/ Returns 0.0 to less than 1.0.\nWriteLine($\"Random double: {randomReal}\");\nbyte[] arrayOfBytes = new byte[256]; \nr.NextBytes(arrayOfBytes); \/\/ Fills array with 256 random bytes.\nWrite(\"Random bytes: \");\nfor (int i = 0; i &lt; arrayOfBytes.Length; i++)\n{\n  Write($\"{arrayOfBytes[i]:X2} \");\n}\nWriteLine();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Random die roll: 1\nRandom double: 0.06735275453092382\nRandom bytes: D9 38 CD F3 5B 40 2D F4 5B D0 48 DF F7 B6 67 C1 95 A1 2C 58 42 CF 70 6C C3 BE 82 D7 EC 61 0D D2 2D C4 49 7B C7 0F EA CC B3 41 F3 04 5D 29 25 B7 F7 99 8A 0F 56 20 A6 B3 57 C4 48 DA 94 2B 07 F1 15 64 EA 8D FF 79 E6 E4 9A C8 65 C5 D8 55 3D 3C C0 2B 0B 4C 3A 0E E6 A5 91 B7 59 6C 9A 94 97 43 B7 90 EE D8 9A C6 CA A1 8F DD 0A 23 3C 01 48 E0 45 E1 D6 BD 7C 41 C8 22 8A 81 82 DC 1F 2E AD 3F 93 68 0F B5 40 7B 2B 31 FC A6 BF BA 05 C0 76 EE 58 B3 41 63 88 E5 5C 8B B5 08 5C C3 52 FF 73 69 B0 97 78 B5 3B 87 2C 12 F3 C3 AE 96 43 7D 67 2F F8 C9 31 70 BD AD B3 9B 44 53 39 5F 19 73 C8 43 0E A5 5B 6B 5A 9D 2F DF DC A3 EE C5 CF AF A4 8C 0F F2 9C 78 19 48 CE 49 A8 28 06 A3 4E 7D F7 75 AA 49 E7 4E 20 AF B1 77 0A 90 CF C1 E0 62 BC 4F 79 76 64 98 BF 63 76 B4 F9 1D A4 C4 74 03 63 02<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In scenarios that do need truly random numbers like cryptography, there are specialized types for that, like <code class=\"calibre9\">RandomNumberGenerator<\/code>. I plan to cover this and other cryptographic types in the companion book, <em class=\"calibre10\">Tools and Skills for .NET 8 Pros<\/em> in a chapter titled <em class=\"calibre10\">Protecting Data and Apps Using Cryptography<\/em>, expected to publish in the first half of 2024.<\/p>\n<\/blockquote>\n<p class=\"rights\">.NET 8 introduced two new <code class=\"calibre9\">Random<\/code> methods, as described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">GetItems&lt;T&gt;<\/code>: This method is passed an array or read-only span of any type <code class=\"calibre9\">T<\/code> of choices and the number of items you want to generate, and then it returns that number of items randomly selected from the choices.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Shuffle&lt;T&gt;<\/code>: This method is passed an array or span of any type <code class=\"calibre9\">T<\/code> and the order of items is randomized.<\/li>\n<\/ul>\n<p class=\"rights\">Let's see an example of each:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to access the shared <code class=\"calibre9\">Random<\/code> instance, and then call its methods to generate random numbers, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string[] beatles = r.GetItems(\n  choices: new[] { \"John\", \"Paul\", \"George\", \"Ringo\" }, \n  length: 10);\nWrite(\"Random ten beatles:\");\nforeach (string beatle in beatles)\n{\n  Write($\" {beatle}\");\n}\nWriteLine();\nr.Shuffle(beatles);\nWrite(\"Shuffled beatles:\");\nforeach (string beatle in beatles)\n{\n  Write($\" {beatle}\");\n}\nWriteLine();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Random ten beatles: Paul Paul John John John John Paul John George Ringo\nShuffled beatles: George John Paul Paul John John John Ringo Paul John<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.2.4\" id=\"calibre_link-461\">\n<h3 data-number=\"9.2.4\" class=\"calibre8\">Generating GUIDs<\/h3>\n<p class=\"rights\">A <strong class=\"calibre2\">GUID (globally unique identifier)<\/strong> is a 128-bit text string that represents a unique value for identification. As a developer, you will need to generate GUIDs when a unique reference is needed to identify information. Traditionally, database and computer systems may have used an incrementing integer value, but a GUID is more likely to avoid conflicts in multi-tasking systems.The <code class=\"calibre9\">System.Guid<\/code> type is a value type (<code class=\"calibre9\">struct<\/code>) that represents a GUID value. It has <code class=\"calibre9\">Parse<\/code> and <code class=\"calibre9\">TryParse<\/code> methods to take an existing GUID value represented as a <code class=\"calibre9\">string<\/code> and convert it into the <code class=\"calibre9\">Guid<\/code> type. It has a <code class=\"calibre9\">NewGuid<\/code> method to generate a new value.Let's see how we can generate GUID values and output them:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to access the shared <code class=\"calibre9\">Random<\/code> instance, and then call its methods to generate random numbers, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine($\"Empty GUID: {Guid.Empty}.\");\nGuid g = Guid.NewGuid();\nWriteLine($\"Random GUID: {g}.\");\nbyte[] guidAsBytes = g.ToByteArray();\nWrite(\"GUID as byte array: \");\nfor (int i = 0; i &lt; guidAsBytes.Length; i++)\n{\n  Write($\"{guidAsBytes[i]:X2} \");\n}\nWriteLine();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Empty GUID: 00000000-0000-0000-0000-000000000000.\nRandom GUID: c7a11eea-45a5-4619-964a-a9cce1e4220c.\nGUID as byte array: EA 1E A1 C7 A5 45 19 46 96 4A A9 CC E1 E4 22 0C<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"9.3\" id=\"calibre_link-462\">\n<h2 data-number=\"9.3\" class=\"calibre5\">Working with text<\/h2>\n<p class=\"rights\">One of the other most common types of data for variables is text. The most common types in .NET for working with text are shown in <em class=\"calibre10\">Table 8.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Namespace<\/td>\n<td class=\"calibre21\">Type<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Char<\/code><\/td>\n<td class=\"calibre21\">Storage for a single text character<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">String<\/code><\/td>\n<td class=\"calibre21\">Storage for multiple text characters<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Text<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">StringBuilder<\/code><\/td>\n<td class=\"calibre21\">Efficiently manipulates strings<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Text.RegularExpressions<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Regex<\/code><\/td>\n<td class=\"calibre21\">Efficiently pattern-matches strings<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.2: Common .NET types for working with text<\/p>\n<section data-number=\"9.3.1\" id=\"calibre_link-463\">\n<h3 data-number=\"9.3.1\" class=\"calibre8\">Getting the length of a string<\/h3>\n<p class=\"rights\">Let's explore some common tasks when working with text; for example, sometimes you need to find out the length of a piece of text stored in a <code class=\"calibre9\">string<\/code> variable:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">WorkingWithText<\/code> to the <code class=\"calibre9\">Chapter08<\/code> solution.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithText<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then add statements to define a variable to store the name of the city London, and then write its name and length to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string city = \"London\";\nWriteLine($\"{city} is {city.Length} characters long.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">London is 6 characters long.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.3.2\" id=\"calibre_link-464\">\n<h3 data-number=\"9.3.2\" class=\"calibre8\">Getting the characters of a string<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">string<\/code> class uses an array of <code class=\"calibre9\">char<\/code> internally to store the text. It also has an indexer, which means that we can use the array syntax to read its characters. Array indexes start at zero, so the third character will be at index 2.Let's see this in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a statement to write the characters at the first and fourth positions in the <code class=\"calibre9\">string<\/code> variable, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine($\"First char is {city[0]} and fourth is {city[3]}.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">First char is L and fourth is d.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.3.3\" id=\"calibre_link-465\">\n<h3 data-number=\"9.3.3\" class=\"calibre8\">Splitting a string<\/h3>\n<p class=\"rights\">Sometimes, you need to split some text wherever there is a character, such as a comma:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to define a single <code class=\"calibre9\">string<\/code> variable containing comma-separated city names, then use the <code class=\"calibre9\">Split<\/code> method and specify that you want to treat commas as the separator, and then enumerate the returned array of <code class=\"calibre9\">string<\/code> values, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string cities = \"Paris,Tehran,Chennai,Sydney,New York,Medell\u00edn\";\nstring[] citiesArray = cities.Split(',');\nWriteLine($\"There are {citiesArray.Length} items in the array:\");\nforeach (string item in citiesArray)\n{\n  WriteLine($\"  {item}\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">There are 6 items in the array:\n  Paris\n  Tehran\n  Chennai\n  Sydney\n  New York\n  Medell\u00edn<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Later in this chapter, you will learn how to handle more complex string-splitting scenarios using a regular expression.<\/p>\n<\/section>\n<section data-number=\"9.3.4\" id=\"calibre_link-466\">\n<h3 data-number=\"9.3.4\" class=\"calibre8\">Getting part of a string<\/h3>\n<p class=\"rights\">Sometimes, you need to get part of some text. The <code class=\"calibre9\">IndexOf<\/code> method has nine overloads that return the index position of a specified <code class=\"calibre9\">char<\/code> or <code class=\"calibre9\">string<\/code> within a <code class=\"calibre9\">string<\/code>. The <code class=\"calibre9\">Substring<\/code> method has two overloads, as shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Substring(startIndex, length)<\/code>: Returns part of a string starting at <code class=\"calibre9\">startIndex<\/code> and containing the next <code class=\"calibre9\">length<\/code> characters<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Substring(startIndex)<\/code>: Returns part of a string starting at <code class=\"calibre9\">startIndex<\/code> and containing all characters up to the end of the string<\/li>\n<\/ul>\n<p class=\"rights\">Let's explore a simple example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to store a person's full name in a <code class=\"calibre9\">string<\/code> variable with a space character between the first and last names, find the position of the space, and then extract the first name and last name as two parts so that they can be recombined in a different order, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string fullName = \"Alan Shore\";\nint indexOfTheSpace = fullName.IndexOf(' ');\nstring firstName = fullName.Substring(\n  startIndex: 0, length: indexOfTheSpace);\nstring lastName = fullName.Substring(\n  startIndex: indexOfTheSpace + 1);\nWriteLine($\"Original: {fullName}\");\nWriteLine($\"Swapped: {lastName}, {firstName}\"); <\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Original: Alan Shore\nSwapped: Shore, Alan<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If the format of the initial full name was different, for example, <code class=\"calibre9\">\"LastName, FirstName\"<\/code>, then the code would need to be different. As an optional exercise, try writing some statements that would change the input <code class=\"calibre9\">\"Shore, Alan\"<\/code> into <code class=\"calibre9\">\"Alan Shore\"<\/code>.<\/p>\n<\/section>\n<section data-number=\"9.3.5\" id=\"calibre_link-467\">\n<h3 data-number=\"9.3.5\" class=\"calibre8\">Checking a string for content<\/h3>\n<p class=\"rights\">Sometimes, you need to check whether a piece of text starts or ends with some characters or contains some characters. You can achieve this with methods named <code class=\"calibre9\">StartsWith<\/code>, <code class=\"calibre9\">EndsWith<\/code>, and <code class=\"calibre9\">Contains<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to store a <code class=\"calibre9\">string<\/code> value and then check if it starts with or contains a couple of different <code class=\"calibre9\">string<\/code> values, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string company = \"Microsoft\";\nWriteLine($\"Text: {company}\");\nWriteLine(\"Starts with M: {0}, contains an N: {1}\", \n  arg0: company.StartsWith(\"M\"),\n  arg1: company.Contains(\"N\"));<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Text: Microsoft\nStarts with M: True, contains an N: False<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.3.6\" id=\"calibre_link-468\">\n<h3 data-number=\"9.3.6\" class=\"calibre8\">Comparing string values<\/h3>\n<p class=\"rights\">Two common tasks with string values are sorting (aka collating) and comparing. For example, when a user enters their username or password, you need to compare what they entered with what is stored.The <code class=\"calibre9\">string<\/code> class implements the <code class=\"calibre9\">IComparable<\/code> interface meaning that you can easily compare two string values using the <code class=\"calibre9\">CompareTo<\/code> instance method and it will return <code class=\"calibre9\">-1<\/code>, <code class=\"calibre9\">0<\/code>, or <code class=\"calibre9\">1<\/code> depending on if the value is \"less than,\" \"equal to,\" or \"greater than\" the other. You saw an example of this when you implemented the <code class=\"calibre9\">IComparable<\/code> interface for the <code class=\"calibre9\">Person<\/code> class in <em class=\"calibre10\">Chapter 6, Implementing Interfaces and Inheriting Classes<\/em>.But the lower or upper casing of characters can affect ordering, and the ordering rules for text are culture dependent. For example, double-L is treated as a single character in traditional Spanish, as shown in <em class=\"calibre10\">Table 8.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Culture<\/td>\n<td class=\"calibre21\">Description<\/td>\n<td class=\"calibre21\">Example string values<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Spanish<\/td>\n<td class=\"calibre21\">In 1994, the Royal Spanish Academy issued a new alphabetization rule to treat LL and CH as Latin alphabetic characters instead of separate individual characters.<\/td>\n<td class=\"calibre21\">Modern: <code class=\"calibre9\">llegar<\/code> comes before <code class=\"calibre9\">lugar<\/code> . Traditional: <code class=\"calibre9\">llegar<\/code> comes after <code class=\"calibre9\">lugar<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Swedish<\/td>\n<td class=\"calibre21\">In 2006, the Swedish Academy issued a new rule. Before 2006, V and W were the same character. Since 2006, they are treated as separate characters.<\/td>\n<td class=\"calibre21\">Swedish words mostly only use V. Loanwords (words taken from other languages) that contain W can now keep those Ws instead of replacing the Ws with Vs.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">German<\/td>\n<td class=\"calibre21\">Phonebook ordering is different than dictionary ordering, for example, umlauts are sorted as combinations of letters.<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">M\u00fcller<\/code> and <code class=\"calibre9\">Mueller<\/code> in phonebook ordering are the same name.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">German<\/td>\n<td class=\"calibre21\">The character <code class=\"calibre9\">\u00df<\/code> is sorted as <code class=\"calibre9\">SS<\/code> . This is a common issue with addresses since the word for <code class=\"calibre9\">street<\/code> is <code class=\"calibre9\">Stra\u00dfe<\/code> .<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Stra\u00dfe<\/code> and <code class=\"calibre9\">Strasse<\/code> have the same meaning.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.3: Examples of ordering rules in European languages<\/p>\n<p class=\"rights\">For consistency and performance, you sometimes want to make comparisons in a culture-invariant way. It is therefore better to use the <code class=\"calibre9\">static<\/code> method <code class=\"calibre9\">Compare<\/code>.Let's see some examples:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.cs<\/code>, import the namespace for working with cultures and enable special characters like the Euro currency symbol, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Globalization; \/\/ To use CultureInfo.\nOutputEncoding = System.Text.Encoding.UTF8; \/\/ Enable Euro symbol.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, define some text variables and compare them in different cultures, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo(\"en-US\");\nstring text1 = \"Mark\";\nstring text2 = \"MARK\";\nWriteLine($\"text1: {text1}, text2: {text2}\");\nWriteLine(\"Compare: {0}.\", string.Compare(text1, text2));\nWriteLine(\"Compare (ignoreCase): {0}.\",\n  string.Compare(text1, text2, ignoreCase: true));\nWriteLine(\"Compare (InvariantCultureIgnoreCase): {0}.\",\n  string.Compare(text1, text2, \n  StringComparison.InvariantCultureIgnoreCase));<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that a lowercase \"a\" is \"less than\" (<code class=\"calibre9\">-1<\/code>) an upper case \"A,\" so the comparison returns -1. But we can either set an option to ignore case, or even better, do a culture- and case-invariant comparison to treat the two string values as equal (<code class=\"calibre9\">0<\/code>), as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">text1: Mark, text2: MARK\nCompare: -1.\nCompare (ignoreCase): 0.\nCompare (InvariantCultureIgnoreCase): 0.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about string comparisons at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/globalization\/locale\/sorting-and-string-comparison\">https:\/\/learn.microsoft.com\/en-us\/globalization\/locale\/sorting-and-string-comparison<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"9.3.7\" id=\"calibre_link-469\">\n<h3 data-number=\"9.3.7\" class=\"calibre8\">Joining, formatting, and other string members<\/h3>\n<p class=\"rights\">There are many other <code class=\"calibre9\">string<\/code> members, as shown in <em class=\"calibre10\">Table 8.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Member<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Trim<\/code> , <code class=\"calibre9\">TrimStart<\/code> , <code class=\"calibre9\">TrimEnd<\/code><\/td>\n<td class=\"calibre21\">These methods trim whitespace characters such as space, tab, and carriage return from the start and\/or end.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ToUpper<\/code> , <code class=\"calibre9\">ToLower<\/code><\/td>\n<td class=\"calibre21\">These convert all the characters into uppercase or lowercase.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Insert<\/code> , <code class=\"calibre9\">Remove<\/code><\/td>\n<td class=\"calibre21\">These methods insert or remove some text.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Replace<\/code><\/td>\n<td class=\"calibre21\">This replaces some text with other text.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">string.Empty<\/code><\/td>\n<td class=\"calibre21\">This can be used instead of allocating memory each time you use a literal string value using an empty pair of double quotes ( <code class=\"calibre9\">\"\"<\/code> ).<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">string.Concat<\/code><\/td>\n<td class=\"calibre21\">This concatenates two string variables. The <code class=\"calibre9\">+<\/code> operator does the equivalent when used between string operands.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">string.Join<\/code><\/td>\n<td class=\"calibre21\">This concatenates one or more string variables with a character in between each one.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">string.IsNullOrEmpty<\/code><\/td>\n<td class=\"calibre21\">This checks whether a string variable is null or empty.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">string.IsNullOrWhiteSpace<\/code><\/td>\n<td class=\"calibre21\">This checks whether a string variable is null or whitespace; that is, a mix of any number of horizontal and vertical spacing characters, for example, tab, space, carriage return, line feed, and so on.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">string.Format<\/code><\/td>\n<td class=\"calibre21\">An alternative method to string interpolation for outputting formatted string values, which uses positioned instead of named parameters.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.4: Joining, formatting, and other string members<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Some of the preceding methods are <code class=\"calibre9\">static<\/code> methods. This means that the method can only be called from the type, not from a variable instance. In the preceding table, I indicated the static methods by prefixing them with <code class=\"calibre9\">string.<\/code>, as in <code class=\"calibre9\">string.Format<\/code>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's explore some of these methods:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to take an array of <code class=\"calibre9\">string<\/code> values and combine them back together into a single <code class=\"calibre9\">string<\/code> variable with separators using the <code class=\"calibre9\">Join<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string recombined = string.Join(\" =&gt; \", citiesArray); \nWriteLine(recombined);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Paris =&gt; Tehran =&gt; Chennai =&gt; Sydney =&gt; New York =&gt; Medell\u00edn<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to use positioned parameters and interpolated <code class=\"calibre9\">string<\/code> formatting syntax to output the same three variables twice, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string fruit = \"Apples\"; \ndecimal price =  0.39M; \nDateTime when = DateTime.Today;\nWriteLine($\"Interpolated:  {fruit} cost {price:C} on {when:dddd}.\"); \nWriteLine(string.Format(\"string.Format: {0} cost {1:C} on {2:dddd}.\",\n  arg0: fruit, arg1: price, arg2: when));<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Some code editors like JetBrains Rider will warn you about boxing operations. These are slow but not a problem in this scenario. To avoid boxing, call <code class=\"calibre9\">ToString<\/code> on <code class=\"calibre9\">price<\/code> and <code class=\"calibre9\">when<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Interpolated:  Apples cost $0.39 on Friday.\nstring.Format: Apples cost $0.39 on Friday.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note that we could have simplified the second statement because <code class=\"calibre9\">Console.WriteLine<\/code> supports the same format codes as <code class=\"calibre9\">string.Format<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(\"WriteLine: {0} cost {1:C} on {2:dddd}.\",\n  arg0: fruit, arg1: price, arg2: when);<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.3.8\" id=\"calibre_link-470\">\n<h3 data-number=\"9.3.8\" class=\"calibre8\">Building strings efficiently<\/h3>\n<p class=\"rights\">You can concatenate two strings to make a new <code class=\"calibre9\">string<\/code> using the <code class=\"calibre9\">String.Concat<\/code> method or simply by using the <code class=\"calibre9\">+<\/code> operator. But both choices are bad practice when combining more than a few values because .NET must create a completely new <code class=\"calibre9\">string<\/code> in memory.This might not be noticeable if you are only adding two <code class=\"calibre9\">string<\/code> values, but if you concatenate inside a loop with many iterations, it can have a significant negative impact on performance and memory use. You can concatenate <code class=\"calibre9\">string<\/code> variables more efficiently using the <code class=\"calibre9\">StringBuilder<\/code> type.I have written an online-only section for the companion book, <em class=\"calibre10\">Apps and Services with .NET 8<\/em>, about performance benchmarking using <code class=\"calibre9\">string<\/code> concatenations as the main example. You can optionally complete the section and its practical coding tasks at the following link: <a href=\"https:\/\/github.com\/markjprice\/apps-services-net8\/blob\/main\/docs\/ch01-benchmarking.md\">https:\/\/github.com\/markjprice\/apps-services-net8\/blob\/main\/docs\/ch01-benchmarking.md<\/a>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can see examples of using <code class=\"calibre9\">StringBuilder<\/code> at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.text.stringbuilder#examples\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.text.stringbuilder#examples<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"9.4\" id=\"calibre_link-471\">\n<h2 data-number=\"9.4\" class=\"calibre5\">Pattern matching with regular expressions<\/h2>\n<p class=\"rights\">Regular expressions are useful for validating input from the user. They are very powerful and can get very complicated. Almost all programming languages have support for regular expressions and use a common set of special characters to define them.Let's try out some example regular expressions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">WorkingWithRegularExpressions<\/code> to the <code class=\"calibre9\">Chapter08<\/code> solution.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then import the following namespace:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Text.RegularExpressions; \/\/ To use Regex.<\/code><\/pre>\n<\/div>\n<section data-number=\"9.4.1\" id=\"calibre_link-472\">\n<h3 data-number=\"9.4.1\" class=\"calibre8\">Checking for digits entered as text<\/h3>\n<p class=\"rights\">We will start by implementing the common example of validating number input:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to prompt the user to enter their age and then check that it is valid using a regular expression that looks for a digit character, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Write(\"Enter your age: \");\nstring input = ReadLine()!; \/\/ Null-forgiving operator.\nRegex ageChecker = new(@\"\\d\");\nWriteLine(ageChecker.IsMatch(input) ? \"Thank you!\" :\n  $\"This is not a valid age: {input}\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following about the code:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The <code class=\"calibre9\">@<\/code> character switches off the ability to use escape characters in the <code class=\"calibre9\">string<\/code>. Escape characters are prefixed with a backslash. For example, <code class=\"calibre9\">\\t<\/code> means a tab and <code class=\"calibre9\">\\n<\/code> means a new line. When writing regular expressions, we need to disable this feature. To paraphrase the television show <em class=\"calibre10\">The West Wing<\/em>, \"Let backslash be backslash.\"<\/li>\n<li class=\"calibre3\">Once escape characters are disabled with <code class=\"calibre9\">@<\/code>, then they can be interpreted by a regular expression. For example, <code class=\"calibre9\">\\d<\/code> means digit. You will learn about more regular expression symbols that are prefixed with a backslash later in this topic.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter a whole number such as <code class=\"calibre9\">34<\/code> for the age, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter your age: 34 \nThank you!<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code again, enter <code class=\"calibre9\">carrots<\/code>, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter your age: carrots\nThis is not a valid age: carrots<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code again, enter <code class=\"calibre9\">bob30smith<\/code>, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter your age: bob30smith\nThank you!<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The regular expression we used is <code class=\"calibre9\">\\d<\/code>, which means <em class=\"calibre10\">one digit<\/em>. However, it does not specify what can be entered before and after that one digit. This regular expression could be described in English as \"Enter any characters you want as long as you enter at least one digit character.\"In regular expressions, you indicate the start of some input with the caret <code class=\"calibre9\">^<\/code> symbol and the end of some input with the dollar <code class=\"calibre9\">$<\/code> symbol. Let's use these symbols to indicate that we expect nothing else between the start and end of the input except for a digit.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a <code class=\"calibre9\">^<\/code> and a <code class=\"calibre9\">$<\/code> to change the regular expression to <code class=\"calibre9\">^\\d$<\/code>, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Regex ageChecker = new(@\"^\\d$\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code again and note that it rejects any input except a single digit.<\/li>\n<li class=\"calibre3\">Add a <code class=\"calibre9\">+<\/code> after the <code class=\"calibre9\">\\d<\/code> expression to modify the meaning to one or more digits, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Regex ageChecker = new(@\"^\\d+$\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code again and note the regular expression only allows zero or positive whole numbers of any length.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"9.4.2\" id=\"calibre_link-473\">\n<h3 data-number=\"9.4.2\" class=\"calibre8\">Regular expression performance improvements<\/h3>\n<p class=\"rights\">The .NET types for working with regular expressions are used throughout the .NET platform and many of the apps built with it. As such, they have a significant impact on performance. But until now, they have not received much optimization attention from Microsoft.With .NET 5 and later, the types in the <code class=\"calibre9\">System.Text.RegularExpressions<\/code> namespace have rewritten implementations to squeeze out maximum performance. Common regular expression benchmarks using methods like <code class=\"calibre9\">IsMatch<\/code> are now five times faster. And the best thing is, you do not have to change your code to get the benefits!With .NET 7 and later, the <code class=\"calibre9\">IsMatch<\/code> method of the <code class=\"calibre9\">Regex<\/code> class now has an overload for a <code class=\"calibre9\">ReadOnlySpan&lt;char&gt;<\/code> as its input, which gives even better performance.<\/p>\n<\/section>\n<section data-number=\"9.4.3\" id=\"calibre_link-474\">\n<h3 data-number=\"9.4.3\" class=\"calibre8\">Understanding the syntax of a regular expression<\/h3>\n<p class=\"rights\">Some common symbols that you can use in regular expressions are shown in <em class=\"calibre10\">Table 8.5<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Symbol<\/td>\n<td class=\"calibre21\">Meaning<\/td>\n<td class=\"calibre21\">Symbol<\/td>\n<td class=\"calibre21\">Meaning<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">^<\/code><\/td>\n<td class=\"calibre21\">Start of input<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">$<\/code><\/td>\n<td class=\"calibre21\">End of input<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\\d<\/code><\/td>\n<td class=\"calibre21\">A single digit<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">\\D<\/code><\/td>\n<td class=\"calibre21\">A single <em class=\"calibre10\">non<\/em> -digit<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\\s<\/code><\/td>\n<td class=\"calibre21\">Whitespace<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">\\S<\/code><\/td>\n<td class=\"calibre21\"><em class=\"calibre10\">Non<\/em> -whitespace<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\\w<\/code><\/td>\n<td class=\"calibre21\">Word characters<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">\\W<\/code><\/td>\n<td class=\"calibre21\"><em class=\"calibre10\">Non<\/em> -word characters<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[A-Za-z0-9]<\/code><\/td>\n<td class=\"calibre21\">Range(s) of characters<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">\\^<\/code><\/td>\n<td class=\"calibre21\">^ (caret) character<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[aeiou]<\/code><\/td>\n<td class=\"calibre21\">Set of characters<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">[^aeiou]<\/code><\/td>\n<td class=\"calibre21\"><em class=\"calibre10\">Not<\/em> in a set of characters<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">.<\/code><\/td>\n<td class=\"calibre21\">Any single character<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">\\.<\/code><\/td>\n<td class=\"calibre21\">. (dot) character<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.5: Common regular expression symbols<\/p>\n<p class=\"rights\">In addition, some common regular expression quantifiers that affect the previous symbols in a regular expression are shown in <em class=\"calibre10\">Table 8.6<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Symbol<\/td>\n<td class=\"calibre21\">Meaning<\/td>\n<td class=\"calibre21\">Symbol<\/td>\n<td class=\"calibre21\">Meaning<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">+<\/code><\/td>\n<td class=\"calibre21\">One or more<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">?<\/code><\/td>\n<td class=\"calibre21\">One or none<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">{3}<\/code><\/td>\n<td class=\"calibre21\">Exactly three<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">{3,5}<\/code><\/td>\n<td class=\"calibre21\">Three to five<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">{3,}<\/code><\/td>\n<td class=\"calibre21\">At least three<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">{,3}<\/code><\/td>\n<td class=\"calibre21\">Up to three<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.6: Common regular expression quantifiers<br \/>\n<\/section>\n<section data-number=\"9.4.4\" id=\"calibre_link-475\">\n<h3 data-number=\"9.4.4\" class=\"calibre8\">Examples of regular expressions<\/h3>\n<p class=\"rights\">Some examples of regular expressions with a description of their meaning are shown in <em class=\"calibre10\">Table 8.7<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre19\"><\/col>\n<col class=\"calibre19\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Expression<\/td>\n<td class=\"calibre21\">Meaning<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\\d<\/code><\/td>\n<td class=\"calibre21\">A single digit somewhere in the input<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">a<\/code><\/td>\n<td class=\"calibre21\">The character \u201ca\u201d somewhere in the input<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Bob<\/code><\/td>\n<td class=\"calibre21\">The word \u201cBob\u201d somewhere in the input<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">^Bob<\/code><\/td>\n<td class=\"calibre21\">The word \u201cBob\u201d at the start of the input<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Bob$<\/code><\/td>\n<td class=\"calibre21\">The word \u201cBob\u201d at the end of the input<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">^\\d{2}$<\/code><\/td>\n<td class=\"calibre21\">Exactly two digits<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">^[0-9]{2}$<\/code><\/td>\n<td class=\"calibre21\">Exactly two digits<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">^[A-Z]{4,}$<\/code><\/td>\n<td class=\"calibre21\">At least four uppercase English letters in the ASCII character set only<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">^[A-Za-z]{4,}$<\/code><\/td>\n<td class=\"calibre21\">At least four upper or lowercase English letters in the ASCII character set only<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">^[A-Z]{2}\\d{3}$<\/code><\/td>\n<td class=\"calibre21\">Two uppercase English letters in the ASCII character set and three digits only<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">^[A-Za-z\\u00c0-\\u017e]+$<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">At least one uppercase or lowercase English letter in the ASCII character set or European letters in the Unicode character set, as shown in the following list:<\/p>\n<p class=\"rights\"><code class=\"calibre9\">\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">\u00de\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff\u0131\u0152\u0153\u0160\u0161\u0178\u017d\u017e<\/code><\/p>\n<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">^d.g$<\/code><\/td>\n<td class=\"calibre21\">The letter <code class=\"calibre9\">d<\/code> , then any character, and then the letter <code class=\"calibre9\">g<\/code> , so it would match both <code class=\"calibre9\">dig<\/code> and <code class=\"calibre9\">dog<\/code> or any single character between the <code class=\"calibre9\">d<\/code> and <code class=\"calibre9\">g<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">^d\\.g$<\/code><\/td>\n<td class=\"calibre21\">The letter <code class=\"calibre9\">d<\/code> , then a dot <code class=\"calibre9\">.<\/code> , and then the letter <code class=\"calibre9\">g<\/code> , so it would match <code class=\"calibre9\">d.g<\/code> only<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.7: Examples of regular expressions with descriptions of their meaning<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Use regular expressions to validate input from the user. The same regular expressions can be reused in other languages such as JavaScript and Python.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"9.4.5\" id=\"calibre_link-476\">\n<h3 data-number=\"9.4.5\" class=\"calibre8\">Splitting a complex comma-separated string<\/h3>\n<p class=\"rights\">Earlier in this chapter, you learned how to split a simple comma-separated string variable. But what about the following example of film titles?<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\"Monsters, Inc.\",\"I, Tonya\",\"Lock, Stock and Two Smoking Barrels\"<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">string<\/code> value uses double quotes around each film title. We can use these to identify whether we need to split on a comma (or not). The <code class=\"calibre9\">Split<\/code> method is not powerful enough, so we can use a regular expression instead.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You can read a fuller explanation in the Stack Overflow article that inspired this task at the following link: <a href=\"https:\/\/stackoverflow.com\/questions\/18144431\/regex-to-split-a-csv\">https:\/\/stackoverflow.com\/questions\/18144431\/regex-to-split-a-csv<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">To include double quotes inside a <code class=\"calibre9\">string<\/code> value, we prefix them with a backslash, or we could use the C# 11 raw string literal feature in C# 11 or later:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to store a complex comma-separated <code class=\"calibre9\">string<\/code> variable, and then split it in a dumb way using the <code class=\"calibre9\">Split<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ C# 1 to 10: Use escaped double-quote characters \\\"\n\/\/ string films = \"\\\"Monsters, Inc.\\\",\\\"I, Tonya\\\",\\\"Lock, Stock and Two Smoking Barrels\\\"\";\n\/\/ C# 11 or later: Use \"\"\" to start and end a raw string literal\nstring films = \"\"\"\n\"Monsters, Inc.\",\"I, Tonya\",\"Lock, Stock and Two Smoking Barrels\"\n\"\"\";\nWriteLine($\"Films to split: {films}\");\nstring[] filmsDumb = films.Split(',');\nWriteLine(\"Splitting with string.Split method:\"); \nforeach (string film in filmsDumb)\n{\n  WriteLine($\"  {film}\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add statements to define a regular expression to split and write the film titles in a smart way, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Regex csv = new(\n  \"(?:^|,)(?=[^\\\"]|(\\\")?)\\\"?((?(1)[^\\\"]*|[^,\\\"]*))\\\"?(?=,|$)\");\nMatchCollection filmsSmart = csv.Matches(films);\nWriteLine(\"Splitting with regular expression:\"); \nforeach (Match film in filmsSmart)\n{\n  WriteLine($\"  {film.Groups[2].Value}\");\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In a later section, you will see how you can get a source generator to auto-generate XML comments for a regular expression to explain how it works. This is really useful for regular expressions that you might have copied from a website.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Splitting with string.Split method:\n  \"Monsters\n   Inc.\" \n  \"I\n   Tonya\" \n  \"Lock\n   Stock and Two Smoking Barrels\" \nSplitting with regular expression: \n  Monsters, Inc.\n  I, Tonya\n  Lock, Stock and Two Smoking Barrels<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.4.6\" id=\"calibre_link-477\">\n<h3 data-number=\"9.4.6\" class=\"calibre8\">Activating regular expression syntax coloring<\/h3>\n<p class=\"rights\">If you use Visual Studio 2022 as your code editor, then you probably noticed that when passing a <code class=\"calibre9\">string<\/code> value to the <code class=\"calibre9\">Regex<\/code> constructor, you see color syntax highlighting, as shown in <em class=\"calibre10\">Figure 8.1<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 8.1: Regular expression color syntax highlighting when using the Regex constructor\" height=\"487\" src=\"\/images\/cs12\/000093.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 8.1: Regular expression color syntax highlighting when using the Regex constructor<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">This would be a good time to remind print book readers who will only see the preceding figure in grayscale that they can see all figures in full color as a PDF at the following link: <a href=\"https:\/\/static.packt-cdn.com\/downloads\/???_ColorImages.pdf\">https:\/\/static.packt-cdn.com\/downloads\/???_ColorImages.pdf<\/a><\/p>\n<\/blockquote>\n<p class=\"rights\">Why does this <code class=\"calibre9\">string<\/code> get syntax coloring for regular expressions when most <code class=\"calibre9\">string<\/code> values do not? Let's find out:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Right-click on the <code class=\"calibre9\">new<\/code> constructor, select <strong class=\"calibre2\">Go To Implementation<\/strong>, and note the <code class=\"calibre9\">string<\/code> parameter named <code class=\"calibre9\">pattern<\/code> is decorated with an attribute named <code class=\"calibre9\">StringSyntax<\/code> that has the <code class=\"calibre9\">string<\/code> constant <code class=\"calibre9\">Regex<\/code> value passed to it, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public Regex([StringSyntax(StringSyntaxAttribute.Regex)] string pattern) :\n  this(pattern, culture: null)\n{\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Right-click on the <code class=\"calibre9\">StringSyntax<\/code> attribute, select <strong class=\"calibre2\">Go To Implementation<\/strong>, and note there are 12 recognized <code class=\"calibre9\">string<\/code> syntax formats that you can choose from as well as <code class=\"calibre9\">Regex<\/code>, as shown in the following partial code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]\npublic sealed class StringSyntaxAttribute : Attribute\n{\n  public const string CompositeFormat = \"CompositeFormat\";\n  public const string DateOnlyFormat = \"DateOnlyFormat\";\n  public const string DateTimeFormat = \"DateTimeFormat\";\n  public const string EnumFormat = \"EnumFormat\";\n  public const string GuidFormat = \"GuidFormat\";\n  public const string Json = \"Json\";\n  public const string NumericFormat = \"NumericFormat\";\n  public const string Regex = \"Regex\";\n  public const string TimeOnlyFormat = \"TimeOnlyFormat\";\n  public const string TimeSpanFormat = \"TimeSpanFormat\";\n  public const string Uri = \"Uri\";\n  public const string Xml = \"Xml\";\n  \u2026\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithRegularExpressions<\/code> project, add a new class file named <code class=\"calibre9\">Program.Strings.cs<\/code>, delete any existing statements, and then define some <code class=\"calibre9\">string<\/code> constants in a partial <code class=\"calibre9\">Program<\/code> class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">partial class Program\n{\n  private const string DigitsOnlyText = @\"^\\d+$\";\n  private const string CommaSeparatorText = \n    \"(?:^|,)(?=[^\\\"]|(\\\")?)\\\"?((?(1)[^\\\"]*|[^,\\\"]*))\\\"?(?=,|$)\";\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note that the two <code class=\"calibre9\">string<\/code> constants do not have any color syntax highlighting yet.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, replace the literal <code class=\"calibre9\">string<\/code> with the <code class=\"calibre9\">string<\/code> constant for the digits-only regular expression, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Regex ageChecker = new(DigitsOnlyText);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, replace the literal <code class=\"calibre9\">string<\/code> with the <code class=\"calibre9\">string<\/code> constant for the comma-separator regular expression, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Regex csv = new(CommaSeparatorText);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the <code class=\"calibre9\">WorkingWithRegularExpressions<\/code> project and confirm that the regular expression behavior is as before.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Strings.cs<\/code>, import the namespace for the <code class=\"calibre9\">[StringSyntax]<\/code> attribute and then decorate both <code class=\"calibre9\">string<\/code> constants with it, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Diagnostics.CodeAnalysis; \/\/ To use [StringSyntax].\npartial class Program\n{\n  [StringSyntax(StringSyntaxAttribute.Regex)]\n  private const string DigitsOnlyText = @\"^\\d+$\";\n  [StringSyntax(StringSyntaxAttribute.Regex)]\n  private const string CommaSeparatorText = \n    \"(?:^|,)(?=[^\\\"]|(\\\")?)\\\"?((?(1)[^\\\"]*|[^,\\\"]*))\\\"?(?=,|$)\";\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Strings.cs<\/code>, add another <code class=\"calibre9\">string<\/code> constant for formatting a date, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[StringSyntax(StringSyntaxAttribute.DateTimeFormat)]\nprivate const string FullDateTime = \"\";<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Click inside the empty string, type the letter <code class=\"calibre9\">d<\/code>, and note the IntelliSense, as shown in <em class=\"calibre10\">Figure 8.2<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 8.2: IntelliSense activated due to the StringSyntax attribute\" height=\"775\" src=\"\/images\/cs12\/000110.png\" width=\"2161\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 8.2: IntelliSense activated due to the StringSyntax attribute<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Finish entering the date format and as you type, note the IntelliSense: <code class=\"calibre9\">dddd, d MMMM yyyy<\/code>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Inside, at the end of the <code class=\"calibre9\">DigitsOnlyText<\/code> string literal, enter a <code class=\"calibre9\">\\<\/code>, and note the IntelliSense to help you write a valid regular expression, as shown in <em class=\"calibre10\">Figure 8.3<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 8.3: IntelliSense for writing a regular expression\" height=\"775\" src=\"\/images\/cs12\/000027.png\" width=\"2161\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 8.3: IntelliSense for writing a regular expression<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Delete the <code class=\"calibre9\">\\<\/code> that you entered to trigger IntelliSense.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">[StringSyntax]<\/code> attribute is a new feature introduced in .NET 7. It depends on your code editor whether it is recognized. The .NET BCL has more than 350 parameters, properties, and fields that are now decorated with this attribute.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"9.4.7\" id=\"calibre_link-478\">\n<h3 data-number=\"9.4.7\" class=\"calibre8\">Improving regular expression performance with source generators<\/h3>\n<p class=\"rights\">When you pass a <code class=\"calibre9\">string<\/code> literal or <code class=\"calibre9\">string<\/code> constant to the constructor of <code class=\"calibre9\">Regex<\/code>, the class parses the string and transforms it into an internal tree structure that represents the expression in an optimized way that can be executed efficiently by a regular expression interpreter.You can also compile regular expressions by specifying a <code class=\"calibre9\">RegexOptions<\/code>, as in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Regex ageChecker = new(DigitsOnlyText, RegexOptions.Compiled);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Unfortunately, compiling has the negative effect of slowing down the initial creation of the regular expression. After creating the tree structure that would then be executed by the interpreter, the compiler then must convert the tree into IL code, and then that IL code needs to be JIT compiled into native code. If you\u2019re only running the regular expression a few times, it is not worth compiling it, which is why it is not the default behavior. If you\u2019re running the regular expression more than a few times, for example, because it will be used to validate the URL for every incoming HTTP request to a website, then it is worth compiling. But even then, you should only use compilation if you must use .NET 6 or earlier..NET 7 introduced a source generator for regular expressions that recognizes if you decorate a partial method that returns <code class=\"calibre9\">Regex<\/code> with the <code class=\"calibre9\">[GeneratedRegex]<\/code> attribute. It generates an implementation of that method that implements the logic for the regular expression.Let's see it in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithRegularExpressions<\/code> project, add a new class file named <code class=\"calibre9\">Program.Regexs.cs<\/code> and modify its content to define some <code class=\"calibre9\">partial<\/code> methods, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Text.RegularExpressions; \/\/ To use [GeneratedRegex].\npartial class Program\n{\n  [GeneratedRegex(DigitsOnlyText, RegexOptions.IgnoreCase)]\n  private static partial Regex DigitsOnly();\n  [GeneratedRegex(CommaSeparatorText, RegexOptions.IgnoreCase)]\n  private static partial Regex CommaSeparator();\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, replace the <code class=\"calibre9\">new<\/code> constructor with a call to the partial method that returns the digits-only regular expression, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Regex ageChecker = DigitsOnly();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, replace the new constructor with a call to the partial method that returns the comma-separator regular expression, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Regex csv = CommaSeparator();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Hover your mouse pointer over the partial methods and note the tooltip describes the behavior of the regular expression, as shown in <em class=\"calibre10\">Figure 8.4<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 8.4: Tooltip for a partial method shows a description of the regular expression\" height=\"759\" src=\"\/images\/cs12\/000045.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 8.4: Tooltip for a partial method shows a description of the regular expression<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Right-click the <code class=\"calibre9\">DigitsOnly<\/code> partial method, select <strong class=\"calibre2\">Go To Definition<\/strong>, and note that you can review the implementation of the auto-generated partial methods, as shown in <em class=\"calibre10\">Figure 8.5<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 8.5: The auto-generated source code for the regular expression\" height=\"759\" src=\"\/images\/cs12\/000061.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 8.5: The auto-generated source code for the regular expression<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Run the project and confirm that the functionality is the same as before.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can learn more about the improvements to regular expressions with .NET 7 at the following link: <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/regular-expression-improvements-in-dotnet-7\">https:\/\/devblogs.microsoft.com\/dotnet\/regular-expression-improvements-in-dotnet-7<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"9.5\" id=\"calibre_link-479\">\n<h2 data-number=\"9.5\" class=\"calibre5\">Storing multiple objects in collections<\/h2>\n<p class=\"rights\">Another of the most common types of data is collections. If you need to store multiple values in a variable, then you can use a collection.A collection is a data structure in memory that can manage multiple items in different ways, although all collections have some shared functionality.The most common types in .NET for working with collections are shown in <em class=\"calibre10\">Table 8.8<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre25\"><\/col>\n<col class=\"calibre25\"><\/col>\n<col class=\"calibre25\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Namespace<\/td>\n<td class=\"calibre21\">Example type(s)<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System .Collections<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">IEnumerable<\/code> ,<br class=\"calibre1\" \/><br \/>\n<code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code><\/td>\n<td class=\"calibre21\">Interfaces and base classes used by collections.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System .Collections .Generic<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">List&lt;T&gt;<\/code> ,<br class=\"calibre1\" \/><br \/>\n<code class=\"calibre9\">Dictionary&lt;T&gt;<\/code> ,<br class=\"calibre1\" \/><br \/>\n<code class=\"calibre9\">Queue&lt;T&gt;<\/code> ,<br class=\"calibre1\" \/><br \/>\n<code class=\"calibre9\">Stack&lt;T&gt;<\/code><\/td>\n<td class=\"calibre21\">Introduced in C# 2.0 with .NET Framework 2.0. These collections allow you to specify the type you want to store using a generic type parameter (which is safer, faster, and more efficient).<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System .Collections .Concurrent<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">BlockingCollection<\/code> ,<br class=\"calibre1\" \/><br \/>\n<code class=\"calibre9\">ConcurrentDictionary<\/code> ,<br class=\"calibre1\" \/><br \/>\n<code class=\"calibre9\">ConcurrentQueue<\/code><\/td>\n<td class=\"calibre21\">These collections are safe to use in multithreaded scenarios.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System .Collections .Immutable<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">ImmutableArray<\/code> ,<br class=\"calibre1\" \/><br \/>\n<code class=\"calibre9\">ImmutableDictionary<\/code> ,<br class=\"calibre1\" \/><br \/>\n<code class=\"calibre9\">ImmutableList<\/code> ,<br class=\"calibre1\" \/><br \/>\n<code class=\"calibre9\">ImmutableQueue<\/code><\/td>\n<td class=\"calibre21\">Designed for scenarios where the contents of the original collection will never change, although they can create modified collections as a new instance.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.8: Common .NET collection types<\/p>\n<section data-number=\"9.5.1\" id=\"calibre_link-480\">\n<h3 data-number=\"9.5.1\" class=\"calibre8\">Common features of all collections<\/h3>\n<p class=\"rights\">All collections implement the <code class=\"calibre9\">ICollection<\/code> interface; this means that they must have a <code class=\"calibre9\">Count<\/code> property to tell you how many objects are in them, and three other members, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace System.Collections;\npublic interface ICollection : IEnumerable\n{\n  int Count { get; }\n  bool IsSynchronized { get; }\n  object SyncRoot { get; }\n  void CopyTo(Array array, int index);\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">For example, if we had a collection named <code class=\"calibre9\">passengers<\/code>, we could do this:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int howMany = passengers.Count;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">As you have probably surmised, <code class=\"calibre9\">CopyTo<\/code> copies the collection to an array. <code class=\"calibre9\">IsSynchronized<\/code> and <code class=\"calibre9\">SyncRoot<\/code> are used in multithreading scenarios, so I do not cover them in this book.All collections implement the <code class=\"calibre9\">IEnumerable<\/code> interface, which means that they can be iterated using the <code class=\"calibre9\">foreach<\/code> statement. They must have a <code class=\"calibre9\">GetEnumerator<\/code> method that returns an object that implements <code class=\"calibre9\">IEnumerator<\/code>; this means that the returned <code class=\"calibre9\">object<\/code> must have <code class=\"calibre9\">MoveNext<\/code> and <code class=\"calibre9\">Reset<\/code> methods for navigating through the collection and a <code class=\"calibre9\">Current<\/code> property containing the current item in the collection, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace System.Collections;\npublic interface IEnumerable\n{\n  IEnumerator GetEnumerator();\n}\npublic interface IEnumerator\n{\n  object Current { get; }\n  bool MoveNext();\n  void Reset();\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">For example, to perform an action on each object in the <code class=\"calibre9\">passengers<\/code> collection, we could write the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">foreach (Passenger p in passengers)\n{\n  \/\/ Perform an action on each passenger.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">As well as the <code class=\"calibre9\">object<\/code>-based collection interface, there is also a generic collection interface, where the generic type defines the type stored in the collection. It has additional members like <code class=\"calibre9\">IsReadOnly<\/code>, <code class=\"calibre9\">Add<\/code>, <code class=\"calibre9\">Clear<\/code>, <code class=\"calibre9\">Contains<\/code>, and <code class=\"calibre9\">Remove<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace System.Collections.Generic;\npublic interface ICollection&lt;T&gt; : IEnumerable&lt;T&gt;, IEnumerable\n{\n  int Count { get; }\n  bool IsReadOnly { get; }\n  void Add(T item);\n  void Clear();\n  bool Contains(T item);\n  void CopyTo(T[] array, int index);\n  bool Remove(T item);\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.5.2\" id=\"calibre_link-481\">\n<h3 data-number=\"9.5.2\" class=\"calibre8\">Working with lists<\/h3>\n<p class=\"rights\">Lists, that is, a type that implements <code class=\"calibre9\">IList&lt;T&gt;<\/code>, are <strong class=\"calibre2\">ordered collections<\/strong>, with an <code class=\"calibre9\">int<\/code> index to show the position of an item within the list, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace System.Collections.Generic;\n[DefaultMember(\"Item\")] \/\/ aka \"this\" indexer.\npublic interface IList&lt;T&gt; : ICollection&lt;T&gt;, IEnumerable&lt;T&gt;, IEnumerable\n{\n  T this[int index] { get; set; }\n  int IndexOf(T item);\n  void Insert(int index, T item);\n  void RemoveAt(int index);\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">[DefaultMember]<\/code> attribute allows you to specify which member is accessed by default when no member name is specified. To make <code class=\"calibre9\">IndexOf<\/code> the default member, you would use <code class=\"calibre9\">[DefaultMember(\"IndexOf\")]<\/code>. To specify the indexer, you use <code class=\"calibre9\">[DefaultMember(\"Item\")]<\/code>.<\/p>\n<\/blockquote>\n<p class=\"rights\"><code class=\"calibre9\">IList&lt;T&gt;<\/code> derives from <code class=\"calibre9\">ICollection&lt;T&gt;<\/code>, so it has a <code class=\"calibre9\">Count<\/code> property, and an <code class=\"calibre9\">Add<\/code> method to put an item at the end of the collection, as well as an <code class=\"calibre9\">Insert<\/code> method to put an item in the list at a specified position, and <code class=\"calibre9\">RemoveAt<\/code> to remove an item at a specified position.Lists are a good choice when you want to manually control the order of items in a collection. Each item in a list has a unique index (or position) that is automatically assigned. Items can be any type defined by <code class=\"calibre9\">T<\/code> and items can be duplicated. Indexes are <code class=\"calibre9\">int<\/code> types and start from <code class=\"calibre9\">0<\/code>, so the first item in a list is at index <code class=\"calibre9\">0<\/code>, as shown in <em class=\"calibre10\">Table 8.9<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Index<\/td>\n<td class=\"calibre21\">Item<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">0<\/td>\n<td class=\"calibre21\">London<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">1<\/td>\n<td class=\"calibre21\">Paris<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">London<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">3<\/td>\n<td class=\"calibre21\">Sydney<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.9: Cities in a list with indexes<\/p>\n<p class=\"rights\">If a new item (for example, Santiago) is inserted between London and Sydney, then the index of Sydney is automatically incremented. Therefore, you must be aware that an item\u2019s index can change after inserting or removing items, as shown in <em class=\"calibre10\">Table 8.10<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Index<\/td>\n<td class=\"calibre21\">Item<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">0<\/td>\n<td class=\"calibre21\">London<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">1<\/td>\n<td class=\"calibre21\">Paris<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">London<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">3<\/td>\n<td class=\"calibre21\">Santiago<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">4<\/td>\n<td class=\"calibre21\">Sydney<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.10: Cities list after an item is inserted<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Some developers can get into a poor habit of using <code class=\"calibre9\">List&lt;T&gt;<\/code> and other collections when an array would be better. Use arrays instead of collections if the data will not change size after instantiation. You should also use lists initially while you are adding and removing items, but then convert them into an array once you are done with manipulating the items.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's explore lists:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">WorkingWithCollections<\/code> to the <code class=\"calibre9\">Chapter08<\/code> solution.<\/li>\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Program.Helpers.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Helpers.cs<\/code>, define a partial <code class=\"calibre9\">Program<\/code> class with a generic method to output a collection of <code class=\"calibre9\">T<\/code> values with a title, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">partial class Program\n{\n  private static void OutputCollection&lt;T&gt;(\n    string title, IEnumerable&lt;T&gt; collection)\n  {\n    WriteLine($\"{title}:\");\n    foreach (T item in collection)\n    {\n      WriteLine($\"  {item}\");\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then add some statements to illustrate some of the common ways of defining and working with lists, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Simple syntax for creating a list and adding three items.\nList&lt;string&gt; cities = new(); \ncities.Add(\"London\"); \ncities.Add(\"Paris\"); \ncities.Add(\"Milan\");\n\/* Alternative syntax that is converted by the compiler into\n   the three Add method calls above.\nList&lt;string&gt; cities = new()\n  { \"London\", \"Paris\", \"Milan\" }; *\/\n\/* Alternative syntax that passes an array\n   of string values to AddRange method.\nList&lt;string&gt; cities = new(); \ncities.AddRange(new[] { \"London\", \"Paris\", \"Milan\" }); *\/\nOutputCollection(\"Initial list\", cities);\nWriteLine($\"The first city is {cities[0]}.\"); \nWriteLine($\"The last city is {cities[cities.Count - 1]}.\");\ncities.Insert(0, \"Sydney\");\nOutputCollection(\"After inserting Sydney at index 0\", cities); \ncities.RemoveAt(1); \ncities.Remove(\"Milan\");\nOutputCollection(\"After removing two cities\", cities);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Initial list:\n  London\n  Paris\n  Milan\nThe first city is London. \nThe last city is Milan.\nAfter inserting Sydney at index 0:\n  Sydney\n  London\n  Paris\n  Milan\nAfter removing two cities:\n  Sydney\n  Paris<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.5.3\" id=\"calibre_link-482\">\n<h3 data-number=\"9.5.3\" class=\"calibre8\">Working with dictionaries<\/h3>\n<p class=\"rights\">Dictionaries are a good choice when each <strong class=\"calibre2\">value<\/strong> (or object) has a unique sub-value (or a made-up value) that can be used as a <strong class=\"calibre2\">key<\/strong> to quickly find a value in the collection later. The key must be unique. For example, if you are storing a list of people, you could choose to use a government-issued identity number as the key. Dictionaries are called <strong class=\"calibre2\">hashmaps<\/strong> in other languages like Python and Java.Think of the key as being like an index entry in a real-world dictionary. It allows you to quickly find the definition of a word because the words (in other words, keys) are kept sorted; if we know we're looking for the definition of <em class=\"calibre10\">manatee<\/em>, we will jump to the middle of the dictionary to start looking, because the letter <em class=\"calibre10\">m<\/em> is in the middle of the alphabet.Dictionaries in programming are similarly smart when looking something up. They must implement the interface <code class=\"calibre9\">IDictionary&lt;TKey, TValue&gt;<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace System.Collections.Generic;\n[DefaultMember(\"Item\")] \/\/ aka \"this\" indexer.\npublic interface IDictionary&lt;TKey, TValue&gt;\n  : ICollection&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;,\n    IEnumerable&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;, IEnumerable\n{\n  TValue this[TKey key] { get; set; }\n  ICollection&lt;TKey&gt; Keys { get; }\n  ICollection&lt;TValue&gt; Values { get; }\n  void Add(TKey key, TValue value);\n  bool ContainsKey(TKey key);\n  bool Remove(TKey key);\n  bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value);\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Items in a dictionary are instances of the <code class=\"calibre9\">struct<\/code>, aka the value type, <code class=\"calibre9\">KeyValuePair&lt;TKey, TValue&gt;<\/code>, where <code class=\"calibre9\">TKey<\/code> is the type of the key and <code class=\"calibre9\">TValue<\/code> is the type of the value, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace System.Collections.Generic;\npublic readonly struct KeyValuePair&lt;TKey, TValue&gt;\n{\n  public KeyValuePair(TKey key, TValue value);\n  public TKey Key { get; }\n  public TValue Value { get; }\n  [EditorBrowsable(EditorBrowsableState.Never)]\n  public void Deconstruct(out TKey key, out TValue value);\n  public override string ToString();\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">An example <code class=\"calibre9\">Dictionary&lt;string, Person&gt;<\/code> uses a <code class=\"calibre9\">string<\/code> as the key and a <code class=\"calibre9\">Person<\/code> instance as the value. <code class=\"calibre9\">Dictionary&lt;string, string&gt;<\/code> uses <code class=\"calibre9\">string<\/code> values for both, as shown in <em class=\"calibre10\">Table 8.11<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Key<\/td>\n<td class=\"calibre21\">Value<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">BSA<\/td>\n<td class=\"calibre21\">Bob Smith<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">MW<\/td>\n<td class=\"calibre21\">Max Williams<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">BSB<\/td>\n<td class=\"calibre21\">Bob Smith<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">AM<\/td>\n<td class=\"calibre21\">Amir Mohammed<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.11: Dictionary with keys and values<\/p>\n<p class=\"rights\">Let's explore dictionaries:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.cs<\/code>, define an alias for the <code class=\"calibre9\">Dictionary&lt;TKey, TValue&gt;<\/code> class where <code class=\"calibre9\">TKey<\/code> and <code class=\"calibre9\">TValue<\/code> are both <code class=\"calibre9\">string<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Define an alias for a dictionary with string key and string value.\nusing StringDictionary = System.Collections.Generic.Dictionary&lt;string, string&gt;;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add some statements to illustrate some of the common ways of working with dictionaries, for example, looking up word definitions, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Declare a dictionary without the alias.\n\/\/ Dictionary&lt;string, string&gt; keywords = new();\n\/\/ Use the alias to declare the dictionary.\nStringDictionary keywords = new();\n\/\/ Add using named parameters.\nkeywords.Add(key: \"int\", value: \"32-bit integer data type\");\n\/\/ Add using positional parameters.\nkeywords.Add(\"long\", \"64-bit integer data type\"); \nkeywords.Add(\"float\", \"Single precision floating point number\");\n\/* Alternative syntax; compiler converts this to calls to Add method.\nDictionary&lt;string, string&gt; keywords = new()\n{\n  { \"int\", \"32-bit integer data type\" },\n  { \"long\", \"64-bit integer data type\" },\n  { \"float\", \"Single precision floating point number\" },\n}; *\/\n\/* Alternative syntax; compiler converts this to calls to Add method.\nDictionary&lt;string, string&gt; keywords = new()\n{\n  [\"int\"] = \"32-bit integer data type\",\n  [\"long\"] = \"64-bit integer data type\",\n  [\"float\"] = \"Single precision floating point number\",\n}; *\/\nOutputCollection(\"Dictionary keys\", keywords.Keys);\nOutputCollection(\"Dictionary values\", keywords.Values);\nWriteLine(\"Keywords and their definitions:\");\nforeach (KeyValuePair&lt;string, string&gt; item in keywords)\n{\n  WriteLine($\"  {item.Key}: {item.Value}\");\n}\n\/\/ Look up a value using a key.\nstring key = \"long\";\nWriteLine($\"The definition of {key} is {keywords[key]}.\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The trailing commas after the third item is added to the dictionary are optional and the compiler will not complain about them. This is convenient so that you can change the order of the three items without having to delete and add commas in the right places.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Dictionary keys:\n  int\n  long\n  float\nDictionary values:\n  32-bit integer data type\n  64-bit integer data type\n  Single precision floating point number\nKeywords and their definitions:\n  int: 32-bit integer data type\n  long: 64-bit integer data type\n  float: Single precision floating point number\nThe definition of long is 64-bit integer data type<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In <em class=\"calibre10\">Chapter 11<\/em>, <em class=\"calibre10\">Querying and Manipulating Data Using LINQ<\/em>, you will learn how to create dictionaries and lookups from existing data sources like tables in a database using LINQ methods like <code class=\"calibre9\">ToDictionary<\/code> and <code class=\"calibre9\">ToLookup<\/code>. This is much more common than manually adding items to a dictionary as shown in this section.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"9.5.4\" id=\"calibre_link-483\">\n<h3 data-number=\"9.5.4\" class=\"calibre8\">Sets, stacks, and queues<\/h3>\n<p class=\"rights\"><strong class=\"calibre2\">Sets<\/strong> are a good choice when you want to perform set operations between two collections. For example, you may have two collections of city names, and you want to know which names appear in both sets (known as the <em class=\"calibre10\">intersect<\/em> between the sets). Items in a set must be unique. Common set methods are shown in <em class=\"calibre10\">Table 8.12<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Method<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Add<\/code><\/td>\n<td class=\"calibre21\">If the item does not already exist in the set, then it is added. Returns <code class=\"calibre9\">true<\/code> if the item was added, and <code class=\"calibre9\">false<\/code> if it was already in the set.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ExceptWith<\/code><\/td>\n<td class=\"calibre21\">Removes the items in the set passed as the parameter from the set.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">IntersectWith<\/code><\/td>\n<td class=\"calibre21\">Removes the items not in the set passed as the parameter and in the set.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">IsProperSubsetOf<\/code> , <code class=\"calibre9\">IsProperSupersetOf<\/code> , <code class=\"calibre9\">IsSubsetOf<\/code> , <code class=\"calibre9\">IsSupersetOf<\/code><\/td>\n<td class=\"calibre21\">A subset is a set whose items are all in the other set. A proper subset is a set whose items are all in the other set but there is at least one item in the other set that is not in the set. A superset is a set that contains all the items in the other set. A proper superset is a set that contains all the items in the other set and at least one more not in the other set.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Overlaps<\/code><\/td>\n<td class=\"calibre21\">The set and the other set share at least one common item.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">SetEquals<\/code><\/td>\n<td class=\"calibre21\">The set and the other set contain exactly the same items.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">SymmetricExceptWith<\/code><\/td>\n<td class=\"calibre21\">Removes the items not in the set passed as the parameter from the set and adds any that are missing.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">UnionWith<\/code><\/td>\n<td class=\"calibre21\">Adds any items in the set passed as the parameter to the set that are not already in the set.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.12: Set methods<\/p>\n<p class=\"rights\">Let's explore example code for sets:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add some statements to add items to a set, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">HashSet&lt;string&gt; names = new();\nforeach (string name in\n  new[] { \"Adam\", \"Barry\", \"Charlie\", \"Barry\" })\n{\n  bool added = names.Add(name);\n  WriteLine($\"{name} was added: {added}.\");\n}\nWriteLine($\"names set: {string.Join(',', names)}.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Adam was added: True.\nBarry was added: True.\nCharlie was added: True.\nBarry was added: False.\nnames set: Adam,Barry,Charlie.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You will see more set operations in <em class=\"calibre10\">Chapter 11<\/em>, <em class=\"calibre10\">Querying and Manipulating Data Using LINQ<\/em>.<strong class=\"calibre2\">Stacks<\/strong> are a good choice when you want to implement <strong class=\"calibre2\">last-in, first-out<\/strong> (<strong class=\"calibre2\">LIFO<\/strong>) behavior. With a stack, you can only directly access or remove the one item at the top of the stack, although you can enumerate to read through the whole stack of items. You cannot, for example, directly access the second item in a stack.For example, word processors use a stack to remember the sequence of actions you have recently performed, and then when you press <span>Ctrl<\/span> + <span>Z<\/span>, it will undo the last action in the stack, and then the next-to-last action, and so on.<strong class=\"calibre2\">Queues<\/strong> are a good choice when you want to implement the <strong class=\"calibre2\">first-in, first-out<\/strong> (<strong class=\"calibre2\">FIFO<\/strong>) behavior. With a queue, you can only directly access or remove the item at the front of the queue, although you can enumerate to read through the whole queue of items. You cannot, for example, directly access the second item in a queue.For example, background processes use a queue to process work items in the order that they arrive, just like people standing in line at the post office..NET 6 introduced the <code class=\"calibre9\">PriorityQueue<\/code>, where each item in the queue has a priority value assigned, as well as its position in the queue.Let's explore example code for queues:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add some statements to illustrate some of the common ways of working with queues, for example, handling customers in a queue for coffee, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Queue&lt;string&gt; coffee = new();\ncoffee.Enqueue(\"Damir\"); \/\/ Front of the queue.\ncoffee.Enqueue(\"Andrea\");\ncoffee.Enqueue(\"Ronald\");\ncoffee.Enqueue(\"Amin\");\ncoffee.Enqueue(\"Irina\"); \/\/ Back of the queue.\nOutputCollection(\"Initial queue from front to back\", coffee);\n\/\/ Server handles next person in queue.\nstring served = coffee.Dequeue();\nWriteLine($\"Served: {served}.\");\n\/\/ Server handles next person in queue.\nserved = coffee.Dequeue();\nWriteLine($\"Served: {served}.\");\nOutputCollection(\"Current queue from front to back\", coffee);\nWriteLine($\"{coffee.Peek()} is next in line.\");\nOutputCollection(\"Current queue from front to back\", coffee);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Initial queue from front to back:\n  Damir\n  Andrea\n  Ronald\n  Amin\n  Irina\nServed: Damir.\nServed: Andrea.\nCurrent queue from front to back:\n  Ronald\n  Amin\n  Irina\nRonald is next in line.\nCurrent queue from front to back:\n  Ronald\n  Amin\n  Irina<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Helpers.cs<\/code>, in the partial <code class=\"calibre9\">Program<\/code> class, add a static method named <code class=\"calibre9\">OutputPQ<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void OutputPQ&lt;TElement, TPriority&gt;(string title,\n  IEnumerable&lt;(TElement Element, TPriority Priority)&gt; collection)\n{\n  WriteLine($\"{title}:\");\n  foreach ((TElement, TPriority) item in collection)\n  {\n    WriteLine($\"  {item.Item1}: {item.Item2}\");\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note that the <code class=\"calibre9\">OutputPQ<\/code> method is generic. You can specify the two types used in the tuples that are passed in as <code class=\"calibre9\">collection<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add some statements to illustrate some of the common ways of working with priority queues, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">PriorityQueue&lt;string, int&gt; vaccine = new();\n\/\/ Add some people.\n\/\/ 1 = High priority people in their 70s or poor health.\n\/\/ 2 = Medium priority e.g. middle-aged.\n\/\/ 3 = Low priority e.g. teens and twenties.\nvaccine.Enqueue(\"Pamela\", 1);\nvaccine.Enqueue(\"Rebecca\", 3);\nvaccine.Enqueue(\"Juliet\", 2);\nvaccine.Enqueue(\"Ian\", 1);\nOutputPQ(\"Current queue for vaccination\", vaccine.UnorderedItems);\nWriteLine($\"{vaccine.Dequeue()} has been vaccinated.\");\nWriteLine($\"{vaccine.Dequeue()} has been vaccinated.\");\nOutputPQ(\"Current queue for vaccination\", vaccine.UnorderedItems);\nWriteLine($\"{vaccine.Dequeue()} has been vaccinated.\");\nWriteLine(\"Adding Mark to queue with priority 2.\");\nvaccine.Enqueue(\"Mark\", 2);\nWriteLine($\"{vaccine.Peek()} will be next to be vaccinated.\");\nOutputPQ(\"Current queue for vaccination\", vaccine.UnorderedItems);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Current queue for vaccination:\n  Pamela: 1\n  Rebecca: 3\n  Juliet: 2\n  Ian: 1\nPamela has been vaccinated.\nIan has been vaccinated.\nCurrent queue for vaccination:\n  Juliet: 2\n  Rebecca: 3\nJuliet has been vaccinated.\nAdding Mark to queue with priority 2\nMark will be next to be vaccinated.\nCurrent queue for vaccination:\n  Mark: 2\n  Rebecca: 3<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.5.5\" id=\"calibre_link-484\">\n<h3 data-number=\"9.5.5\" class=\"calibre8\">Collection add and remove methods<\/h3>\n<p class=\"rights\">Each collection has a different set of methods to \"add\" and \"remove\" items, as shown in <em class=\"calibre10\">Table 8.13<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Collection<\/td>\n<td class=\"calibre21\">\"Add\" methods<\/td>\n<td class=\"calibre21\">\"Remove\" methods<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">List<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Add<\/code> , <code class=\"calibre9\">Insert<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Remove<\/code> , <code class=\"calibre9\">RemoveAt<\/code><\/td>\n<td class=\"calibre21\">Lists are ordered so items have an integer index position. <code class=\"calibre9\">Add<\/code> will add a new item at the end of the list. <code class=\"calibre9\">Insert<\/code> will add a new item at the index position specified.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Dictionary<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Add<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Remove<\/code><\/td>\n<td class=\"calibre21\">Dictionaries are not ordered so items do not have integer index positions. You can check if a key has been used by calling the <code class=\"calibre9\">ContainsKey<\/code> method.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Stack<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Push<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Pop<\/code><\/td>\n<td class=\"calibre21\">Stacks always add a new item at the top of the stack using the <code class=\"calibre9\">Push<\/code> method. The first item is at the bottom. Items are always removed from the top of the stack using the <code class=\"calibre9\">Pop<\/code> method. Call the <code class=\"calibre9\">Peek<\/code> method to see this value without removing it. Stacks are LIFO.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Queue<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Enqueue<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Dequeue<\/code><\/td>\n<td class=\"calibre21\">Queues always add a new item at the end of the queue using the <code class=\"calibre9\">Enqueue<\/code> method. The first item is at the front of the queue. Items are always removed from the front of the queue using the <code class=\"calibre9\">Dequeue<\/code> method. Call the <code class=\"calibre9\">Peek<\/code> method to see this value without removing it. Queues are FIFO.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.13: Collection \"add\" and \"remove\" methods<br \/>\n<\/section>\n<section data-number=\"9.5.6\" id=\"calibre_link-485\">\n<h3 data-number=\"9.5.6\" class=\"calibre8\">Sorting collections<\/h3>\n<p class=\"rights\">A <code class=\"calibre9\">List&lt;T&gt;<\/code> class can be sorted by manually calling its <code class=\"calibre9\">Sort<\/code> method (but remember that the indexes of each item will change). Manually sorting a list of <code class=\"calibre9\">string<\/code> values or other built-in types will work without extra effort on your part, but if you create a collection of your own type, then that type must implement an interface named <code class=\"calibre9\">IComparable<\/code>. You learned how to do this in <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>.A <code class=\"calibre9\">Stack&lt;T&gt;<\/code> or <code class=\"calibre9\">Queue&lt;T&gt;<\/code> collection cannot be sorted because you wouldn't usually want that functionality; for example, you would probably never sort a queue of guests checking into a hotel. But sometimes, you might want to sort a dictionary or a set.Sometimes it would be useful to have an automatically sorted collection, that is, one that maintains the items in a sorted order as you add and remove them.There are multiple auto-sorting collections to choose from. The differences between these sorted collections are often subtle but can have an impact on the memory requirements and performance of your application, so it is worth putting effort into picking the most appropriate option for your requirements.Some common auto-sorting collections are shown in <em class=\"calibre10\">Table 8.14<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Collection<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">SortedDictionary&lt;TKey, TValue&gt;<\/code><\/td>\n<td class=\"calibre21\">This represents a collection of key\/value pairs that are sorted by key. Internally it maintains a binary tree for items.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">SortedList&lt;TKey, TValue&gt;<\/code><\/td>\n<td class=\"calibre21\">This represents a collection of key-value pairs that are sorted by key. The name is misleading because this is not a list. Compared to <code class=\"calibre9\">SortedDictionary&lt;TKey, TValue&gt;<\/code> , retrieval performance is similar, it uses less memory, and insert and remove operations are slower for unsorted data. If it is populated from sorted data, then it is faster. Internally, it maintains a sorted array with a binary search to find elements.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">SortedSet&lt;T&gt;<\/code><\/td>\n<td class=\"calibre21\">This represents a collection of unique objects that are maintained in a sorted order.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 8.14: Common auto-sorting collections<br \/>\n<\/section>\n<section data-number=\"9.5.7\" id=\"calibre_link-486\">\n<h3 data-number=\"9.5.7\" class=\"calibre8\">Specialized collections<\/h3>\n<p class=\"rights\">There are a few other collections for special situations.The <code class=\"calibre9\">System.Collections.BitArray<\/code> collection manages a compact array of bit values, which are represented as Booleans, where <code class=\"calibre9\">true<\/code> indicates that the bit is on (value is 1) and <code class=\"calibre9\">false<\/code> indicates that the bit is off (value is 0).The <code class=\"calibre9\">System.Collections.Generics.LinkedList&lt;T&gt;<\/code> collection represents a doubly linked list where every item has a reference to its previous and next items. They provide better performance compared to <code class=\"calibre9\">List&lt;T&gt;<\/code> for scenarios where you will frequently insert and remove items from the middle of the list. In a <code class=\"calibre9\">LinkedList&lt;T&gt;<\/code>, the items do not have to be rearranged in memory.<\/p>\n<\/section>\n<section data-number=\"9.5.8\" id=\"calibre_link-487\">\n<h3 data-number=\"9.5.8\" class=\"calibre8\">Read-only, immutable, and frozen collections<\/h3>\n<p class=\"rights\">When we looked at the generic collection interface, we saw that it has a property named <code class=\"calibre9\">IsReadOnly<\/code>. This is useful when we want to pass a collection to a method but not allow it to make changes.For example, we might define a method, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">void ReadCollection&lt;T&gt;(ICollection&lt;T&gt; collection)\n{\n  \/\/ We can check if the collection is read-only.\n  if (collection.IsReadOnly)\n  {\n    \/\/ Read the collection.\n  }\n  else\n  {\n    WriteLine(\"You have given me a collection that I could change!\");\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Generic collections like <code class=\"calibre9\">List&lt;T&gt;<\/code> and <code class=\"calibre9\">Dictionary&lt;TKey, TValue&gt;<\/code> have an <code class=\"calibre9\">AsReadOnly<\/code> method to create a <code class=\"calibre9\">ReadOnlyCollection&lt;T&gt;<\/code> that references the original collection. Although the <code class=\"calibre9\">ReadOnlyCollection&lt;T&gt;<\/code> has to have an <code class=\"calibre9\">Add<\/code> and a <code class=\"calibre9\">Remove<\/code> method because it implements <code class=\"calibre9\">ICollection&lt;T&gt;<\/code>, it throws a <code class=\"calibre9\">NotImplementedException<\/code> to prevent changes. If the original collection has items added or removed, the <code class=\"calibre9\">ReadOnlyCollection&lt;T&gt;<\/code> will see those changes. You can think of a <code class=\"calibre9\">ReadOnlyCollection&lt;T&gt;<\/code> as a protected view of a collection.Let's see how we can make sure a collection is read-only:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithCollections<\/code> project, in <code class=\"calibre9\">Program.Helpers.cs<\/code>, add a method that should only be given a read-only dictionary with <code class=\"calibre9\">string<\/code> for the type of key and value, but the naughty method tries to call <code class=\"calibre9\">Add<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void UseDictionary(\n  IDictionary&lt;string, string&gt; dictionary)\n{\n  WriteLine($\"Count before is {dictionary.Count}.\");\n  try\n  {\n    WriteLine(\"Adding new item with GUID values.\");\n    \/\/ Add method with return type of void.\n    dictionary.Add(\n      key: Guid.NewGuid().ToString(), \n      value: Guid.NewGuid().ToString()); \n  }\n  catch (NotSupportedException)\n  {\n    WriteLine(\"This dictionary does not support the Add method.\");\n  }\n  WriteLine($\"Count after is {dictionary.Count}.\");\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note the type of parameter is <code class=\"calibre9\">IDictionary&lt;TKey, TValue&gt;<\/code>. Using an interface provides more flexibility because we can pass either a <code class=\"calibre9\">Dictionary&lt;TKey, TValue&gt;<\/code>, a <code class=\"calibre9\">ReadOnlyDictionary&lt;TKey, TValue&gt;<\/code>, or anything else that implements that interface.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to pass the <code class=\"calibre9\">keywords<\/code> dictionary to this naughty method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">UseDictionary(keywords);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that the naughty method was able to add a new key-value pair, so the count has incremented, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Count before is 3.\nAdding new item with GUID values.\nCount after is 4.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the <code class=\"calibre9\">UseDictionary<\/code> statement and then add a statement to pass the dictionary converted into a read-only collection, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/UseDictionary(keywords);\nUseDictionary(keywords.AsReadOnly());<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that this time the method was not able to add an item, so the count is the same, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Count before is 3.\nAdding new item with GUID values.\nThis dictionary does not support the Add method.\nCount after is 3.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.cs<\/code>, import the <code class=\"calibre9\">System.Collections.Immutable<\/code> namespace, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Collections.Immutable; \/\/ To use ImmutableDictionary&lt;T, T&gt;.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the <code class=\"calibre9\">AsReadOnly<\/code> statement and then add a statement to pass the keywords converted into an immutable dictionary, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/UseDictionary(keywords.AsReadOnly());\nUseDictionary(keywords.ToImmutableDictionary());<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that this time the method was also not able to add a default value, so the count is the same &ndash; it is the same behavior as using a read-only collection, so what's the point of immutable collections?<\/li>\n<\/ol>\n<p class=\"rights\">If you import the <code class=\"calibre9\">System.Collections.Immutable<\/code> namespace, then any collection that implements <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> is given six extension methods to convert it into an immutable collection like a list, dictionary, set, and so on.Although the immutable collection will have a method named <code class=\"calibre9\">Add<\/code>, it does not add an item to the original immutable collection! Instead, it returns a new immutable collection with the new item in it. The original immutable collection still only has the original items in it.Let's see an example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to convert the keywords dictionary into an immutable dictionary and then add a new keyword definition to it by randomly generating GUID values, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ImmutableDictionary&lt;string, string&gt; immutableKeywords = \n  keywords.ToImmutableDictionary();\n\/\/ Call the Add method with a return value.\nImmutableDictionary&lt;string, string&gt; newDictionary = \n  immutableKeywords.Add(\n    key: Guid.NewGuid().ToString(),\n    value: Guid.NewGuid().ToString());\nOutputCollection(\"Immutable keywords dictionary\", immutableKeywords);\nOutputCollection(\"New keywords dictionary\", newDictionary); <\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that the immutable keywords dictionary does not get modified when you call the <code class=\"calibre9\">Add<\/code> method on it; instead, it returns a new dictionary with all the existing keywords plus the newly added keyword, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Immutable keywords dictionary:\n  [float, Single precision floating point number]\n  [long, 64-bit integer data type]\n  [int, 32-bit integer data type]\nNew keywords dictionary:\n  [d0e099ff-995f-4463-ae7f-7b59ed3c8d1d, 3f8e4c38-c7a3-4b20-acb3-01b2e3c86e8c]\n  [float, Single precision floating point number]\n  [long, 64-bit integer data type]\n  [int, 32-bit integer data type] <\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Newly added items will not always appear at the top of the dictionary as shown in my output above. Internally, the order is defined by the hash of the key. This is why dictionaries are sometimes called hash tables.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: To improve performance, many applications store a shared copy of commonly accessed objects in a central cache. To safely allow multiple threads to work with those objects knowing they won't change, you should make them immutable or use a concurrent collection type, which you can read about at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.collections.concurrent\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.collections.concurrent<\/a>.<\/p>\n<\/blockquote>\n<\/blockquote>\n<p class=\"rights\">The generic collections have some potential performance issues related to how they are designed. First, being generic, the types of items or types used for keys and values for a dictionary have a big effect on performance depending on what they are. Since they could be any type, the .NET team cannot optimize the algorithm. <code class=\"calibre9\">string<\/code> and <code class=\"calibre9\">int<\/code> types are the most used in real life. If the .NET team could rely on those always being the types used, then they could greatly improve performance.Second, collections are dynamic, meaning that new items can be added, and existing items can be removed at any time. Even more optimizations could be made if the .NET team knew that no more changes would be made to the collection..NET 8 introduces a new concept: frozen collections. Hmmm, we already have immutable collections, so what is different about frozen collections? Are they tasty and delicious like ice cream? The idea is that 95% of the time, a collection is populated and then never changed. So, if we could optimize them at the time of creation, then those optimizations could be made, adding some time and effort upfront, but then after that, performance for reading the collection could be greatly improved.In .NET 8, there are only two frozen collections: <code class=\"calibre9\">FrozenDictionary&lt;TKey, TValue&gt;<\/code> and <code class=\"calibre9\">FrozenSet&lt;T&gt;<\/code>. More may come in future versions of .NET, but these are the two most common scenarios that would benefit from the frozen concept.Let's go:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.cs<\/code>, import the <code class=\"calibre9\">System.Collections.Frozen<\/code> namespace, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Collections.Frozen; \/\/ To use FrozenDictionary&lt;T, T&gt;.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of <code class=\"calibre9\">Program.cs<\/code>, add statements to convert the keywords dictionary into a frozen dictionary, output its items, and then look up the definition of <code class=\"calibre9\">long<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Creating a frozen collection has an overhead to perform the\n\/\/ sometimes complex optimizations.\nFrozenDictionary&lt;string, string&gt; frozenKeywords =\n  keywords.ToFrozenDictionary();\nOutputCollection(\"Frozen keywords dictionary\", frozenKeywords);\n\/\/ Lookups are faster in a frozen dictionary.\nWriteLine($\"Define long: {frozenKeywords[\"long\"]}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Frozen keywords dictionary:\n  [int, 32-bit integer data type]\n  [long, 64-bit integer data type]\n  [float, Single precision floating point number]\nDefine long: 64-bit integer data type<\/code><\/pre>\n<\/div>\n<p class=\"rights\">What the <code class=\"calibre9\">Add<\/code> method does depends on the type, as summarized in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">List&lt;T&gt;<\/code>: Adds a new item to the end of the existing list.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Dictionary&lt;TKey, TValue&gt;<\/code>: Adds a new item to the existing dictionary in a position determined by its internal structure.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">ReadOnlyCollection&lt;T&gt;<\/code>: Throws a not-supported exception.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">ImmutableList&lt;T&gt;<\/code>: Returns a new list with the new item in it. Does not affect the original list.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">ImmutableDictionary&lt;TKey, TValue&gt;<\/code>: Returns a new dictionary with the new item in it. Does not affect the original dictionary.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">FrozenDictionary&lt;TKey, TValue&gt;<\/code>: Does not exist.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: The documentation for frozen collections is found at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.collections.frozen\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.collections.frozen<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"9.5.9\" id=\"calibre_link-488\">\n<h3 data-number=\"9.5.9\" class=\"calibre8\">Initializing collections using collection expressions<\/h3>\n<p class=\"rights\">Introduced with C# 12 is a new consistent syntax for initializing arrays, collections, and span variables.With C# 11 and earlier, you would have to declare and initialize an array, collection, or span of <code class=\"calibre9\">int<\/code> values using the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int[] numbersArray11 = { 1, 3, 5 };\nList&lt;int&gt; numbersList11 = new() { 1, 3, 5 };\nSpan&lt;int&gt; numbersSpan11 = stackalloc int[] { 1, 3, 5 };<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Starting with C# 12, you can now consistently use square brackets, and the compiler will do the right thing, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int[] numbersArray12 = [ 1, 3, 5 ];\nList&lt;int&gt; numbersList12 = [ 1, 3, 5 ];\nSpan&lt;int&gt; numbersSpan12 = [ 1, 3, 5 ];<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about collection expressions at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/proposals\/csharp-12.0\/collection-expressions\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/proposals\/csharp-12.0\/collection-expressions<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"9.5.10\" id=\"calibre_link-489\">\n<h3 data-number=\"9.5.10\" class=\"calibre8\">Good practice with collections<\/h3>\n<p class=\"rights\">Since .NET 1.1, types like <code class=\"calibre9\">StringBuilder<\/code> have had a method named <code class=\"calibre9\">EnsureCapacity<\/code> that can presize its internal storage array to the expected final size of the <code class=\"calibre9\">string<\/code>. This improves performance because it does not have to repeatedly increment the size of the array as more characters are appended.Since .NET Core 2.1, types like <code class=\"calibre9\">Dictionary&lt;T&gt;<\/code> and <code class=\"calibre9\">HashSet&lt;T&gt;<\/code> have also had <code class=\"calibre9\">EnsureCapacity<\/code>.In .NET 6 and later, collections like <code class=\"calibre9\">List&lt;T&gt;<\/code>, <code class=\"calibre9\">Queue&lt;T&gt;<\/code>, and <code class=\"calibre9\">Stack&lt;T&gt;<\/code> now have an <code class=\"calibre9\">EnsureCapacity<\/code> method too, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">List&lt;string&gt; names = new();\nnames.EnsureCapacity(10_000);\n\/\/ Load ten thousand names into the list.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Let's say you need to create a method to process a collection. For maximum flexibility, you could declare the input parameter to be <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> and make the method generic, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">void ProcessCollection&lt;T&gt;(IEnumerable&lt;T&gt; collection)\n{\n  \/\/ Process the items in the collection,\n  \/\/ perhaps using a foreach statement.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">I could pass an array, a list, a queue, or a stack, containing any type, like <code class=\"calibre9\">int<\/code>, <code class=\"calibre9\">string<\/code>, <code class=\"calibre9\">Person<\/code>, or anything else that implements <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code>, into this method and it will process the items. However, the flexibility to pass any collection to this method comes at a performance cost.One of the performance problems with <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> is also one of its benefits: deferred execution, also known as lazy loading. Types that implement this interface do not have to implement deferred execution, but many do.But the worst performance problem with <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> is that the iteration must allocate an object on the heap. To avoid this memory allocation, you should define your method using a concrete type, as shown highlighted in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">void ProcessCollection&lt;T&gt;(List&lt;T&gt; collection)\n{\n  \/\/ Process the items in the collection,\n  \/\/ perhaps using a foreach statement.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This will use the <code class=\"calibre9\">List&lt;T&gt;.Enumerator GetEnumerator()<\/code> method, which returns a <code class=\"calibre9\">struct<\/code>, instead of the <code class=\"calibre9\">IEnumerator&lt;T&gt; GetEnumerator()<\/code> method, which returns a reference type. Your code will be two to three times faster and require less memory. As with all recommendations related to performance, you should confirm the benefit by running performance tests on your actual code in a product environment.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"9.6\" id=\"calibre_link-490\">\n<h2 data-number=\"9.6\" class=\"calibre5\">Working with spans, indexes, and ranges<\/h2>\n<p class=\"rights\">One of Microsoft's goals with .NET Core 2.1 was to improve performance and resource usage. A key .NET feature that enables this is the <code class=\"calibre9\">Span&lt;T&gt;<\/code> type.<\/p>\n<section data-number=\"9.6.1\" id=\"calibre_link-491\">\n<h3 data-number=\"9.6.1\" class=\"calibre8\">Using memory efficiently using spans<\/h3>\n<p class=\"rights\">When manipulating arrays, you will often create new copies or subsets of existing ones so that you can process just the subset. This is not efficient because duplicate objects must be created in memory.If you need to work with a subset of an array, use a <strong class=\"calibre2\">span<\/strong> because it is like a window into the original array. This is more efficient in terms of memory usage and improves performance. Spans only work with arrays, not collections, because the memory must be contiguous.Before we look at spans in more detail, we need to understand some related objects: indexes and ranges.<\/p>\n<\/section>\n<section data-number=\"9.6.2\" id=\"calibre_link-492\">\n<h3 data-number=\"9.6.2\" class=\"calibre8\">Identifying positions with the Index type<\/h3>\n<p class=\"rights\">C# 8 introduced two features for identifying an item's index position within an array and a range of items using two indexes.You learned in the previous section that objects in a list can be accessed by passing an integer into their indexer, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int index = 3;\nPerson p = people[index]; \/\/ Fourth person in array.\nchar letter = name[index]; \/\/ Fourth letter in name.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">Index<\/code> value type is a more formal way of identifying a position, and supports counting from the end, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Two ways to define the same index, 3 in from the start.\nIndex i1 = new(value: 3); \/\/ Counts from the start \nIndex i2 = 3; \/\/ Using implicit int conversion operator.\n\/\/ Two ways to define the same index, 5 in from the end.\nIndex i3 = new(value: 5, fromEnd: true); \nIndex i4 = ^5; \/\/ Using the caret ^ operator.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.6.3\" id=\"calibre_link-493\">\n<h3 data-number=\"9.6.3\" class=\"calibre8\">Identifying ranges with the Range type<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">Range<\/code> value type uses <code class=\"calibre9\">Index<\/code> values to indicate the start and end of its range, using its constructor, C# syntax, or its static methods, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Range r1 = new(start: new Index(3), end: new Index(7));\nRange r2 = new(start: 3, end: 7); \/\/ Using implicit int conversion.\nRange r3 = 3..7; \/\/ Using C# 8.0 or later syntax.\nRange r4 = Range.StartAt(3); \/\/ From index 3 to last index.\nRange r5 = 3..; \/\/ From index 3 to last index.\nRange r6 = Range.EndAt(3); \/\/ From index 0 to index 3.\nRange r7 = ..3; \/\/ From index 0 to index 3.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Extension methods have been added to <code class=\"calibre9\">string<\/code> values (which internally use an array of <code class=\"calibre9\">char<\/code>), <code class=\"calibre9\">int<\/code> arrays, and spans to make ranges easier to work with. These extension methods accept a range as a parameter and return a <code class=\"calibre9\">Span&lt;T&gt;<\/code>. This makes them very memory-efficient.<\/p>\n<\/section>\n<section data-number=\"9.6.4\" id=\"calibre_link-494\">\n<h3 data-number=\"9.6.4\" class=\"calibre8\">Using indexes, ranges, and spans<\/h3>\n<p class=\"rights\">Let's explore using indexes and ranges to return spans:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">WorkingWithRanges<\/code> to the <code class=\"calibre9\">Chapter08<\/code> solution.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then add statements to compare using the <code class=\"calibre9\">string<\/code> type's <code class=\"calibre9\">Substring<\/code> method with ranges to extract parts of someone's name, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string name = \"Samantha Jones\";\n\/\/ Getting the lengths of the first and last names.\nint lengthOfFirst = name.IndexOf(' ');\nint lengthOfLast = name.Length - lengthOfFirst - 1;\n\/\/ Using Substring.\nstring firstName = name.Substring(\n  startIndex: 0,\n  length: lengthOfFirst);\nstring lastName = name.Substring(\n  startIndex: name.Length - lengthOfLast,\n  length: lengthOfLast);\nWriteLine($\"First: {firstName}, Last: {lastName}\");\n\/\/ Using spans.\nReadOnlySpan&lt;char&gt; nameAsSpan = name.AsSpan();\nReadOnlySpan&lt;char&gt; firstNameSpan = nameAsSpan[0..lengthOfFirst]; \nReadOnlySpan&lt;char&gt; lastNameSpan = nameAsSpan[^lengthOfLast..];\nWriteLine($\"First: {firstNameSpan}, Last: {lastNameSpan}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">First: Samantha, Last: Jones\nFirst: Samantha, Last: Jones<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"9.7\" id=\"calibre_link-495\">\n<h2 data-number=\"9.7\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring with deeper research into the topics in this chapter.<\/p>\n<section data-number=\"9.7.1\" id=\"calibre_link-496\">\n<h3 data-number=\"9.7.1\" class=\"calibre8\">Exercise 8.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Use the web to answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the maximum number of characters that can be stored in a <code class=\"calibre9\">string<\/code> variable?<\/li>\n<li class=\"calibre3\">When and why should you use a <code class=\"calibre9\">SecureString<\/code> type?<\/li>\n<li class=\"calibre3\">When is it appropriate to use a <code class=\"calibre9\">StringBuilder<\/code> class?<\/li>\n<li class=\"calibre3\">When should you use a <code class=\"calibre9\">LinkedList&lt;T&gt;<\/code> class?<\/li>\n<li class=\"calibre3\">When should you use a <code class=\"calibre9\">SortedDictionary&lt;T&gt;<\/code> class rather than a <code class=\"calibre9\">SortedList&lt;T&gt;<\/code> class?<\/li>\n<li class=\"calibre3\">In a regular expression, what does <code class=\"calibre9\">$<\/code> mean?<\/li>\n<li class=\"calibre3\">In a regular expression, how can you represent digits?<\/li>\n<li class=\"calibre3\">Why should you <em class=\"calibre10\">not<\/em> use the official standard for email addresses to create a regular expression to validate a user's email address?<\/li>\n<li class=\"calibre3\">What characters are output when the following code runs?<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string city = \"Aberdeen\";\nReadOnlySpan&lt;char&gt; citySpan = city.AsSpan()[^5..^0];\nWriteLine(citySpan.ToString());<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">How could you check that a web service is available before calling it?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"9.7.2\" id=\"calibre_link-497\">\n<h3 data-number=\"9.7.2\" class=\"calibre8\">Exercise 8.2 &ndash; Practice regular expressions<\/h3>\n<p class=\"rights\">In the <code class=\"calibre9\">Chapter08<\/code> solution, create a console app named <code class=\"calibre9\">Ch08Ex02RegularExpressions<\/code> that prompts the user to enter a regular expression and then prompts the user to enter some input, and compare the two for a match until the user presses <em class=\"calibre10\">Esc<\/em>, as shown in the following output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">The default regular expression checks for at least one digit.\nEnter a regular expression (or press ENTER to use the default): ^[a-z]+$ \nEnter some input: apples\napples matches ^[a-z]+$? True\nPress ESC to end or any key to try again.\nEnter a regular expression (or press ENTER to use the default): ^[a-z]+$ \nEnter some input: abc123xyz\nabc123xyz matches ^[a-z]+$? False\nPress ESC to end or any key to try again.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"9.7.3\" id=\"calibre_link-498\">\n<h3 data-number=\"9.7.3\" class=\"calibre8\">Exercise 8.3 &ndash; Practice writing extension methods<\/h3>\n<p class=\"rights\">In the <code class=\"calibre9\">Chapter08<\/code> solution, create a class library named <code class=\"calibre9\">Ch08Ex03NumbersAsWordsLib<\/code> and projects to test it. It should define extension methods that extend number types such as <code class=\"calibre9\">BigInteger<\/code> and <code class=\"calibre9\">int<\/code> with a method named <code class=\"calibre9\">ToWords<\/code> that returns a <code class=\"calibre9\">string<\/code> describing the number.For example, <code class=\"calibre9\">18,000,000<\/code> would be eighteen million, and <code class=\"calibre9\">18,456,002,032,011,000,007<\/code> would be eighteen quintillion, four hundred and fifty-six quadrillion, two trillion, thirty-two billion, eleven million, and seven.You can read more about names for large numbers at the following link: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Names_of_large_numbers\">https:\/\/en.wikipedia.org\/wiki\/Names_of_large_numbers<\/a>.<\/p>\n<\/section>\n<section data-number=\"9.7.4\" id=\"calibre_link-499\">\n<h3 data-number=\"9.7.4\" class=\"calibre8\">Exercise 8.4 &ndash; Working with network resources<\/h3>\n<p class=\"rights\">If you are interested in some low-level types for working with network resources, then you can read an online-only section found at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch08-network-resources.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch08-network-resources.md<\/a><\/p>\n<\/section>\n<section data-number=\"9.7.5\" id=\"calibre_link-500\">\n<h3 data-number=\"9.7.5\" class=\"calibre8\">Exercise 8.5 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more details about the topics covered in this chapter:<\/p>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-8---working-with-common-net-types\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-8---working-with-common-net-types<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"9.8\" id=\"calibre_link-501\">\n<h2 data-number=\"9.8\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you explored:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Choices for types to store and manipulate numbers.<\/li>\n<li class=\"calibre3\">Handling text, including using regular expressions for validating input.<\/li>\n<li class=\"calibre3\">Collections to use for storing multiple items.<\/li>\n<li class=\"calibre3\">Working with indexes, ranges, and spans.<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, we will manage files and streams, encode and decode text, and perform serialization.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-936\">\n<div id=\"calibre_link-1935\" class=\"calibre1\">\n<section data-number=\"10\" id=\"calibre_link-502\">\n<h1 data-number=\"10\" class=\"title\">9 Working with Files, Streams, and Serialization<\/h1>\n<section data-number=\"10.1\" id=\"calibre_link-503\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"10.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000172.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about reading and writing to files and streams, text encoding, and serialization. Applications that do not interact with the filesystem are extraordinarily rare. As a .NET developer, almost every application that you build will need to manage the filesystem and create, open, read, and write to and from files. Most of those files will contain text, so it is important to understand how text is encoded. And finally, after working with objects in memory, you will need to store them somewhere permanently for later reuse. You do that using a technique called serialization.In this chapter, we will cover the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Managing the filesystem<\/li>\n<li class=\"calibre3\">Reading and writing with streams<\/li>\n<li class=\"calibre3\">Encoding and decoding text<\/li>\n<li class=\"calibre3\">Serializing object graphs<\/li>\n<li class=\"calibre3\">Working with environment variables<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"10.2\" id=\"calibre_link-504\">\n<h2 data-number=\"10.2\" class=\"calibre5\">Managing the filesystem<\/h2>\n<p class=\"rights\">Your applications will often need to perform input and output operations with files and directories in different environments. The <code class=\"calibre9\">System<\/code> and <code class=\"calibre9\">System.IO<\/code> namespaces contain classes for this purpose.<\/p>\n<section data-number=\"10.2.1\" id=\"calibre_link-505\">\n<h3 data-number=\"10.2.1\" class=\"calibre8\">Handling cross-platform environments and filesystems<\/h3>\n<p class=\"rights\">Let's explore how to handle cross-platform environments and the differences between Windows, Linux, and macOS. Paths are different for Windows, macOS, and Linux, so we will start by exploring how .NET handles this:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to create a new project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">WorkingWithFileSystems<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter09<\/code><\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In the project file, add a package reference for <code class=\"calibre9\">Spectre.Console<\/code>, and then add elements to import the following classes statically and globally: <code class=\"calibre9\">System.Console<\/code>, <code class=\"calibre9\">System.IO.Directory<\/code>, <code class=\"calibre9\">System.IO.Path<\/code>, and <code class=\"calibre9\">System.Environment<\/code>, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;PackageReference Include=\"Spectre.Console\" Version=\"0.47.0\" \/&gt;\n&lt;\/ItemGroup&gt;\n&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n  &lt;Using Include=\"System.IO.Directory\" Static=\"true\" \/&gt;\n  &lt;Using Include=\"System.IO.Path\" Static=\"true\" \/&gt;\n  &lt;Using Include=\"System.Environment\" Static=\"true\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">WorkingWithFileSystems<\/code> project to restore packages.<\/li>\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Program.Helpers.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Helpers.cs<\/code>, add a partial <code class=\"calibre9\">Program<\/code> class with a <code class=\"calibre9\">SectionTitle<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ null namespace to merge with auto-generated Program.\npartial class Program\n{\n  private static void SectionTitle(string title)\n  {\n    WriteLine();\n    ConsoleColor previousColor = ForegroundColor;\n    \/\/ Use a color that stands out on your system.\n    ForegroundColor = ConsoleColor.DarkYellow;\n    WriteLine($\"*** {title} ***\");\n    ForegroundColor = previousColor;\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to use a <code class=\"calibre9\">Spectre.Console<\/code> table to do the following:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Output the path and directory separation characters.<\/li>\n<li class=\"calibre3\">Output the path of the current directory.<\/li>\n<li class=\"calibre3\">Output some special paths for system files, temporary files, and documents:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Spectre.Console; \/\/ To use Table.\n#region Handling cross-platform environments and filesystems\nSectionTitle(\"Handling cross-platform environments and filesystems\");\n\/\/ Create a Spectre Console table.\nTable table = new();\n\/\/ Add two columns with markup for colors.\ntable.AddColumn(\"[blue]MEMBER[\/]\");\ntable.AddColumn(\"[blue]VALUE[\/]\");\n\/\/ Add rows.\ntable.AddRow(\"Path.PathSeparator\", PathSeparator.ToString());\ntable.AddRow(\"Path.DirectorySeparatorChar\", \n  DirectorySeparatorChar.ToString());\ntable.AddRow(\"Directory.GetCurrentDirectory()\", \n  GetCurrentDirectory());\ntable.AddRow(\"Environment.CurrentDirectory\", CurrentDirectory);\ntable.AddRow(\"Environment.SystemDirectory\", SystemDirectory);\ntable.AddRow(\"Path.GetTempPath()\", GetTempPath());\ntable.AddRow(\"\");\ntable.AddRow(\"GetFolderPath(SpecialFolder\", \"\");\ntable.AddRow(\"  .System)\", GetFolderPath(SpecialFolder.System));\ntable.AddRow(\"  .ApplicationData)\", \n  GetFolderPath(SpecialFolder.ApplicationData));\ntable.AddRow(\"  .MyDocuments)\", \n  GetFolderPath(SpecialFolder.MyDocuments));\ntable.AddRow(\"  .Personal)\", \n  GetFolderPath(SpecialFolder.Personal));\n\/\/ Render the table to the console\nAnsiConsole.Write(table);\n#endregion <\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">Environment<\/code> type has many other useful members that we did not use in this code, including the <code class=\"calibre9\">OSVersion<\/code> and <code class=\"calibre9\">ProcessorCount<\/code> properties.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown using Visual Studio 2022 on Windows in <em class=\"calibre10\">Figure 9.1<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 9.1: Showing filesystem information with Visual Studio 2022 on Windows\" height=\"839\" src=\"\/images\/cs12\/000010.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 9.1: Showing filesystem information with Visual Studio 2022 on Windows<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about using Spectre Console tables at the following link: <a href=\"https:\/\/spectreconsole.net\/widgets\/table\">https:\/\/spectreconsole.net\/widgets\/table<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">When running the console app using <code class=\"calibre9\">dotnet run<\/code> on a Mac, the path and directory separator characters are different and the <code class=\"calibre9\">CurrentDirectory<\/code> will be the project folder, not a folder inside <code class=\"calibre9\">bin<\/code>, as shown in <em class=\"calibre10\">Figure 9.2<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 9.2: Showing filesystem information with the CLI on macOS\" height=\"678\" src=\"\/images\/cs12\/000103.png\" width=\"1576\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 9.2: Showing filesystem information with the CLI on macOS<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Windows uses a backslash (<code class=\"calibre9\">\\<\/code>) for the directory separator character. macOS and Linux use a forward slash (<code class=\"calibre9\">\/<\/code>) for the directory separator character. Do not assume what character is used in your code when combining paths; use <code class=\"calibre9\">Path.DirectorySeparatorChar<\/code>.<\/p>\n<\/blockquote>\n<p class=\"rights\">In future sections of this chapter, we will create directories and files in the <code class=\"calibre9\">Personal<\/code> special folder, so make a note of where that is for your operating system. For example, if you're using Linux, it should be <code class=\"calibre9\">$USER\/Documents<\/code>.<\/p>\n<\/section>\n<section data-number=\"10.2.2\" id=\"calibre_link-506\">\n<h3 data-number=\"10.2.2\" class=\"calibre8\">Managing drives<\/h3>\n<p class=\"rights\">To manage drives, use the <code class=\"calibre9\">DriveInfo<\/code> type, which has a static method that returns information about all the drives connected to your computer. Each drive has a drive type.Let's explore drives:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, write statements to get all the drives and output their name, type, size, available free space, and format, but only if the drive is ready, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Managing drives\");\nTable drives = new();\ndrives.AddColumn(\"[blue]NAME[\/]\");\ndrives.AddColumn(\"[blue]TYPE[\/]\");\ndrives.AddColumn(\"[blue]FORMAT[\/]\");\ndrives.AddColumn(new TableColumn(\n  \"[blue]SIZE (BYTES)[\/]\").RightAligned());\ndrives.AddColumn(new TableColumn(\n  \"[blue]FREE SPACE[\/]\").RightAligned());\nforeach (DriveInfo drive in DriveInfo.GetDrives())\n{\n  if (drive.IsReady)\n  {\n    drives.AddRow(drive.Name, drive.DriveType.ToString(), \n      drive.DriveFormat, drive.TotalSize.ToString(\"N0\"), \n      drive.AvailableFreeSpace.ToString(\"N0\"));\n  }\n  else\n  {\n    drives.AddRow(drive.Name, drive.DriveType.ToString(),\n      string.Empty, string.Empty, string.Empty);\n  }\n}\nAnsiConsole.Write(drives);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Check that a drive is ready before reading properties such as <code class=\"calibre9\">TotalSize<\/code>, or you will see an exception thrown with removable drives.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">On Linux, by default, your console app will only have permission to read the <code class=\"calibre9\">Name<\/code> and <code class=\"calibre9\">DriveType<\/code> properties when run as a normal user. An <code class=\"calibre9\">UnauthorizedAccessException<\/code> is thrown for <code class=\"calibre9\">DriveFormat<\/code>, <code class=\"calibre9\">TotalSize<\/code>, and <code class=\"calibre9\">AvailableFreeSpace<\/code>. Run the console app as superuser to avoid this issue, as shown in the following command: <code class=\"calibre9\">sudo dotnet run<\/code>. Using <code class=\"calibre9\">sudo<\/code> is fine in a development environment, but in a production environment, it's recommended to edit your permissions to avoid running with elevated permissions. On Linux, the name and drive format columns might also need to be wider, for example, 55 and 12 characters wide respectively.<\/p>\n<\/blockquote>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in <em class=\"calibre10\">Figure 9.3<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 9.3: Showing drive information on Windows and macOS\" height=\"680\" src=\"\/images\/cs12\/000121.png\" width=\"1429\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 9.3: Showing drive information on Windows and macOS<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"10.2.3\" id=\"calibre_link-507\">\n<h3 data-number=\"10.2.3\" class=\"calibre8\">Managing directories<\/h3>\n<p class=\"rights\">To manage directories, use the <code class=\"calibre9\">Directory<\/code>, <code class=\"calibre9\">Path<\/code>, and <code class=\"calibre9\">Environment<\/code> static classes. These types include many members to work with the filesystem.When constructing custom paths, you must be careful to write your code so that it makes no assumptions about the platform, for example, what to use for the directory separator character:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, write statements to do the following:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Define a custom path under the user's home directory by creating an array of strings for the directory names, and then properly combine them with the <code class=\"calibre9\">Path<\/code> type's <code class=\"calibre9\">Combine<\/code> method.<\/li>\n<li class=\"calibre3\">Check for the existence of the custom directory path using the <code class=\"calibre9\">Exists<\/code> method of the <code class=\"calibre9\">Directory<\/code> class.<\/li>\n<li class=\"calibre3\">Create and then delete the directory, including files and subdirectories within it, using the <code class=\"calibre9\">CreateDirectory<\/code> and <code class=\"calibre9\">Delete<\/code> methods of the <code class=\"calibre9\">Directory<\/code> class:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Managing directories\");\nstring newFolder = Combine(\n  GetFolderPath(SpecialFolder.Personal), \"NewFolder\");\nWriteLine($\"Working with: {newFolder}\");\n\/\/ We must explicitly say which Exists method to use \n\/\/ because we statically imported both Path and Directory.\nWriteLine($\"Does it exist? {Path.Exists(newFolder)}\");\nWriteLine(\"Creating it...\");\nCreateDirectory(newFolder);\n\/\/ Let's use the Directory.Exists method this time.\nWriteLine($\"Does it exist? {Directory.Exists(newFolder)}\");\nWrite(\"Confirm the directory exists, and then press any key.\");\nReadKey(intercept: true);\nWriteLine(\"Deleting it...\");\nDelete(newFolder, recursive: true);\nWriteLine($\"Does it exist? {Path.Exists(newFolder)}\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In .NET 6 and earlier, only the <code class=\"calibre9\">Directory<\/code> class had an <code class=\"calibre9\">Exists<\/code> method. In .NET 7 or later, the <code class=\"calibre9\">Path<\/code> class also has an <code class=\"calibre9\">Exists<\/code> method. Both can be used to check for the existence of a path.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and use your favorite file management tool to confirm that the directory has been created before pressing <span>Enter<\/span> to delete it, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Working with: C:\\Users\\markj\\OneDrive\\Documents\\NewFolder \nDoes it exist? False\nCreating it...\nDoes it exist? True\nConfirm the directory exists, and then press any key.\nDeleting it...\nDoes it exist? False<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"10.2.4\" id=\"calibre_link-508\">\n<h3 data-number=\"10.2.4\" class=\"calibre8\">Managing files<\/h3>\n<p class=\"rights\">When working with files, you can statically import the file type, just as we did for the directory type. However, for the next example, we will not do so because it has some of the same methods as the directory type, and they would conflict. The file type has a short enough name not to matter in this case. The steps are as follows:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, write statements to do the following:\n<ol class=\"toc1\">\n<li class=\"calibre3\">Check for the existence of a file.<\/li>\n<li class=\"calibre3\">Create a text file.<\/li>\n<li class=\"calibre3\">Write a line of text to the file.<\/li>\n<li class=\"calibre3\">Close the file to release system resources and file locks (this would normally be done inside a <code class=\"calibre9\">try<\/code>-<code class=\"calibre9\">finally<\/code> statement block to ensure that the file is closed even if an exception occurs when writing to it).<\/li>\n<li class=\"calibre3\">Copy the file to a backup.<\/li>\n<li class=\"calibre3\">Delete the original file.<\/li>\n<li class=\"calibre3\">Read the backup file's contents and then close it:<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Managing files\");\n\/\/ Define a directory path to output files starting\n\/\/ in the user's folder.\nstring dir = Combine(\n  GetFolderPath(SpecialFolder.Personal), \"OutputFiles\");\nCreateDirectory(dir);\n\/\/ Define file paths.\nstring textFile = Combine(dir, \"Dummy.txt\");\nstring backupFile = Combine(dir, \"Dummy.bak\");\nWriteLine($\"Working with: {textFile}\");\nWriteLine($\"Does it exist? {File.Exists(textFile)}\");\n\/\/ Create a new text file and write a line to it.\nStreamWriter textWriter = File.CreateText(textFile);\ntextWriter.WriteLine(\"Hello, C#!\");\ntextWriter.Close(); \/\/ Close file and release resources.\nWriteLine($\"Does it exist? {File.Exists(textFile)}\");\n\/\/ Copy the file, and overwrite if it already exists.\nFile.Copy(sourceFileName: textFile,\n  destFileName: backupFile, overwrite: true);\nWriteLine(\n  $\"Does {backupFile} exist? {File.Exists(backupFile)}\");\nWrite(\"Confirm the files exist, and then press any key.\");\nReadKey(intercept: true);\n\/\/ Delete the file.\nFile.Delete(textFile);\nWriteLine($\"Does it exist? {File.Exists(textFile)}\");\n\/\/ Read from the text file backup.\nWriteLine($\"Reading contents of {backupFile}:\");\nStreamReader textReader = File.OpenText(backupFile); \nWriteLine(textReader.ReadToEnd());\ntextReader.Close();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Working with: C:\\Users\\markj\\OneDrive\\Documents\\OutputFiles\\Dummy.txt \nDoes it exist? False\nDoes it exist? True\nDoes C:\\Users\\markj\\OneDrive\\Documents\\OutputFiles\\Dummy.bak exist? True \nConfirm the files exist, and then press any key.\nDoes it exist? False\nReading contents of C:\\Users\\markj\\OneDrive\\Documents\\OutputFiles\\Dummy.bak:\nHello, C#!<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"10.2.5\" id=\"calibre_link-509\">\n<h3 data-number=\"10.2.5\" class=\"calibre8\">Managing paths<\/h3>\n<p class=\"rights\">Sometimes, you need to work with parts of a path; for example, you might want to extract just the folder name, the filename, or the extension. Sometimes, you need to generate temporary folders and filenames. You can do this with static methods of the <code class=\"calibre9\">Path<\/code> class:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add the following statements:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Managing paths\");\nWriteLine($\"Folder Name: {GetDirectoryName(textFile)}\"); \nWriteLine($\"File Name: {GetFileName(textFile)}\"); \nWriteLine(\"File Name without Extension: {0}\",\n  GetFileNameWithoutExtension(textFile)); \nWriteLine($\"File Extension: {GetExtension(textFile)}\"); \nWriteLine($\"Random File Name: {GetRandomFileName()}\"); \nWriteLine($\"Temporary File Name: {GetTempFileName()}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Folder Name: C:\\Users\\markj\\OneDrive\\Documents\\OutputFiles \nFile Name: Dummy.txt\nFile Name without Extension: Dummy \nFile Extension: .txt\nRandom File Name: u45w1zki.co3 \nTemporary File Name:\nC:\\Users\\markj\\AppData\\Local\\Temp\\tmphdmipz.tmp<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">GetTempFileName<\/code> creates a zero-byte file and returns its name, ready for you to use. <code class=\"calibre9\">GetRandomFileName<\/code> just returns a filename; it doesn't create the file.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"10.2.6\" id=\"calibre_link-510\">\n<h3 data-number=\"10.2.6\" class=\"calibre8\">Getting file information<\/h3>\n<p class=\"rights\">To get more information about a file or directory, for example, its size or when it was last accessed, you can create an instance of the <code class=\"calibre9\">FileInfo<\/code> or <code class=\"calibre9\">DirectoryInfo<\/code> class.<code class=\"calibre9\">FileInfo<\/code> and <code class=\"calibre9\">DirectoryInfo<\/code> both inherit from <code class=\"calibre9\">FileSystemInfo<\/code>, so they both have members such as <code class=\"calibre9\">LastAccessTime<\/code> and <code class=\"calibre9\">Delete<\/code>, as well as extra members specific to themselves, as shown in <em class=\"calibre10\">Table 9.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre19\"><\/col>\n<col class=\"calibre19\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Class<\/td>\n<td class=\"calibre21\">Members<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">FileSystemInfo<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Fields: <code class=\"calibre9\">FullPath<\/code>, <code class=\"calibre9\">OriginalPath<\/code><\/p>\n<p class=\"rights\">Properties: <code class=\"calibre9\">Attributes<\/code>, <code class=\"calibre9\">CreationTime<\/code>, <code class=\"calibre9\">CreationTimeUtc<\/code>, <code class=\"calibre9\">Exists<\/code>, <code class=\"calibre9\">Extension<\/code>, <code class=\"calibre9\">FullName<\/code>, <code class=\"calibre9\">LastAccessTime<\/code>, <code class=\"calibre9\">LastAccessTimeUtc<\/code>, <code class=\"calibre9\">LastWriteTime<\/code>, <code class=\"calibre9\">LastWriteTimeUtc<\/code>, <code class=\"calibre9\">Name<\/code><\/p>\n<p class=\"rights\">Methods: <code class=\"calibre9\">Delete<\/code>, <code class=\"calibre9\">GetObjectData<\/code>, <code class=\"calibre9\">Refresh<\/code><\/p>\n<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">DirectoryInfo<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Properties: <code class=\"calibre9\">Parent<\/code>, <code class=\"calibre9\">Root<\/code><\/p>\n<p class=\"rights\">Methods: <code class=\"calibre9\">Create<\/code>, <code class=\"calibre9\">CreateSubdirectory<\/code>, <code class=\"calibre9\">EnumerateDirectories<\/code>, <code class=\"calibre9\">EnumerateFiles<\/code>, <code class=\"calibre9\">EnumerateFileSystemInfos<\/code>, <code class=\"calibre9\">GetAccessControl<\/code>, <code class=\"calibre9\">GetDirectories<\/code>, <code class=\"calibre9\">GetFiles<\/code>, <code class=\"calibre9\">GetFileSystemInfos<\/code>, <code class=\"calibre9\">MoveTo<\/code>, <code class=\"calibre9\">SetAccessControl<\/code><\/p>\n<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">FileInfo<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Properties: <code class=\"calibre9\">Directory<\/code>, <code class=\"calibre9\">DirectoryName<\/code>, <code class=\"calibre9\">IsReadOnly<\/code>, <code class=\"calibre9\">Length<\/code><\/p>\n<p class=\"rights\">Methods: <code class=\"calibre9\">AppendText<\/code>, <code class=\"calibre9\">CopyTo<\/code>, <code class=\"calibre9\">Create<\/code>, <code class=\"calibre9\">CreateText<\/code>, <code class=\"calibre9\">Decrypt<\/code>, <code class=\"calibre9\">Encrypt<\/code>, <code class=\"calibre9\">GetAccessControl<\/code>, <code class=\"calibre9\">MoveTo<\/code>, <code class=\"calibre9\">Open<\/code>, <code class=\"calibre9\">OpenRead<\/code>, <code class=\"calibre9\">OpenText<\/code>, <code class=\"calibre9\">OpenWrite<\/code>, <code class=\"calibre9\">Replace<\/code>, <code class=\"calibre9\">SetAccessControl<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 9.1: Classes to get information about files and directories<\/p>\n<p class=\"rights\">Let's write some code that uses a <code class=\"calibre9\">FileInfo<\/code> instance to efficiently perform multiple actions on a file:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to create an instance of <code class=\"calibre9\">FileInfo<\/code> for the backup file, and write information about it to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Getting file information\");\nFileInfo info = new(backupFile);\nWriteLine($\"{backupFile}:\");\nWriteLine($\"  Contains {info.Length} bytes.\");\nWriteLine($\"  Last accessed: {info.LastAccessTime}\");\nWriteLine($\"  Has readonly set to {info.IsReadOnly}.\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">C:\\Users\\markj\\OneDrive\\Documents\\OutputFiles\\Dummy.bak:\n  Contains 12 bytes.\n  Last accessed: 13\/07\/2023 12:11:12\n  Has readonly set to False.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The number of bytes might be different on your operating system because operating systems can use different line endings.<\/p>\n<\/section>\n<section data-number=\"10.2.7\" id=\"calibre_link-511\">\n<h3 data-number=\"10.2.7\" class=\"calibre8\">Controlling how you work with files<\/h3>\n<p class=\"rights\">When working with files, you often need to control how they are opened. The <code class=\"calibre9\">File.Open<\/code> method has overloads to specify additional options using <code class=\"calibre9\">enum<\/code> values.The <code class=\"calibre9\">enum<\/code> types are as follows:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">FileMode<\/code>: This controls what you want to do with the file, like <code class=\"calibre9\">CreateNew<\/code>, <code class=\"calibre9\">OpenOrCreate<\/code>, or <code class=\"calibre9\">Truncate<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">FileAccess<\/code>: This controls what level of access you need, like <code class=\"calibre9\">ReadWrite<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">FileShare<\/code>: This controls locks on the file to allow other processes the specified level of access, like <code class=\"calibre9\">Read<\/code>.<\/li>\n<\/ul>\n<p class=\"rights\">You might want to open a file and read from it, and allow other processes to read it too, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">FileStream file = File.Open(pathToFile,\n  FileMode.Open, FileAccess.Read, FileShare.Read);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">There is also an <code class=\"calibre9\">enum<\/code> for attributes of a file as follows:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">FileAttributes<\/code>: This is to check a <code class=\"calibre9\">FileSystemInfo<\/code>-derived type\u2019s <code class=\"calibre9\">Attributes<\/code> property for values like <code class=\"calibre9\">Archive<\/code> and <code class=\"calibre9\">Encrypted<\/code>.<\/li>\n<\/ul>\n<p class=\"rights\">You could check a file or directory's attributes, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">FileInfo info = new(backupFile);\nWriteLine(\"Is the backup file compressed? {0}\",\n  info.Attributes.HasFlag(FileAttributes.Compressed));<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Now that you've learned some common ways to work with the directories and files in the filesystem, you next need to learn how to read and write the data stored in a file, that is, how to work with streams.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"10.3\" id=\"calibre_link-512\">\n<h2 data-number=\"10.3\" class=\"calibre5\">Reading and writing with streams<\/h2>\n<p class=\"rights\">In <em class=\"calibre10\">Chapter 10<\/em>, <em class=\"calibre10\">Working with Data Using Entity Framework Core<\/em>, you will use a file named <code class=\"calibre9\">Northwind.db<\/code>, but you will not work with the file directly. Instead, you will interact with the SQLite database engine, which in turn will read and write to the file. In scenarios where there is no other system that \"owns\" the file and does the reading and writing for you, you will use a file stream to work directly with the file.A <strong class=\"calibre2\">stream<\/strong> is a sequence of bytes that can be read from and written to. Although files can be processed rather like arrays, with random access provided by knowing the position of a byte within the file, it is more efficient to process a file as a stream in which the bytes can be accessed in sequential order. When a human does the processing, they tend to need random access so that they can jump around the data making changes and return to the data they worked on earlier. When an automated system does the processing, they tend to be able to work sequentially and only need to \"touch\" the data once.Streams can also be used to process terminal input and output and networking resources, such as sockets and ports, that do not provide random access and cannot seek (that is, move) to a position. You can write code to process some arbitrary bytes without knowing or caring where they come from. Your code simply reads or writes to a stream, and another piece of code handles where the bytes are stored.<\/p>\n<section data-number=\"10.3.1\" id=\"calibre_link-513\">\n<h3 data-number=\"10.3.1\" class=\"calibre8\">Understanding abstract and concrete streams<\/h3>\n<p class=\"rights\">There is an <code class=\"calibre9\">abstract<\/code> class named <code class=\"calibre9\">Stream<\/code> that represents any type of stream. Remember that an <code class=\"calibre9\">abstract<\/code> class cannot be instantiated using <code class=\"calibre9\">new<\/code>; it can only be inherited. This is because it is only partially implemented.There are many concrete classes that inherit from this base class, including <code class=\"calibre9\">FileStream<\/code>, <code class=\"calibre9\">MemoryStream<\/code>, <code class=\"calibre9\">BufferedStream<\/code>, <code class=\"calibre9\">GZipStream<\/code>, and <code class=\"calibre9\">SslStream<\/code>. They all work the same way. All streams implement <code class=\"calibre9\">IDisposable<\/code>, so they have a <code class=\"calibre9\">Dispose<\/code> method to release unmanaged resources.Some of the common members of the <code class=\"calibre9\">Stream<\/code> class are described in <em class=\"calibre10\">Table 9.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Member<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">CanRead<\/code> , <code class=\"calibre9\">CanWrite<\/code><\/td>\n<td class=\"calibre21\">These properties determine if you can read from and write to the stream.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Length<\/code> , <code class=\"calibre9\">Position<\/code><\/td>\n<td class=\"calibre21\">These properties determine the total number of bytes and the current position within the stream. These properties may throw a <code class=\"calibre9\">NotSupportedException<\/code> for some types of streams, for example, if <code class=\"calibre9\">CanSeek<\/code> returns <code class=\"calibre9\">false<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Close<\/code> , <code class=\"calibre9\">Dispose<\/code><\/td>\n<td class=\"calibre21\">This method closes the stream and releases its resources. You can call either method since the implementation of <code class=\"calibre9\">Dispose<\/code> literally calls <code class=\"calibre9\">Close<\/code> !<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Flush<\/code><\/td>\n<td class=\"calibre21\">If the stream has a buffer, then this method writes the bytes in the buffer to the stream, and the buffer is cleared.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">CanSeek<\/code><\/td>\n<td class=\"calibre21\">This property determines if the <code class=\"calibre9\">Seek<\/code> method can be used.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Seek<\/code><\/td>\n<td class=\"calibre21\">This method moves the current position to the one specified in its parameter.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Read<\/code> , <code class=\"calibre9\">ReadAsync<\/code><\/td>\n<td class=\"calibre21\">These methods read a specified number of bytes from the stream into a byte array and advance the position.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ReadByte<\/code><\/td>\n<td class=\"calibre21\">This method reads the next byte from the stream and advances the position.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Write<\/code> , <code class=\"calibre9\">WriteAsync<\/code><\/td>\n<td class=\"calibre21\">These methods write the contents of a byte array into the stream.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">WriteByte<\/code><\/td>\n<td class=\"calibre21\">This method writes a byte to the stream.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 9.2: Common members of the Stream class<br \/>\n<\/section>\n<section data-number=\"10.3.2\" id=\"calibre_link-514\">\n<h3 data-number=\"10.3.2\" class=\"calibre8\">Understanding storage streams<\/h3>\n<p class=\"rights\">Some storage streams that represent a location where the bytes will be stored are described in <em class=\"calibre10\">Table 9.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Namespace<\/td>\n<td class=\"calibre21\">Class<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.IO<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">FileStream<\/code><\/td>\n<td class=\"calibre21\">Bytes stored in the filesystem.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.IO<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">MemoryStream<\/code><\/td>\n<td class=\"calibre21\">Bytes stored in memory in the current process.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Net.Sockets<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">NetworkStream<\/code><\/td>\n<td class=\"calibre21\">Bytes stored at a network location.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 9.3: Storage stream classes<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">FileStream<\/code> has been rewritten in .NET 6 to have much higher performance and reliability on Windows. You can read more about this at the following link: <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/file-io-improvements-in-dotnet-6\/\">https:\/\/devblogs.microsoft.com\/dotnet\/file-io-improvements-in-dotnet-6\/<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"10.3.3\" id=\"calibre_link-515\">\n<h3 data-number=\"10.3.3\" class=\"calibre8\">Understanding function streams<\/h3>\n<p class=\"rights\">Function streams cannot exist on their own but can only be \"plugged into\" other streams to add functionality. Some are described in <em class=\"calibre10\">Table 9.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Namespace<\/td>\n<td class=\"calibre21\">Class<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Security.Cryptography<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">CryptoStream<\/code><\/td>\n<td class=\"calibre21\">This encrypts and decrypts the stream.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.IO.Compression<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">GZipStream<\/code> , <code class=\"calibre9\">DeflateStream<\/code><\/td>\n<td class=\"calibre21\">These compress and decompress the stream.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Net.Security<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">AuthenticatedStream<\/code><\/td>\n<td class=\"calibre21\">This sends credentials across the stream.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 9.4: Function stream classes<br \/>\n<\/section>\n<section data-number=\"10.3.4\" id=\"calibre_link-516\">\n<h3 data-number=\"10.3.4\" class=\"calibre8\">Understanding stream helpers<\/h3>\n<p class=\"rights\">Although there will be occasions where you need to work with streams at a low level, most often, you can plug helper classes into the chain to make things easier. All the helper types for streams implement <code class=\"calibre9\">IDisposable<\/code>, so they have a <code class=\"calibre9\">Dispose<\/code> method to release unmanaged resources.Some helper classes to handle common scenarios are described in <em class=\"calibre10\">Table 9.5<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Namespace<\/td>\n<td class=\"calibre21\">Class<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.IO<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">StreamReader<\/code><\/td>\n<td class=\"calibre21\">This reads from the underlying stream as plain text.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.IO<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">StreamWriter<\/code><\/td>\n<td class=\"calibre21\">This writes to the underlying stream as plain text.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.IO<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">BinaryReader<\/code><\/td>\n<td class=\"calibre21\">This reads from streams as .NET types. For example, the <code class=\"calibre9\">ReadDecimal<\/code> method reads the next 16 bytes from the underlying stream as a <code class=\"calibre9\">decimal<\/code> value, and the <code class=\"calibre9\">ReadInt32<\/code> method reads the next 4 bytes as an <code class=\"calibre9\">int<\/code> value.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.IO<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">BinaryWriter<\/code><\/td>\n<td class=\"calibre21\">This writes to streams as .NET types. For example, the <code class=\"calibre9\">Write<\/code> method with a <code class=\"calibre9\">decimal<\/code> parameter writes 16 bytes to the underlying stream, and the <code class=\"calibre9\">Write<\/code> method with an <code class=\"calibre9\">int<\/code> parameter writes 4 bytes.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Xml<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">XmlReader<\/code><\/td>\n<td class=\"calibre21\">This reads from the underlying stream using the XML format.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">System.Xml<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">XmlWriter<\/code><\/td>\n<td class=\"calibre21\">This writes to the underlying stream using the XML format.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 9.5: Stream helper classes<br \/>\n<\/section>\n<section data-number=\"10.3.5\" id=\"calibre_link-517\">\n<h3 data-number=\"10.3.5\" class=\"calibre8\">Building a stream pipeline<\/h3>\n<p class=\"rights\">It is very common to combine a helper like <code class=\"calibre9\">StreamWriter<\/code> and multiple function streams like <code class=\"calibre9\">CryptoStream<\/code> and <code class=\"calibre9\">GZipStream<\/code> with a storage stream like <code class=\"calibre9\">FileStream<\/code> into a pipeline, as shown in <em class=\"calibre10\">Figure 9.4<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 9.4: Writing plain text, then encrypting and compressing it into a file stream\" height=\"192\" src=\"\/images\/cs12\/000137.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 9.4: Writing plain text, then encrypting and compressing it into a file stream<\/figcaption><\/figure>\n<p class=\"rights\">Your code would just call a simple helper method like <code class=\"calibre9\">WriteLine<\/code> to send a <code class=\"calibre9\">string<\/code> value like <code class=\"calibre9\">\"Hello\"<\/code> through the pipeline until it arrives at its final destination having been encrypted and compressed so it gets written to the file as <code class=\"calibre9\">\"G7x\"<\/code> (or whatever it would be).<\/p>\n<\/section>\n<section data-number=\"10.3.6\" id=\"calibre_link-518\">\n<h3 data-number=\"10.3.6\" class=\"calibre8\">Writing to text streams<\/h3>\n<p class=\"rights\">When you open a file to read or write to it, you use resources outside of .NET. These are called <strong class=\"calibre2\">unmanaged resources<\/strong> and must be disposed of when you are done working with them. To deterministically control when they are disposed of, we can call the <code class=\"calibre9\">Dispose<\/code> method. When the <code class=\"calibre9\">Stream<\/code> class was first designed, all cleanup code was expected to go in the <code class=\"calibre9\">Close<\/code> method. But later, the concept of <code class=\"calibre9\">IDisposable<\/code> was added to .NET and <code class=\"calibre9\">Stream<\/code> had to implement a <code class=\"calibre9\">Dispose<\/code> method. Later, the <code class=\"calibre9\">using<\/code> statement was added to .NET, which can automatically call <code class=\"calibre9\">Dispose<\/code>. So today, you can call either <code class=\"calibre9\">Close<\/code> or <code class=\"calibre9\">Dispose<\/code>, and they actually do the same thing.Let's type some code to write text to a stream:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">WorkingWithStreams<\/code> to the <code class=\"calibre9\">Chapter09<\/code> solution:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">In Visual Studio, set the startup project for the solution to the current selection.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In the project file, add an element to import the <code class=\"calibre9\">System.Console<\/code>, <code class=\"calibre9\">System.Environment<\/code>, and <code class=\"calibre9\">System.IO.Path<\/code> classes statically and globally.<\/li>\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Program.Helpers.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Helpers.cs<\/code>, add a partial <code class=\"calibre9\">Program<\/code> class with a <code class=\"calibre9\">SectionTitle<\/code> and an <code class=\"calibre9\">OutputFileInfo<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ null namespace to merge with auto-generated Program.\npartial class Program\n{\n  private static void SectionTitle(string title)\n  {\n    ConsoleColor previousColor = ForegroundColor;\n    ForegroundColor = ConsoleColor.DarkYellow;\n    WriteLine($\"*** {title} ***\");\n    ForegroundColor = previousColor;\n  }\n  private static void OutputFileInfo(string path)\n  {\n    WriteLine(\"**** File Info ****\");\n    WriteLine($\"File: {GetFileName(path)}\");\n    WriteLine($\"Path: {GetDirectoryName(path)}\");\n    WriteLine($\"Size: {new FileInfo(path).Length:N0} bytes.\");\n    WriteLine(\"\/------------------\");\n    WriteLine(File.ReadAllText(path));\n    WriteLine(\"------------------\/\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Viper.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Viper.cs<\/code>, define a static class named <code class=\"calibre9\">Viper<\/code> with a static array of <code class=\"calibre9\">string<\/code> values named <code class=\"calibre9\">Callsigns<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic static class Viper\n{\n  \/\/ Define an array of Viper pilot call signs.\n  public static string[] Callsigns = new[]\n  {\n    \"Husker\", \"Starbuck\", \"Apollo\", \"Boomer\",\n    \"Bulldog\", \"Athena\", \"Helo\", \"Racetrack\"\n  };\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, and then import the namespace to work with the Viper class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Packt.Shared; \/\/ To use Viper.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to enumerate the Viper call signs, writing each one on its own line in a single text file, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Writing to text streams\");\n\/\/ Define a file to write to.\nstring textFile = Combine(CurrentDirectory, \"streams.txt\");\n\/\/ Create a text file and return a helper writer.\nStreamWriter text = File.CreateText(textFile);\n\/\/ Enumerate the strings, writing each one to the stream\n\/\/ on a separate line.\nforeach (string item in Viper.Callsigns)\n{\n  text.WriteLine(item);\n}\ntext.Close(); \/\/ Release unmanaged file resources.\nOutputFileInfo(textFile);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Calling <code class=\"calibre9\">Close<\/code> on the stream writer helper will call <code class=\"calibre9\">Close<\/code> on the underlying stream. This in turn calls <code class=\"calibre9\">Dispose<\/code> to release unmanaged file resources.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">**** File Info ****\nFile: streams.txt\nPath: C:\\cs12dotnet8\\Chapter09\\WorkingWithStreams\\bin\\Debug\\net8.0\nSize: 68 bytes.\n\/------------------\nHusker\nStarbuck\nApollo\nBoomer\nBulldog\nAthena\nHelo\nRacetrack\n------------------\/<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Open the file that was created, and confirm that it contains the list of call signs, as well as a blank line because we are effectively calling <code class=\"calibre9\">WriteLine<\/code> twice: once when we write the last call sign to the file, and again when we read the whole file and write it out to the console.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Remember that if you run the project at the command prompt using <code class=\"calibre9\">dotnet run<\/code>, then the path will be the project folder. It will not include <code class=\"calibre9\">bin\\Debug\\net8.0<\/code>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"10.3.7\" id=\"calibre_link-519\">\n<h3 data-number=\"10.3.7\" class=\"calibre8\">Writing to XML streams<\/h3>\n<p class=\"rights\">There are two ways to write an XML element, as follows:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">WriteStartElement<\/code> and <code class=\"calibre9\">WriteEndElement<\/code>: Use this pair when an element might have child elements.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">WriteElementString<\/code>: Use this when an element does not have children.<\/li>\n<\/ul>\n<p class=\"rights\">Now, let's try storing the Viper pilot call signs array of <code class=\"calibre9\">string<\/code> values in an XML file:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.cs<\/code>, import the <code class=\"calibre9\">System.Xml<\/code> namespace, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Xml; \/\/ To use XmlWriter and so on.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of <code class=\"calibre9\">Program.cs<\/code>, add statements that enumerate the call signs, writing each one as an element in a single XML file, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Writing to XML streams\");\n\/\/ Define a file path to write to.\nstring xmlFile = Combine(CurrentDirectory, \"streams.xml\");\n\/\/ Declare variables for the filestream and XML writer.\nFileStream? xmlFileStream = null;\nXmlWriter? xml = null;\ntry\n{\n  xmlFileStream = File.Create(xmlFile);\n  \/\/ Wrap the file stream in an XML writer helper and tell it\n  \/\/ to automatically indent nested elements.\n  xml = XmlWriter.Create(xmlFileStream,\n    new XmlWriterSettings { Indent = true });\n  \/\/ Write the XML declaration.\n  xml.WriteStartDocument();\n  \/\/ Write a root element.\n  xml.WriteStartElement(\"callsigns\");\n  \/\/ Enumerate the strings, writing each one to the stream.\n  foreach (string item in Viper.Callsigns)\n  {\n    xml.WriteElementString(\"callsign\", item);\n  }\n  \/\/ Write the close root element.\n  xml.WriteEndElement();\n}\ncatch (Exception ex)\n{\n  \/\/ If the path doesn't exist the exception will be caught.\n  WriteLine($\"{ex.GetType()} says {ex.Message}\");\n}\nfinally\n{\n  if (xml is not null)\n  {\n    xml.Close();\n    WriteLine(\"The XML writer's unmanaged resources have been disposed.\");\n  }\n  if (xmlFileStream is not null)\n  {\n    xmlFileStream.Close();\n    WriteLine(\"The file stream's unmanaged resources have been disposed.\");\n  }\n}\nOutputFileInfo(xmlFile);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Optionally, right-click in the <code class=\"calibre9\">Close<\/code> method of <code class=\"calibre9\">xmlFileStream<\/code>, select <strong class=\"calibre2\">Go To Implementation<\/strong>, and note the implementations of the <code class=\"calibre9\">Dispose<\/code>, <code class=\"calibre9\">Close<\/code>, and <code class=\"calibre9\">Dispose(bool)<\/code> methods, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public void Dispose() =&gt; Close();\npublic virtual void Close()\n{\n  \/\/ When initially designed, Stream required that all cleanup logic \n  \/\/ went into Close(), but this was thought up before IDisposable \n  \/\/ was added and never revisited. All subclasses\n  \/\/ should put their cleanup now in Dispose(bool).\n  Dispose(true);\n  GC.SuppressFinalize(this);\n}\nprotected virtual void Dispose(bool disposing)\n{\n  \/\/ Note: Never change this to call other virtual methods on Stream\n  \/\/ like Write, since the state on subclasses has already been\n  \/\/ torn down.  This is the last code to run on cleanup for a stream.\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">Close<\/code> and <code class=\"calibre9\">Dispose(bool)<\/code> methods are <code class=\"calibre9\">virtual<\/code> in the <code class=\"calibre9\">Stream<\/code> class because they are designed to be overridden in a derived class, like <code class=\"calibre9\">FileStream<\/code>, to do the work of releasing unmanaged resources.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">**** File Info ****\nThe XML writer's unmanaged resources have been disposed.\nThe file stream's unmanaged resources have been disposed.\nFile: streams.xml\nPath: C:\\cs12dotnet8\\Chapter09\\WorkingWithStreams\\bin\\Debug\\net8.0\nSize: 320 bytes.\n\/------------------\n&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;callsigns&gt;\n  &lt;callsign&gt;Husker&lt;\/callsign&gt;\n  &lt;callsign&gt;Starbuck&lt;\/callsign&gt;\n  &lt;callsign&gt;Apollo&lt;\/callsign&gt;\n  &lt;callsign&gt;Boomer&lt;\/callsign&gt;\n  &lt;callsign&gt;Bulldog&lt;\/callsign&gt;\n  &lt;callsign&gt;Athena&lt;\/callsign&gt;\n  &lt;callsign&gt;Helo&lt;\/callsign&gt;\n  &lt;callsign&gt;Racetrack&lt;\/callsign&gt;\n&lt;\/callsigns&gt;\n-------------------\/<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Before calling the <code class=\"calibre9\">Dispose<\/code> method, check that the object is not <code class=\"calibre9\">null<\/code>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"10.3.8\" id=\"calibre_link-520\">\n<h3 data-number=\"10.3.8\" class=\"calibre8\">Simplifying disposal by using the using statement<\/h3>\n<p class=\"rights\">You can simplify the code that needs to check for a <code class=\"calibre9\">null<\/code> object and then call its <code class=\"calibre9\">Dispose<\/code> method by using the <code class=\"calibre9\">using<\/code> statement. Generally, I would recommend using <code class=\"calibre9\">using<\/code> rather than manually calling <code class=\"calibre9\">Dispose<\/code> because it\u2019s less code to write, unless you need a greater level of control.Confusingly, there are two uses for the <code class=\"calibre9\">using<\/code> keyword: importing a namespace and generating a <code class=\"calibre9\">finally<\/code> statement that calls <code class=\"calibre9\">Dispose<\/code> on an object implementing <code class=\"calibre9\">IDisposable<\/code>.The compiler changes a <code class=\"calibre9\">using<\/code> statement block into a <code class=\"calibre9\">try<\/code>-<code class=\"calibre9\">finally<\/code> statement without a <code class=\"calibre9\">catch<\/code> statement. You can use nested <code class=\"calibre9\">try<\/code> statements; so, if you do want to catch any exceptions, you can, as shown in the following code example:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using (FileStream file2 = File.OpenWrite(\n  Path.Combine(path, \"file2.txt\")))\n{\n  using (StreamWriter writer2 = new StreamWriter(file2))\n  {\n    try\n    {\n      writer2.WriteLine(\"Welcome, .NET!\");\n    }\n    catch(Exception ex)\n    {\n      WriteLine($\"{ex.GetType()} says {ex.Message}\");\n    }\n  } \/\/ Automatically calls Dispose if the object is not null.\n} \/\/ Automatically calls Dispose if the object is not null.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You can even simplify the code further by not explicitly specifying the braces and indentation for the <code class=\"calibre9\">using<\/code> statements, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using FileStream file2 = File.OpenWrite(\n  Path.Combine(path, \"file2.txt\"));\nusing StreamWriter writer2 = new(file2);\ntry\n{\n  writer2.WriteLine(\"Welcome, .NET!\");\n}\ncatch(Exception ex)\n{\n  WriteLine($\"{ex.GetType()} says {ex.Message}\");\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"10.3.9\" id=\"calibre_link-521\">\n<h3 data-number=\"10.3.9\" class=\"calibre8\">Compressing streams<\/h3>\n<p class=\"rights\">XML is relatively verbose, so it takes up more space in bytes than plain text. Let's see how we can squeeze the XML using a common compression algorithm known as GZIP.In .NET Core 2.1, Microsoft introduced an implementation of the Brotli compression algorithm. In performance, Brotli is like the algorithm used in DEFLATE and GZIP, but the output is about 20% denser.Let's compare the two compression algorithms:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Program.Compress.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Compress.cs<\/code>, write statements to use instances of <code class=\"calibre9\">GZipStream<\/code> or <code class=\"calibre9\">BrotliStream<\/code> to create a compressed file containing the same XML elements as before, and then decompress it while reading it and outputting to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Packt.Shared; \/\/ To use Viper.\nusing System.IO.Compression; \/\/ To use BrotliStream, GZipStream.\nusing System.Xml; \/\/ To use XmlWriter, XmlReader.\npartial class Program\n{\n  private static void Compress(string algorithm = \"gzip\")\n  {\n    \/\/ Define a file path using the algorithm as file extension.\n    string filePath = Combine(\n      CurrentDirectory, $\"streams.{algorithm}\");\n    FileStream file = File.Create(filePath);\n    Stream compressor;\n    if (algorithm == \"gzip\")\n    {\n      compressor = new GZipStream(file, CompressionMode.Compress);\n    }\n    else\n    {\n      compressor = new BrotliStream(file, CompressionMode.Compress);\n    }\n    using (compressor)\n    {\n      using (XmlWriter xml = XmlWriter.Create(compressor))\n      {\n        xml.WriteStartDocument();\n        xml.WriteStartElement(\"callsigns\");\n        foreach (string item in Viper.Callsigns)\n        {\n          xml.WriteElementString(\"callsign\", item);\n        }\n      }\n    } \/\/ Also closes the underlying stream.\n    OutputFileInfo(filePath);\n    \/\/ Read the compressed file.\n    WriteLine(\"Reading the compressed XML file:\");\n    file = File.Open(filePath, FileMode.Open);\n    Stream decompressor;\n    if (algorithm == \"gzip\")\n    {\n      decompressor = new GZipStream(\n        file, CompressionMode.Decompress);\n    }\n    else\n    {\n      decompressor = new BrotliStream(\n        file, CompressionMode.Decompress);\n    }\n    using (decompressor)\n    \n    using (XmlReader reader = XmlReader.Create(decompressor))\n    \n    while (reader.Read())\n    {\n      \/\/ Check if we are on an element node named callsign.\n      if ((reader.NodeType == XmlNodeType.Element)\n        &amp;&amp; (reader.Name == \"callsign\"))\n      {\n        reader.Read(); \/\/ Move to the text inside element.\n        WriteLine($\"{reader.Value}\"); \/\/ Read its value.\n      }\n      \/\/ Alternative syntax with property pattern matching:\n      \/\/ if (reader is { NodeType: XmlNodeType.Element,\n      \/\/   Name: \"callsign\" })\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add calls to <code class=\"calibre9\">Compress<\/code> with parameters to use <code class=\"calibre9\">gzip<\/code> and <code class=\"calibre9\">brotli<\/code> algorithms, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Compressing streams\");\nCompress(algorithm: \"gzip\");\nCompress(algorithm: \"brotli\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, and compare the sizes of the XML file and the compressed XML file using <code class=\"calibre9\">gzip<\/code> and <code class=\"calibre9\">brotli<\/code> algorithms, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">**** File Info ****\nFile: streams.gzip\nPath: C:\\cs12dotnet8\\Chapter09\\WorkingWithStreams\\bin\\Debug\\net8.0\nSize: 151 bytes.\n\/------------------\n?\nz?{??}En?BYjQqf~???????Bj^r~Jf^??RiI??????MrbNNqfz^1?i?QZ??Zd?@H?$%?&amp;gc?t,?????*????H?????t?&amp;?d??%b??H?aUPbrjIQ\"??b;????9\n------------------\/\nReading the compressed XML file:\nHusker\nStarbuck\nApollo\nBoomer\nBulldog\nAthena\nHelo\nRacetrack\n**** File Info ****\nFile: streams.brotli\nPath: C:\\cs12dotnet8\\Chapter09\\WorkingWithStreams\\bin\\Debug\\net8.0\nSize: 117 bytes.\n\/-------------------\n ??d?&amp;?_????\\@?Gm????\/?h&gt;?6????? ??^?__???wE?'?t&lt;J??]??\n???b?\\fA?&gt;?+??F??]\n?T?\\?~??A?J?Q?q6 ?\u2011??\n???\n--------------------\/\nReading the compressed XML file:\nHusker\nStarbuck\nApollo\nBoomer\nBulldog\nAthena\nHelo\nRacetrack<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To summarize:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Uncompressed: 320 bytes<\/li>\n<li class=\"calibre3\">GZIP-compressed: 151 bytes<\/li>\n<li class=\"calibre3\">Brotli compressed: 117 bytes<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">As well as choosing a compression mode, you can also choose a compression level. You can learn more about this at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.io.compression.compressionlevel\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.io.compression.compressionlevel<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"10.3.10\" id=\"calibre_link-522\">\n<h3 data-number=\"10.3.10\" class=\"calibre8\">Reading and writing with random access handles<\/h3>\n<p class=\"rights\">For the first 20 years of .NET's life, the only API to work directly with files was the stream classes. These work great for automated tasks that only need to process data sequentially. But when a human interacts with the data, they often want to jump around and return multiple times to the same location. With .NET 6 and later, there is a new API for working with files without needing a file stream and in a random access way. Let's see a simple example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">WorkingWithRandomAccess<\/code> to the <code class=\"calibre9\">Chapter09<\/code> solution:<\/li>\n<li class=\"calibre3\">In the project file, add an element to import the <code class=\"calibre9\">System.Console<\/code> class statically and globally.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, and then get a handle to a file named <code class=\"calibre9\">coffee.txt<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.Win32.SafeHandles; \/\/ To use SafeFileHandle.\nusing System.Text; \/\/ To use Encoding.\nusing SafeFileHandle handle = \n  File.OpenHandle(path: \"coffee.txt\", \n    mode: FileMode.OpenOrCreate,\n    access: FileAccess.ReadWrite);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Write some text encoded as a byte array, and then store it in a read-only memory buffer to the file, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string message = \"Caf\u00e9 \u00a34.39\";\nReadOnlyMemory&lt;byte&gt; buffer = new(Encoding.UTF8.GetBytes(message));\nawait RandomAccess.WriteAsync(handle, buffer, fileOffset: 0);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">To read from the file, get the length of the file, allocate a memory buffer for the contents using that length, and then read the file, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">long length = RandomAccess.GetLength(handle);\nMemory&lt;byte&gt; contentBytes = new(new byte[length]);\nawait RandomAccess.ReadAsync(handle, contentBytes, fileOffset: 0);\nstring content = Encoding.UTF8.GetString(contentBytes.ToArray());\nWriteLine($\"Content of file: {content}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, and note the content of the file, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Content of file: Caf\u00e9 \u00a34.39<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"10.4\" id=\"calibre_link-523\">\n<h2 data-number=\"10.4\" class=\"calibre5\">Encoding and decoding text<\/h2>\n<p class=\"rights\">Text characters can be represented in different ways. For example, the alphabet can be encoded using Morse code into a series of dots and dashes for transmission over a telegraph line.In a similar way, text inside a computer is stored as bits (ones and zeros) representing a code point within a code space. Most code points represent a single character, but they can also have other meanings like formatting.For example, ASCII has a code space with 128 code points. .NET uses a standard called <strong class=\"calibre2\">Unicode<\/strong> to encode text internally. Unicode has more than 1 million code points.Sometimes, you will need to move text outside .NET for use by systems that do not use Unicode or a variation of it, so it is important to learn how to convert between encodings.Some common text encodings used by computers are shown in <em class=\"calibre10\">Table 9.6<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Encoding<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ASCII<\/td>\n<td class=\"calibre21\">This encodes a limited range of characters using the lower seven bits of a byte.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">UTF-8<\/td>\n<td class=\"calibre21\">This represents each Unicode code point as a sequence of one to four bytes.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">UTF-7<\/td>\n<td class=\"calibre21\">This is designed to be more efficient over 7-bit channels than UTF-8, but it has security and robustness issues, so UTF-8 is recommended over UTF-7.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">UTF-16<\/td>\n<td class=\"calibre21\">This represents each Unicode code point as a sequence of one or two 16-bit integers.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">UTF-32<\/td>\n<td class=\"calibre21\">This represents each Unicode code point as a 32-bit integer and is, therefore, a fixed-length encoding unlike the other Unicode encodings, which are all variable-length encodings.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">ANSI\/ISO encodings<\/td>\n<td class=\"calibre21\">This provides support for a variety of code pages that are used to support a specific language or group of languages.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 9.6: Common text encodings<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: In most cases today, UTF-8 is a good default, which is why it is literally the default encoding, that is, <code class=\"calibre9\">Encoding.Default<\/code>. You should avoid using <code class=\"calibre9\">Encoding.UTF7<\/code> because it is not secure. Due to this, the C# compiler will warn you when you try to use UTF-7. Of course, you might need to generate text using that encoding for compatibility with another system, so it needs to remain an option in .NET.<\/p>\n<\/blockquote>\n<section data-number=\"10.4.1\" id=\"calibre_link-524\">\n<h3 data-number=\"10.4.1\" class=\"calibre8\">Encoding strings as byte arrays<\/h3>\n<p class=\"rights\">Let's explore text encodings:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">WorkingWithEncodings<\/code> to the <code class=\"calibre9\">Chapter09<\/code> solution.<\/li>\n<li class=\"calibre3\">In the project file, add an element to statically and globally import the <code class=\"calibre9\">System.Console<\/code> class.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, import the <code class=\"calibre9\">System.Text<\/code> namespace, add statements to encode a <code class=\"calibre9\">string<\/code> using an encoding chosen by the user, loop through each byte, and then decode it back into a <code class=\"calibre9\">string<\/code> and output it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Text; \/\/ To use Encoding.\nWriteLine(\"Encodings\"); \nWriteLine(\"[1] ASCII\");\nWriteLine(\"[2] UTF-7\");\nWriteLine(\"[3] UTF-8\");\nWriteLine(\"[4] UTF-16 (Unicode)\");\nWriteLine(\"[5] UTF-32\");\nWriteLine(\"[6] Latin1\");\nWriteLine(\"[any other key] Default encoding\");\nWriteLine();\nWrite(\"Press a number to choose an encoding.\"); \nConsoleKey number = ReadKey(intercept: true).Key; \nWriteLine(); WriteLine();\nEncoding encoder = number switch\n{\n  ConsoleKey.D1 or ConsoleKey.NumPad1 =&gt; Encoding.ASCII,\n  ConsoleKey.D2 or ConsoleKey.NumPad2 =&gt; Encoding.UTF7,\n  ConsoleKey.D3 or ConsoleKey.NumPad3 =&gt; Encoding.UTF8,\n  ConsoleKey.D4 or ConsoleKey.NumPad4 =&gt; Encoding.Unicode,\n  ConsoleKey.D5 or ConsoleKey.NumPad5 =&gt; Encoding.UTF32,\n  ConsoleKey.D6 or ConsoleKey.NumPad6 =&gt; Encoding.Latin1,\n  _  =&gt; Encoding.Default\n};\n\/\/ Define a string to encode\nstring message = \"Caf\u00e9 \u00a34.39\";\nWriteLine($\"Text to encode: {message}  Characters: {message.Length}.\");\n\/\/ Encode the string into a byte array.\nbyte[] encoded = encoder.GetBytes(message);\n\/\/ Check how many bytes the encoding needed.\nWriteLine(\"{0} used {1:N0} bytes.\",\n  encoder.GetType().Name, encoded.Length);\nWriteLine();\n\/\/ Enumerate each byte.\nWriteLine(\"BYTE | HEX | CHAR\");\nforeach (byte b in encoded)\n{\n  WriteLine($\"{b,4} | {b,3:X} | {(char)b,4}\");\n}\n\/\/ Decode the byte array back into a string and display it.\nstring decoded = encoder.GetString(encoded); \nWriteLine($\"Decoded: {decoded}\"); <\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, press <span>1<\/span> to choose ASCII, and note that when outputting the bytes, the pound sign (<code class=\"calibre9\">\u00a3<\/code>) and accented e (<code class=\"calibre9\">\u00e9<\/code>) cannot be represented in ASCII, so it uses a question mark instead:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Text to encode: Caf\u00e9 \u00a34.39  Characters: 10\nASCIIEncodingSealed used 10 bytes.\nBYTE | HEX | CHAR\n  67 |  43 |    C\n  97 |  61 |    a\n 102 |  66 |    f\n  63 |  3F |    ?\n  32 |  20 |\n  63 |  3F |    ?\n  52 |  34 |    4\n  46 |  2E |    .\n  51 |  33 |    3\n  57 |  39 |    9\nDecoded: Caf? ?4.39<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Rerun the code and press <span>3<\/span> to choose UTF-8. Note that UTF-8 requires 2 extra bytes for the two characters that need 2 bytes each (12 bytes instead of 10 bytes in total), but it can encode and decode the \u00e9 and \u00a3 characters:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Text to encode: Caf\u00e9 \u00a34.39  Characters: 10\nUTF8EncodingSealed used 12 bytes.\nBYTE | HEX | CHAR\n  67 |  43 |    C\n  97 |  61 |    a\n 102 |  66 |    f\n 195 |  C3 |    \u00c3\n 169 |  A9 |    \u00a9\n  32 |  20 |\n 194 |  C2 |    \u00c2\n 163 |  A3 |    \u00a3\n  52 |  34 |    4\n  46 |  2E |    .\n  51 |  33 |    3\n  57 |  39 |    9\nDecoded: Caf\u00e9 \u00a34.39<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Rerun the code and press <span>4<\/span> to choose Unicode (UTF-16). Note that UTF-16 requires 2 bytes for every character, so 20 bytes in total, and it can encode and decode the \u00e9 and \u00a3 characters. This encoding is used internally by .NET to store <code class=\"calibre9\">char<\/code> and <code class=\"calibre9\">string<\/code> values.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"10.4.2\" id=\"calibre_link-525\">\n<h3 data-number=\"10.4.2\" class=\"calibre8\">Encoding and decoding text in files<\/h3>\n<p class=\"rights\">When using stream helper classes, such as <code class=\"calibre9\">StreamReader<\/code> and <code class=\"calibre9\">StreamWriter<\/code>, you can specify the encoding you want to use. As you write to the helper, the text will be automatically encoded, and as you read from the helper, the bytes will be automatically decoded.To specify an encoding, pass the encoding as a second parameter to the helper type's constructor, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">StreamReader reader = new(stream, Encoding.UTF8); \nStreamWriter writer = new(stream, Encoding.UTF8);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Often, you won't have the choice of which encoding to use because you will generate a file for use by another system. However, if you do, pick one that uses the least number of bytes but can store every character you need.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"10.5\" id=\"calibre_link-526\">\n<h2 data-number=\"10.5\" class=\"calibre5\">Serializing object graphs<\/h2>\n<p class=\"rights\">An <strong class=\"calibre2\">object graph<\/strong> is a structure of multiple objects that are related to each other, either through a direct reference or indirectly through a chain of references.<strong class=\"calibre2\">Serialization<\/strong> is the process of converting a live object graph into a sequence of bytes using a specified format. <strong class=\"calibre2\">Deserialization<\/strong> is the reverse process. You would use serialization to save the current state of a live object so that you can recreate it in the future, for example, saving the current state of a game so that you can continue at the same place tomorrow. The stream produced from a serialized object is usually stored in a file or database.There are dozens of formats you can choose for serialization, but the two most common text-based human-readable formats are <strong class=\"calibre2\">eXtensible Markup Language<\/strong> (<strong class=\"calibre2\">XML<\/strong>) and <strong class=\"calibre2\">JavaScript Object Notation<\/strong> (<strong class=\"calibre2\">JSON<\/strong>). There are also more efficient binary formats like Protobuf used by gRPC.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: JSON is more compact and is best for web and mobile applications. XML is more verbose but is better supported in more legacy systems. Use JSON to minimize the size of serialized object graphs. JSON is also a good choice when sending object graphs to web applications and mobile applications because JSON is the native serialization format for JavaScript, and mobile apps often make calls over limited bandwidth, so the number of bytes is important.<\/p>\n<\/blockquote>\n<p class=\"rights\">.NET has multiple classes that will serialize to and from XML and JSON. We will start by looking at <code class=\"calibre9\">XmlSerializer<\/code> and <code class=\"calibre9\">JsonSerializer<\/code>.<\/p>\n<section data-number=\"10.5.1\" id=\"calibre_link-527\">\n<h3 data-number=\"10.5.1\" class=\"calibre8\">Serializing as XML<\/h3>\n<p class=\"rights\">Let's start by looking at XML, probably the world's most used serialization format (for now). To show a typical example, we will define a custom class to store information about a person and then create an object graph, using a list of <code class=\"calibre9\">Person<\/code> instances with nesting:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">WorkingWithSerialization<\/code> to the <code class=\"calibre9\">Chapter09<\/code> solution.<\/li>\n<li class=\"calibre3\">In the project file, add elements to statically and globally import the <code class=\"calibre9\">System.Console<\/code>, <code class=\"calibre9\">System.Environment<\/code>, and <code class=\"calibre9\">System.IO.Path<\/code> classes.<\/li>\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Program.Helpers.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Helpers.cs<\/code>, add a partial <code class=\"calibre9\">Program<\/code> class with a <code class=\"calibre9\">SectionTitle<\/code> and an <code class=\"calibre9\">OutputFileInfo<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ null namespace to merge with auto-generated Program.\npartial class Program\n{\n  private static void SectionTitle(string title)\n  {\n    ConsoleColor previousColor = ForegroundColor;\n    ForegroundColor = ConsoleColor.DarkYellow;\n    WriteLine($\"*** {title} ***\");\n    ForegroundColor = previousColor;\n  }\n  private static void OutputFileInfo(string path)\n  {\n    WriteLine(\"**** File Info ****\");\n    WriteLine($\"File: {GetFileName(path)}\");\n    WriteLine($\"Path: {GetDirectoryName(path)}\");\n    WriteLine($\"Size: {new FileInfo(path).Length:N0} bytes.\");\n    WriteLine(\"\/------------------\");\n    WriteLine(File.ReadAllText(path));\n    WriteLine(\"------------------\/\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Person.cs<\/code> to define a <code class=\"calibre9\">Person<\/code> class with a <code class=\"calibre9\">Salary<\/code> property that is <code class=\"calibre9\">protected<\/code>, meaning it is only accessible to itself and derived classes. To populate the salary, the class has a constructor with a single parameter to set the initial salary, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Packt.Shared;\npublic class Person\n{\n  public Person(decimal initialSalary)\n  {\n    Salary = initialSalary;\n  }\n  public string? FirstName { get; set; }\n  public string? LastName { get; set; }\n  public DateTime DateOfBirth { get; set; }\n  public HashSet&lt;Person&gt;? Children { get; set; }\n  protected decimal Salary { get; set; }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, and then import namespaces to work with XML serialization and the <code class=\"calibre9\">Person<\/code> class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Xml.Serialization; \/\/ To use XmlSerializer.\nusing Packt.Shared; \/\/ To use Person.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to create an object graph of <code class=\"calibre9\">Person<\/code> instances, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">List&lt;Person&gt; people = new()\n{\n  new(initialSalary: 30_000M) \n  {\n    FirstName = \"Alice\",\n    LastName = \"Smith\",\n    DateOfBirth = new(year: 1974, month: 3, day: 14)\n  },\n  new(initialSalary: 40_000M) \n  {\n    FirstName = \"Bob\",\n    LastName = \"Jones\",\n    DateOfBirth = new(year: 1969, month: 11, day: 23)\n  },\n  new(initialSalary: 20_000M)\n  {\n    FirstName = \"Charlie\",\n    LastName = \"Cox\",\n    DateOfBirth = new(year: 1984, month: 5, day: 4),\n    Children = new()\n    {\n      new(initialSalary: 0M)\n      {\n        FirstName = \"Sally\",\n        LastName = \"Cox\",\n        DateOfBirth = new(year: 2012, month: 7, day: 12)\n      }\n    }\n  }\n};\nSectionTitle(\"Serializing as XML\");\n\/\/ Create serializer to format a \"List of Person\" as XML.\nXmlSerializer xs = new(type: people.GetType());\n\/\/ Create a file to write to.\nstring path = Combine(CurrentDirectory, \"people.xml\");\nusing (FileStream stream = File.Create(path))\n{\n  \/\/ Serialize the object graph to the stream.\n  xs.Serialize(stream, people);\n} \/\/ Closes the stream.\nOutputFileInfo(path);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that an exception is thrown, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Unhandled Exception: System.InvalidOperationException: Packt.Shared.Person cannot be serialized because it does not have a parameterless constructor.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, add a statement to define a <code class=\"calibre9\">parameterless constructor<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ A parameterless constructor is required for XML serialization.\npublic Person() { }<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The constructor does not need to do anything, but it must exist so that the <code class=\"calibre9\">XmlSerializer<\/code> can call it to instantiate new <code class=\"calibre9\">Person<\/code> instances during the deserialization process.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, and note that the object graph is serialized as XML elements, like <code class=\"calibre9\">&lt;FirstName&gt;Bob&lt;\/FirstName&gt;<\/code>, and that the <code class=\"calibre9\">Salary<\/code> property is not included because it is not a <code class=\"calibre9\">public<\/code> property, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">**** File Info ****\nFile: people.xml\nPath: C:\\cs12dotnet8\\Chapter09\\WorkingWithSerialization\\bin\\Debug\\net8.0\nSize: 793 bytes.\n\/------------------\n&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;ArrayOfPerson xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xmlns:xsd=\"http:\/\/www.w3.org\/2001\/XMLSchema\"&gt;\n  &lt;Person&gt;\n    &lt;FirstName&gt;Alice&lt;\/FirstName&gt;\n    &lt;LastName&gt;Smith&lt;\/LastName&gt;\n    &lt;DateOfBirth&gt;1974-03-14T00:00:00&lt;\/DateOfBirth&gt;\n  &lt;\/Person&gt;\n  &lt;Person&gt;\n    &lt;FirstName&gt;Bob&lt;\/FirstName&gt;\n    &lt;LastName&gt;Jones&lt;\/LastName&gt;\n    &lt;DateOfBirth&gt;1969-11-23T00:00:00&lt;\/DateOfBirth&gt;\n  &lt;\/Person&gt;\n  &lt;Person&gt;\n    &lt;FirstName&gt;Charlie&lt;\/FirstName&gt;\n    &lt;LastName&gt;Cox&lt;\/LastName&gt;\n    &lt;DateOfBirth&gt;1984-05-04T00:00:00&lt;\/DateOfBirth&gt;\n    &lt;Children&gt;\n      &lt;Person&gt;\n        &lt;FirstName&gt;Sally&lt;\/FirstName&gt;\n        &lt;LastName&gt;Cox&lt;\/LastName&gt;\n        &lt;DateOfBirth&gt;2012-07-12T00:00:00&lt;\/DateOfBirth&gt;\n      &lt;\/Person&gt;\n    &lt;\/Children&gt;\n  &lt;\/Person&gt;\n&lt;\/ArrayOfPerson&gt;\n------------------\/<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"10.5.2\" id=\"calibre_link-528\">\n<h3 data-number=\"10.5.2\" class=\"calibre8\">Generating compact XML<\/h3>\n<p class=\"rights\">We could make the XML more compact using attributes instead of elements for some fields:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Person.cs<\/code>, import the <code class=\"calibre9\">System.Xml.Serialization<\/code> namespace so that you can decorate some properties with the <code class=\"calibre9\">[XmlAttribute]<\/code> attribute, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Xml.Serialization; \/\/ To use [XmlAttribute].<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Person.cs<\/code>, decorate the first name, last name, and date of birth properties with the <code class=\"calibre9\">[XmlAttribute]<\/code> attribute, and set a short name for each property, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[XmlAttribute(\"fname\")]\npublic string? FirstName { get; set; }\n[XmlAttribute(\"lname\")]\npublic string? LastName { get; set; }\n[XmlAttribute(\"dob\")]\npublic DateTime DateOfBirth { get; set; }<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, and note that the size of the file has reduced from 793 to 488 bytes, a space-saving of more than a third. This reduction was achieved by outputting property values as XML attributes, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">**** File Info ****\nFile: people.xml\nPath: C:\\cs12dotnet8\\Chapter09\\WorkingWithSerialization\\bin\\Debug\\net8.0\nSize: 488 bytes.\n\/------------------\n&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;ArrayOfPerson xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xmlns:xsd=\"http:\/\/www.w3.org\/2001\/XMLSchema\"&gt;\n  &lt;Person fname=\"Alice\" lname=\"Smith\" dob=\"1974-03-14T00:00:00\" \/&gt;\n  &lt;Person fname=\"Bob\" lname=\"Jones\" dob=\"1969-11-23T00:00:00\" \/&gt;\n  &lt;Person fname=\"Charlie\" lname=\"Cox\" dob=\"1984-05-04T00:00:00\"&gt;\n    &lt;Children&gt;\n      &lt;Person fname=\"Sally\" lname=\"Cox\" dob=\"2012-07-12T00:00:00\" \/&gt;\n    &lt;\/Children&gt;\n  &lt;\/Person&gt;\n&lt;\/ArrayOfPerson&gt;\n------------------\/<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"10.5.3\" id=\"calibre_link-529\">\n<h3 data-number=\"10.5.3\" class=\"calibre8\">Deserializing XML files<\/h3>\n<p class=\"rights\">Now, let's try deserializing the XML file back into live objects in memory:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to open the XML file, and then deserialize it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Deserializing XML files\");\nusing (FileStream xmlLoad = File.Open(path, FileMode.Open))\n{\n  \/\/ Deserialize and cast the object graph into a \"List of Person\".\n  List&lt;Person&gt;? loadedPeople =\n    xs.Deserialize(xmlLoad) as List&lt;Person&gt;;\n  if (loadedPeople is not null)\n  {\n    foreach (Person p in loadedPeople)\n    {\n      WriteLine(\"{0} has {1} children.\", \n        p.LastName, p.Children?.Count ?? 0);\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, and note that the people are loaded successfully from the XML file and then enumerated, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Smith has 0 children.\nJones has 0 children.\nCox has 1 children.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: There are many other attributes defined in the <code class=\"calibre9\">System.Xml.Serialization<\/code> namespace that can be used to control the XML generated. A good place to start is the official documentation for the <code class=\"calibre9\">XmlAttributeAttribute<\/code> class found here: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.xml.serialization.xmlattributeattribute\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.xml.serialization.xmlattributeattribute<\/a>. Do not get this class confused with the <code class=\"calibre9\">XmlAttribute<\/code> class in the <code class=\"calibre9\">System.Xml<\/code> namespace. That is used to represent an XML attribute when reading and writing XML, using <code class=\"calibre9\">XmlReader<\/code> and <code class=\"calibre9\">XmlWriter<\/code>.<\/p>\n<\/blockquote>\n<p class=\"rights\">If you don't use any annotations, <code class=\"calibre9\">XmlSerializer<\/code> performs a case-insensitive match using the property name when deserializing.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: When using <code class=\"calibre9\">XmlSerializer<\/code>, remember that only the public fields and properties are included, and the type must have a parameterless constructor. You can customize the output with attributes.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"10.5.4\" id=\"calibre_link-530\">\n<h3 data-number=\"10.5.4\" class=\"calibre8\">Serializing with JSON<\/h3>\n<p class=\"rights\">One of the most popular .NET libraries to work with the JSON serialization format is <strong class=\"calibre2\">Newtonsoft.Json<\/strong>, known as <strong class=\"calibre2\">Json.NET<\/strong>. It is mature and powerful. Newtonsoft.Json is so popular that it overflowed the bounds of the 32-bit integer used for the download count in the NuGet package manager, as shown in the following tweet in <em class=\"calibre10\">Figure 9.5<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 9.5: Negative 2 billion downloads for Newtonsoft.Json in August 2022\" height=\"474\" src=\"\/images\/cs12\/000055.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 9.5: Negative 2 billion downloads for Newtonsoft.Json in August 2022<\/figcaption><\/figure>\n<p class=\"rights\">Let's see it in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithSerialization<\/code> project, add a package reference for the latest version of <code class=\"calibre9\">Newtonsoft.Json<\/code>, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.3\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">WorkingWithSerialization<\/code> project to restore packages.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to create a text file, and then serialize the people into the file as JSON, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Serializing with JSON\");\n\/\/ Create a file to write to.\nstring jsonPath = Combine(CurrentDirectory, \"people.json\");\nusing (StreamWriter jsonStream = File.CreateText(jsonPath))\n{\n  Newtonsoft.Json.JsonSerializer jss = new();\n  \/\/ Serialize the object graph into a string.\n  jss.Serialize(jsonStream, people);\n} \/\/ Closes the file stream and release resources.\nOutputFileInfo(jsonPath);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, and note that JSON requires fewer than half the number of bytes compared to XML with elements. It's even smaller than the XML file, which uses attributes (366 compared to 488), as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">**** File Info ****\nFile: people.json\nPath: C:\\cs12dotnet8\\Chapter09\\WorkingWithSerialization\\bin\\Debug\\net8.0\nSize: 366 bytes.\n\/------------------\n[{\"FirstName\":\"Alice\",\"LastName\":\"Smith\",\"DateOfBirth\":\"1974-03-14T00:00:00\",\"Children\":null},{\"FirstName\":\"Bob\",\"LastName\":\"Jones\",\"DateOfBirth\":\"1969-11-23T00:00:00\",\"Children\":null},{\"FirstName\":\"Charlie\",\"LastName\":\"Cox\",\"DateOfBirth\":\"1984-05-04T00:00:00\",\"Children\":[{\"FirstName\":\"Sally\",\"LastName\":\"Cox\",\"DateOfBirth\":\"2012-07-12T00:00:00\",\"Children\":null}]}]\n------------------\/<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"10.5.5\" id=\"calibre_link-531\">\n<h3 data-number=\"10.5.5\" class=\"calibre8\">High-performance JSON processing<\/h3>\n<p class=\"rights\">.NET Core 3 introduced a new namespace to work with JSON, <code class=\"calibre9\">System.Text.Json<\/code>, which is optimized for performance by leveraging APIs like <code class=\"calibre9\">Span&lt;T&gt;<\/code>.Also, older libraries like Json.NET are implemented by reading UTF-16. It would be more performant to read and write JSON documents using UTF-8 because most network protocols, including HTTP, use UTF-8, and you can avoid transcoding UTF-8 to and from Json.NET's Unicode <code class=\"calibre9\">string<\/code> values.With the new API, Microsoft achieved between 1.3x and 5x improvement, depending on the scenario.The original author of Json.NET, James Newton-King, joined Microsoft and is working with them to develop their new JSON types. As he says in a comment discussing the new JSON APIs, \"<em class=\"calibre10\">Json.NET isn't going away<\/em>,\" as shown in <em class=\"calibre10\">Figure 9.6<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 9.6: A comment by the original author of Json.NET\" height=\"199\" src=\"\/images\/cs12\/000069.png\" width=\"927\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 9.6: A comment by the original author of Json.NET<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"10.5.6\" id=\"calibre_link-532\">\n<h3 data-number=\"10.5.6\" class=\"calibre8\">Deserializing JSON files<\/h3>\n<p class=\"rights\">Let's see how to use the modern JSON APIs to deserialize a JSON file:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithSerialization<\/code> project, at the top of <code class=\"calibre9\">Program.cs<\/code>, import the new JSON class to perform serialization, using an alias to avoid conflicting names with the Json.NET one we used before, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using FastJson = System.Text.Json.JsonSerializer;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to open the JSON file, deserialize it, and output the names and counts of the children of the people, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Deserializing JSON files\");\nawait using (FileStream jsonLoad = File.Open(jsonPath, FileMode.Open))\n{\n  \/\/ Deserialize object graph into a \"List of Person\".\n  List&lt;Person&gt;? loadedPeople = \n    await FastJson.DeserializeAsync(utf8Json: jsonLoad,\n      returnType: typeof(List&lt;Person&gt;)) as List&lt;Person&gt;;\n  if (loadedPeople is not null)\n  {\n    foreach (Person p in loadedPeople)\n    {\n      WriteLine(\"{0} has {1} children.\",\n        p.LastName, p.Children?.Count ?? 0);\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Smith has 0 children. \nJones has 0 children. \nCox has 1 children.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Choose Json.NET for developer productivity and a large feature set, or <code class=\"calibre9\">System.Text.Json<\/code> for performance. You can review a list of the differences at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/serialization\/system-text-json-migrate-from-newtonsoft-how-to#table-of-differences-between-newtonsoftjson-and-systemtextjson\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/serialization\/system-text-json-migrate-from-newtonsoft-how-to#table-of-differences-between-newtonsoftjson-and-systemtextjson<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"10.5.7\" id=\"calibre_link-533\">\n<h3 data-number=\"10.5.7\" class=\"calibre8\">Controlling JSON processing<\/h3>\n<p class=\"rights\">There are many options to take control of how JSON is processed, as shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Including and excluding fields.<\/li>\n<li class=\"calibre3\">Setting a casing policy.<\/li>\n<li class=\"calibre3\">Selecting a case-sensitivity policy.<\/li>\n<li class=\"calibre3\">Choosing between compact and prettified whitespace.<\/li>\n<\/ul>\n<p class=\"rights\">Let's see some in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">ControllingJson<\/code> to the <code class=\"calibre9\">Chapter09<\/code> solution.<\/li>\n<li class=\"calibre3\">In the project file, add elements to statically and globally import the <code class=\"calibre9\">System.Console<\/code>, <code class=\"calibre9\">System.Environment<\/code>, and <code class=\"calibre9\">System.IO.Path<\/code> classes.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">ControllingJson<\/code> project, add a new class file named <code class=\"calibre9\">Book.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Book.cs<\/code>, define a class named <code class=\"calibre9\">Book<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Text.Json.Serialization; \/\/ To use [JsonInclude].\nnamespace Packt.Shared;\npublic class Book\n{\n  \/\/ Constructor to set non-nullable property.\n  public Book(string title)\n  {\n    Title = title;\n  }\n  \/\/ Properties.\n  public string Title { get; set; }\n  public string? Author { get; set; }\n  \/\/ Fields.\n  [JsonInclude] \/\/ Include this field.\n  public DateTime PublishDate;\n  [JsonInclude] \/\/ Include this field.\n  public DateTimeOffset Created;\n  public ushort Pages;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements, and then import the namespaces to work with high-performance JSON and <code class=\"calibre9\">Book<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Packt.Shared; \/\/ To use Book.\nusing System.Text.Json; \/\/ To use JsonSerializer.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to create an instance of the <code class=\"calibre9\">Book<\/code> class and serialize it to JSON, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Book csharpBook = new(title: \n  \"C# 12 and .NET 8 - Modern Cross-Platform Development Fundamentals\")\n{ \n  Author = \"Mark J Price\",\n  PublishDate = new(year: 2023, month: 11, day: 14),\n  Pages = 823,\n  Created = DateTimeOffset.UtcNow,\n};\nJsonSerializerOptions options = new()\n{\n  IncludeFields = true, \/\/ Includes all fields.\n  PropertyNameCaseInsensitive = true,\n  WriteIndented = true,\n  PropertyNamingPolicy = JsonNamingPolicy.CamelCase,\n};\nstring path = Combine(CurrentDirectory, \"book.json\");\nusing (Stream fileStream = File.Create(path))\n{\n  JsonSerializer.Serialize(\n    utf8Json: fileStream, value: csharpBook, options);\n}\nWriteLine(\"**** File Info ****\");\nWriteLine($\"File: {GetFileName(path)}\");\nWriteLine($\"Path: {GetDirectoryName(path)}\");\nWriteLine($\"Size: {new FileInfo(path).Length:N0} bytes.\");\nWriteLine(\"\/------------------\");\nWriteLine(File.ReadAllText(path));\nWriteLine(\"------------------\/\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">**** File Info ****\nFile: book.json\nPath: C:\\cs12dotnet8\\Chapter09\\ControllingJson\\bin\\Debug\\net8.0\nSize: 221 bytes.\n\/------------------\n{\n  \"title\": \"C# 12 and .NET 8 - Modern Cross-Platform Development Fundamentals\",\n  \"author\": \"Mark J Price\",\n  \"publishDate\": \"2023-11-14T00:00:00\",\n  \"created\": \"2023-07-13T14:29:07.119631+00:00\",\n  \"pages\": 823\n}\n------------------\/<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The JSON file is 221 bytes.<\/li>\n<li class=\"calibre3\">The member names use camelCasing, for example, <code class=\"calibre9\">publishDate<\/code>. This is best for subsequent processing in a browser with JavaScript.<\/li>\n<li class=\"calibre3\">All fields are included due to the options set, including <code class=\"calibre9\">pages<\/code>.<\/li>\n<li class=\"calibre3\">JSON is prettified for easier human legibility.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">DateTime<\/code> and <code class=\"calibre9\">DateTimeOffset<\/code> values are stored as a single standard <code class=\"calibre9\">string<\/code> format.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, when setting the <code class=\"calibre9\">JsonSerializerOptions<\/code>, comment out the setting of casing policy, write with an indent, and include fields.<\/li>\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">**** File Info ****\nFile: book.json\nPath: C:\\cs12dotnet8\\Chapter09\\ControllingJson\\bin\\Debug\\net8.0\nSize: 184 bytes.\n\/------------------\n{\"Title\":\"C# 12 and .NET 8 - Modern Cross-Platform Development Fundamentals\",\"Author\":\"Mark J Price\",\"PublishDate\":\"2023-11-14T00:00:00\",\"Created\":\"2023-07-13T14:30:29.2205861+00:00\"}\n------------------\/<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The JSON file has about a 20% reduction.<\/li>\n<li class=\"calibre3\">The member names use normal casing, for example, <code class=\"calibre9\">PublishDate<\/code>.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">Pages<\/code> field is missing. The other fields are included due to the <code class=\"calibre9\">[JsonInclude]<\/code> attribute on the <code class=\"calibre9\">PublishDate<\/code> and <code class=\"calibre9\">Created<\/code> fields.<\/li>\n<\/ul>\n<\/section>\n<\/section>\n<section data-number=\"10.6\" id=\"calibre_link-534\">\n<h2 data-number=\"10.6\" class=\"calibre5\">Working with environment variables<\/h2>\n<p class=\"rights\">Environment variables are system and user-definable values that can affect the way running processes behave. They are commonly used to set options like toggling between development and production configurations in ASP.NET Core web projects, or to pass values needed by a process like service keys and passwords for database connection strings.Environment variables on Windows can be set at three scope levels: machine (aka system), user, and process. The methods for setting and getting environment variables assume process scope level by default and have overloads to specify the <code class=\"calibre9\">EnvironmentVariableTarget<\/code> of <code class=\"calibre9\">Process<\/code>, <code class=\"calibre9\">User<\/code>, and <code class=\"calibre9\">Machine<\/code>, as shown in <em class=\"calibre10\">Table 9.7<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Method<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">GetEnvironmentVariables<\/code><\/td>\n<td class=\"calibre21\">Returns an <code class=\"calibre9\">IDictionary<\/code> of all environment variables at a specified scope level or for the current process by default.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">GetEnvironmentVariable<\/code><\/td>\n<td class=\"calibre21\">Returns the value for a named environment variable.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">SetEnvironmentVariable<\/code><\/td>\n<td class=\"calibre21\">Sets the value for a named environment variable.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ExpandEnvironmentVariables<\/code><\/td>\n<td class=\"calibre21\">Converts any environment variables in a <code class=\"calibre9\">string<\/code> to their values identified with <code class=\"calibre9\">%%<\/code> . For example, <code class=\"calibre9\">\"My computer is named %COMPUTER_NAME%\"<\/code> .<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 9.7: Methods to work with environment variables<\/p>\n<section data-number=\"10.6.1\" id=\"calibre_link-535\">\n<h3 data-number=\"10.6.1\" class=\"calibre8\">Reading all environment variables<\/h3>\n<p class=\"rights\">Let's start by looking at how to list all current environment variables at various levels of scope:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">WorkingWithEnvVars<\/code> to the <code class=\"calibre9\">Chapter09<\/code> solution.<\/li>\n<li class=\"calibre3\">In the project file, add a package reference for <code class=\"calibre9\">Spectre.Console<\/code>, and then add elements to statically and globally import the <code class=\"calibre9\">System.Console<\/code> and <code class=\"calibre9\">System.Environment<\/code> classes, and finally import the namespaces to work with <code class=\"calibre9\">Spectre.Console<\/code> and <code class=\"calibre9\">System.Collections<\/code>, as shown in the following configuration:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;PackageReference Include=\"Spectre.Console\" Version=\"0.47.0\" \/&gt;\n&lt;\/ItemGroup&gt;\n&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n  &lt;Using Include=\"System.Environment\" Static=\"true\" \/&gt;\n  &lt;Using Include=\"Spectre.Console\" \/&gt;\n  &lt;Using Include=\"System.Collections\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Program.Helpers.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Helpers.cs<\/code>, add a partial <code class=\"calibre9\">Program<\/code> class with a <code class=\"calibre9\">SectionTitle<\/code> and an <code class=\"calibre9\">DictionaryToTable<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ null namespace to merge with auto-generated Program.\npartial class Program\n{\n  private static void SectionTitle(string title)\n  {\n    ConsoleColor previousColor = ForegroundColor;\n    ForegroundColor = ConsoleColor.DarkYellow;\n    WriteLine($\"*** {title} ***\");\n    ForegroundColor = previousColor;\n  }\n  private static void DictionaryToTable(IDictionary dictionary)\n  {\n    Table table = new();\n    table.AddColumn(\"Key\");\n    table.AddColumn(\"Value\");\n    foreach (string key in dictionary.Keys)\n    {\n      table.AddRow(key, dictionary[key]!.ToString()!);\n    }\n    AnsiConsole.Write(table);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete any existing statements, and write statements to show all the environment variables at the three different scopes, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Reading all environment variables for process\");\nIDictionary vars = GetEnvironmentVariables();\nDictionaryToTable(vars);\nSectionTitle(\"Reading all environment variables for machine\");\nIDictionary varsMachine = GetEnvironmentVariables(\n  EnvironmentVariableTarget.Machine);\nDictionaryToTable(varsMachine);\nSectionTitle(\"Reading all environment variables for user\");\nIDictionary varsUser = GetEnvironmentVariables(\n  EnvironmentVariableTarget.User);\nDictionaryToTable(varsUser);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">*** Reading all environment variables for process ***\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Key             \u2502 Value                                            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 HOMEPATH        \u2502 \\Users\\markj                                     \u2502\n...\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"10.6.2\" id=\"calibre_link-536\">\n<h3 data-number=\"10.6.2\" class=\"calibre8\">Expanding, setting, and getting an environment variables<\/h3>\n<p class=\"rights\">Often you need to format a <code class=\"calibre9\">string<\/code> that contains embedded environment variables. They are defined by surrounding the variable name with percent symbols, as shown in the following text:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">My username is %USERNAME%. My CPU is %PROCESSOR_IDENTIFIER%.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To set an environment variable at the command prompt on Windows, use the <code class=\"calibre9\">set<\/code> or <code class=\"calibre9\">setx<\/code> commands, as shown in <em class=\"calibre10\">Table 9.8<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Scope Level<\/td>\n<td class=\"calibre21\">Command<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Session\/Shell<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">set MY_ENV_VAR=\"Alpha\"<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">User<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">setx MY_ENV_VAR \"Beta\"<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Machine<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">setx MY_ENV_VAR \"Gamma\" \/M<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 9.8: Commands to set an environment variable on Windows<\/p>\n<p class=\"rights\">The <code class=\"calibre9\">set<\/code> command defines a temporary environment variable that can be read immediately in the current shell or session. Note that it uses an equal sign <code class=\"calibre9\">=<\/code> to assign the value.The <code class=\"calibre9\">setx<\/code> command defines a permanent environment variable but after defining it, you must close the current shell or session and restart the shell for the environment variable to be read. Note that it does <em class=\"calibre10\">not<\/em> use an equal sign to assign the value!<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about the <code class=\"calibre9\">setx<\/code> command here: <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows-server\/administration\/windows-commands\/setx\">https:\/\/learn.microsoft.com\/en-us\/windows-server\/administration\/windows-commands\/setx<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">You can also manage environment variables with a user interface on Windows: Navigate to <strong class=\"calibre2\">Settings<\/strong> | <strong class=\"calibre2\">System<\/strong> | <strong class=\"calibre2\">About<\/strong> | <strong class=\"calibre2\">Advanced system settings<\/strong>, and then in the <strong class=\"calibre2\">System Properties<\/strong> dialog box, click <strong class=\"calibre2\">Environment Variables<\/strong>.To temporarily set an environment variable at the command prompt or terminal on macOS or Linux, you can use the <code class=\"calibre9\">export<\/code> command, as shown in the following command:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">export MY_ENV_VAR=Delta<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about the <code class=\"calibre9\">export<\/code> command here: <a href=\"https:\/\/ss64.com\/bash\/export.xhtml\">https:\/\/ss64.com\/bash\/export.xhtml<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's see some examples of expanding, setting in various ways, and getting environment variables:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to define a <code class=\"calibre9\">string<\/code> that contains a couple of environment variables (if the ones I picked are not defined on your computer, then pick any other two that you do have defined) and then expand them and output them to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string myComputer = \"My username is %USERNAME%. My CPU is %PROCESSOR_IDENTIFIER%.\";\nWriteLine(ExpandEnvironmentVariables(myComputer));<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">My username is markj. My CPU is Intel64 Family 6 Model 140 Stepping 1, GenuineIntel.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to set a process scoped environment variable named <code class=\"calibre9\">MY_PASSWORD<\/code> and then get it and output it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string password_key = \"MY_PASSWORD\";\nSetEnvironmentVariable(password_key, \"Pa$$w0rd\");\nstring? password = GetEnvironmentVariable(password_key);\nWriteLine($\"{password_key}: {password}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">MY_PASSWORD: Pa$$w0rd<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In a real-world app, you might pass an argument to the console that is then used to set the process scope environment variable on startup for reading later in the process lifetime.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements to try to get an environment variable named <code class=\"calibre9\">MY_PASSWORD<\/code> at all three potential scope levels, and then output them, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string secret_key = \"MY_SECRET\";\nstring? secret = GetEnvironmentVariable(secret_key, \n  EnvironmentVariableTarget.Process);\nWriteLine($\"Process - {secret_key}: {secret}\");\nsecret = GetEnvironmentVariable(secret_key,\n  EnvironmentVariableTarget.Machine);\nWriteLine($\"Machine - {secret_key}: {secret}\");\nsecret = GetEnvironmentVariable(secret_key,\n  EnvironmentVariableTarget.User);\nWriteLine($\"User    - {secret_key}: {secret}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you are using Visual Studio 2022, then navigate to <strong class=\"calibre2\">Project<\/strong> | <strong class=\"calibre2\">WorkingWithEnvVars<\/strong> <strong class=\"calibre2\">Properties<\/strong>, click the Debug tab, and then click <strong class=\"calibre2\">Open debug launch profiles UI<\/strong>. In the <strong class=\"calibre2\">Environment variables<\/strong> section, add an entry with Name <code class=\"calibre9\">MY_SECRET<\/code> and Value of <code class=\"calibre9\">Alpha<\/code>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Properties<\/strong> folder, open <code class=\"calibre9\">launchSettings.json<\/code>, and note the configured environment variables, as shown in the following configuration:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"profiles\": {\n    \"WorkingWithEnvVars\": {\n      \"commandName\": \"Project\",\n      \"environmentVariables\": {\n        \"MY_SECRET\": \"Alpha\"\n      }\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you are using a different code editor, then you can manually create the <code class=\"calibre9\">launchSettings.json<\/code> file. Environment variables defined in the <code class=\"calibre9\">launchSettings.json<\/code> file are set at process scope.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the command prompt or terminal with administrator permissions, set some environment variables at the user and machine scope levels on Windows, as shown in the following commands:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">setx MY_SECRET \"Beta\"\nsetx MY_SECRET \"Gamma\" \/M<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the result for each command, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SUCCESS: Specified value was saved.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">On macOS or Linux, use the <code class=\"calibre9\">export<\/code> command instead.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Process - MY_SECRET: Alpha\nMachine - MY_SECRET: Gamma\nUser    - MY_SECRET: Beta<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Now that you have seen how to work with environment variables, we can use them in future chapters to set options like passwords rather than store those sensitive values in code.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"10.7\" id=\"calibre_link-537\">\n<h2 data-number=\"10.7\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring this chapter's topics with more in-depth research.<\/p>\n<section data-number=\"10.7.1\" id=\"calibre_link-538\">\n<h3 data-number=\"10.7.1\" class=\"calibre8\">Exercise 9.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between using the <code class=\"calibre9\">File<\/code> class and the <code class=\"calibre9\">FileInfo<\/code> class?<\/li>\n<li class=\"calibre3\">What is the difference between the <code class=\"calibre9\">ReadByte<\/code> method and the <code class=\"calibre9\">Read<\/code> method of a stream?<\/li>\n<li class=\"calibre3\">When would you use the <code class=\"calibre9\">StringReader<\/code>, <code class=\"calibre9\">TextReader<\/code>, and <code class=\"calibre9\">StreamReader<\/code> classes?<\/li>\n<li class=\"calibre3\">What does the <code class=\"calibre9\">DeflateStream<\/code> type do?<\/li>\n<li class=\"calibre3\">How many bytes per character does UTF-8 encoding use?<\/li>\n<li class=\"calibre3\">What is an object graph?<\/li>\n<li class=\"calibre3\">What is the best serialization format to choose to minimize space requirements?<\/li>\n<li class=\"calibre3\">What is the best serialization format to choose for cross-platform compatibility?<\/li>\n<li class=\"calibre3\">Why is it bad to use a <code class=\"calibre9\">string<\/code> value like <code class=\"calibre9\">\"\\Code\\Chapter01\"<\/code> to represent a path, and what should you do instead?<\/li>\n<li class=\"calibre3\">Where can you find information about NuGet packages and their dependencies?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"10.7.2\" id=\"calibre_link-539\">\n<h3 data-number=\"10.7.2\" class=\"calibre8\">Exercise 9.2 &ndash; Practice serializing as XML<\/h3>\n<p class=\"rights\">In the <code class=\"calibre9\">Chapter09<\/code> solution, create a console app named <code class=\"calibre9\">Ch09Ex02SerializingShapes<\/code> that creates a list of shapes, uses serialization to save it to the filesystem with XML, and then deserializes it back:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Create a list of Shapes to serialize.\nList&lt;Shape&gt; listOfShapes = new()\n{\n  new Circle { Colour = \"Red\", Radius = 2.5 },\n  new Rectangle { Colour = \"Blue\", Height = 20.0, Width = 10.0 },\n  new Circle { Colour = \"Green\", Radius = 8.0 },\n  new Circle { Colour = \"Purple\", Radius = 12.3 },\n  new Rectangle { Colour = \"Blue\", Height = 45.0, Width = 18.0 }\n};<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Shapes should have a read-only property named <code class=\"calibre9\">Area<\/code> so that when you deserialize, you can output a list of shapes, including their areas, as shown here:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">List&lt;Shape&gt; loadedShapesXml = \n  serializerXml.Deserialize(fileXml) as List&lt;Shape&gt;;\nforeach (Shape item in loadedShapesXml)\n{\n  WriteLine(\"{0} is {1} and has an area of {2:N2}\",\n    item.GetType().Name, item.Colour, item.Area);\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This is what your output should look like when you run your console application:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Loading shapes from XML:\nCircle is Red and has an area of 19.63 \nRectangle is Blue and has an area of 200.00 \nCircle is Green and has an area of 201.06 \nCircle is Purple and has an area of 475.29 \nRectangle is Blue and has an area of 810.00<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"10.7.3\" id=\"calibre_link-540\">\n<h3 data-number=\"10.7.3\" class=\"calibre8\">Exercise 9.3 &ndash; Working with Tar archives<\/h3>\n<p class=\"rights\">If you use Linux, then you will be interested in how to programmatically work with Tar archives. I have written an online-only section to introduce you to them that is found at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch09-tar-archives.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch09-tar-archives.md<\/a><\/p>\n<\/section>\n<section data-number=\"10.7.4\" id=\"calibre_link-541\">\n<h3 data-number=\"10.7.4\" class=\"calibre8\">Exercise 9.4 &ndash; Migrating from Newtonsoft to new JSON<\/h3>\n<p class=\"rights\">If you have existing code that uses the Newtonsoft Json.NET library and you want to migrate to the new <code class=\"calibre9\">System.Text.Json<\/code> namespace, then Microsoft has specific documentation for that that you can find at the following link:<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/serialization\/system-text-json-migrate-from-newtonsoft-how-to\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/serialization\/system-text-json-migrate-from-newtonsoft-how-to<\/a><\/p>\n<\/section>\n<section data-number=\"10.7.5\" id=\"calibre_link-542\">\n<h3 data-number=\"10.7.5\" class=\"calibre8\">Exercise 9.5 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more details about the topics covered in this chapter:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-9---working-with-files-streams-and-serialization\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-9---working-with-files-streams-and-serialization<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"10.8\" id=\"calibre_link-543\">\n<h2 data-number=\"10.8\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned how to:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Read from and write to text files.<\/li>\n<li class=\"calibre3\">Read from and write to XML files.<\/li>\n<li class=\"calibre3\">Compress and decompress files.<\/li>\n<li class=\"calibre3\">Encode and decode text.<\/li>\n<li class=\"calibre3\">Serialize an object graph into JSON and XML.<\/li>\n<li class=\"calibre3\">Deserialize an object graph from JSON and XML.<\/li>\n<li class=\"calibre3\">Work with environment variables.<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will learn how to work with databases using Entity Framework Core.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-934\">\n<div id=\"calibre_link-1936\" class=\"calibre1\">\n<section data-number=\"11\" id=\"calibre_link-544\">\n<h1 data-number=\"11\" class=\"title\">10 Working with Data Using Entity Framework Core<\/h1>\n<section data-number=\"11.1\" id=\"calibre_link-545\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"11.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000088.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about reading from and writing to relational data stores, such as SQLite and SQL Server, by using the object-to-data store mapping technology named <strong class=\"calibre2\">Entity Framework Core<\/strong> (<strong class=\"calibre2\">EF Core<\/strong>).This chapter will cover the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Understanding modern databases<\/li>\n<li class=\"calibre3\">Setting up EF Core in a .NET project<\/li>\n<li class=\"calibre3\">Defining EF Core models<\/li>\n<li class=\"calibre3\">Querying EF Core models<\/li>\n<li class=\"calibre3\">Loading and tracking patterns with EF Core<\/li>\n<li class=\"calibre3\">Modifying data with EF Core<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"11.2\" id=\"calibre_link-546\">\n<h2 data-number=\"11.2\" class=\"calibre5\">Understanding modern databases<\/h2>\n<p class=\"rights\">Two of the most common places to store data are in a <strong class=\"calibre2\">Relational Database Management System<\/strong> (<strong class=\"calibre2\">RDBMS<\/strong>), such as SQL Server, PostgreSQL, MySQL, and SQLite, or in a <strong class=\"calibre2\">NoSQL<\/strong> database such as Azure Cosmos DB, Redis, MongoDB, and Apache Cassandra.Relational databases were invented in the 1970s. They are queried with <strong class=\"calibre2\">Structured Query Language<\/strong> (<strong class=\"calibre2\">SQL<\/strong>). At the time, data storage costs were high, so they reduced data duplication as much as possible. Data is stored in tabular structures with rows and columns that are tricky to refactor once in production. They can be difficult and expensive to scale.NoSQL databases do not just mean \u201cno SQL\u201d; they can also mean \u201cnot only SQL.\u201d They were invented in the 2000s, after the Internet and the web had become popular, and adopted many of the learnings from that era of software. They are designed for massive scalability and high performance and to make programming easier by providing maximum flexibility and allowing schema changes at any time because they do not enforce a structure.If you know nothing about relational databases, then you should read the database primer that I wrote at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch10-database-primer.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch10-database-primer.md<\/a><\/p>\n<section data-number=\"11.2.1\" id=\"calibre_link-547\">\n<h3 data-number=\"11.2.1\" class=\"calibre8\">Understanding legacy Entity Framework<\/h3>\n<p class=\"rights\"><strong class=\"calibre2\">Entity Framework<\/strong> (<strong class=\"calibre2\">EF<\/strong>) was first released as part of .NET Framework 3.5 with Service Pack 1 back in late 2008. Since then, Entity Framework has evolved, as Microsoft has observed how programmers use an <strong class=\"calibre2\">object-relational mapping<\/strong> (<strong class=\"calibre2\">ORM<\/strong>) tool in the real world.ORMs use a mapping definition to associate columns in tables to properties in classes. Then, a programmer can interact with objects of different types in a way that they are familiar with, instead of having to deal with knowing how to store the values in a relational table or another structure provided by a NoSQL data store.The version of EF included with .NET Framework is <strong class=\"calibre2\">Entity Framework 6<\/strong> (<strong class=\"calibre2\">EF6<\/strong>). It is mature and stable and supports an EDMX (XML file) way of defining the model, as well as complex inheritance models and a few other advanced features.EF 6.3 and later have been extracted from .NET Framework as a separate package, so they can be supported on .NET Core 3 and later. This enables existing projects like web applications and services to be ported and run cross-platform. However, EF6 should be considered a legacy technology because it has some limitations when running cross-platform and no new features will be added to it.<\/p>\n<\/section>\n<section data-number=\"11.2.2\" id=\"calibre_link-548\">\n<h3 data-number=\"11.2.2\" class=\"calibre8\">Using the legacy Entity Framework 6.3 or later<\/h3>\n<p class=\"rights\">To use the legacy Entity Framework in a .NET Core 3 or later project, you must add a package reference to it in your project file, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PackageReference Include=\"EntityFramework\" Version=\"6.4.4\" \/&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Only use legacy EF6 if you must; for example, to migrate a WPF app that uses EF6 on .NET Framework to modern .NET. This book is about modern cross-platform development, so in the rest of this chapter, I will only cover the modern EF Core. You will not need to reference the legacy EF6 package as shown above in the projects for this chapter.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"11.2.3\" id=\"calibre_link-549\">\n<h3 data-number=\"11.2.3\" class=\"calibre8\">Understanding Entity Framework Core<\/h3>\n<p class=\"rights\">The truly cross-platform version, <strong class=\"calibre2\">EF Core<\/strong>, is different from the legacy Entity Framework. Although EF Core has a similar name, you should be aware of how it varies from EF6. The latest EF Core is version 8, to match .NET 8.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">EF Core 8 targets .NET 8 or later. EF Core 9 will also target .NET 8 or later because the EF Core team wants as many developers as possible to benefit from new features in future releases even if you must target only long-term support releases of .NET. This means that you can use all the new features of EF Core 9 with either .NET 8 or .NET 9. But when EF Core 10 is released in November 2025, your projects will need to target .NET 10 to use it.<\/p>\n<\/blockquote>\n<p class=\"rights\">EF Core 3 and later only work with platforms that support .NET Standard 2.1, meaning .NET Core 3 and later. EF Core 3 and later do not support .NET Standard 2.0 platforms like .NET Framework 4.8.As well as traditional RDBMSs, EF Core supports modern cloud-based, nonrelational, schema-less data stores, such as Azure Cosmos DB and MongoDB, sometimes with third-party providers.EF Core has so many improvements in each release that this chapter cannot cover them all. In this chapter, I will focus on the fundamentals that all .NET developers should know and some of the most useful new features. You can learn more about EF Core and how to use it with SQL Server in my companion book, <em class=\"calibre10\">Apps and Services with .NET 8<\/em>, or by reading the official documentation, found at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/ef\/core\/\">https:\/\/learn.microsoft.com\/en-us\/ef\/core\/<\/a>.You can keep up with the latest EF Core news at the following link: <a href=\"https:\/\/aka.ms\/efnews\">https:\/\/aka.ms\/efnews<\/a>.<\/p>\n<\/section>\n<section data-number=\"11.2.4\" id=\"calibre_link-550\">\n<h3 data-number=\"11.2.4\" class=\"calibre8\">Understanding Database First and Code First<\/h3>\n<p class=\"rights\">There are two approaches to working with EF Core:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Database First<\/strong>: A database already exists, so you build a model that matches its structure and features. This is the most common scenario in real life. You will see an example of this throughout this chapter.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Code First<\/strong>: No database exists, so you build a model and then use EF Core to create a database that matches its structure and features. You will see an example of this if you complete the online-only section linked to in one of the exercises at the end of this chapter.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"11.2.5\" id=\"calibre_link-551\">\n<h3 data-number=\"11.2.5\" class=\"calibre8\">Performance improvements in EF Core<\/h3>\n<p class=\"rights\">The EF Core team continues to work hard on improving the performance of EF Core. For example, if EF Core identifies that only a single statement will be executed against the database when <code class=\"calibre9\">SaveChanges<\/code> is called, then it does not create an explicit transaction as earlier versions do. That gives a 25% performance improvement to a common scenario.There is too much detail about all the recent performance improvements to cover in this chapter, and you get all the benefits without needing to know how they work anyway. If you are interested (and it is fascinating what they looked at and how they took advantage of some cool SQL Server features in particular), then I recommend that you read the following posts from the EF Core team:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Announcing Entity Framework Core 7 Preview 6: Performance Edition: <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-ef-core-7-preview6-performance-optimizations\/\">https:\/\/devblogs.microsoft.com\/dotnet\/announcing-ef-core-7-preview6-performance-optimizations\/<\/a><\/li>\n<li class=\"calibre3\">Announcing Entity Framework Core 6.0 Preview 4: Performance Edition: <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-entity-framework-core-6-0-preview-4-performance-edition\/\">https:\/\/devblogs.microsoft.com\/dotnet\/announcing-entity-framework-core-6-0-preview-4-performance-edition\/<\/a><\/li>\n<\/ul>\n<\/section>\n<section data-number=\"11.2.6\" id=\"calibre_link-552\">\n<h3 data-number=\"11.2.6\" class=\"calibre8\">Using a sample relational database<\/h3>\n<p class=\"rights\">To learn how to manage an RDBMS using .NET, it would be useful to have a sample one so that you can practice on one that has a medium complexity and a decent number of sample records. Microsoft offers several sample databases, most of which are too complex for our needs, so instead, we will use a database that was first created in the early 1990s known as <strong class=\"calibre2\">Northwind<\/strong>.Let's take a minute to look at a diagram of the Northwind database. You can use the diagram in <em class=\"calibre10\">Figure 10.1<\/em> to refer to as we write code and queries throughout this book:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 10.1: The Northwind database tables and relationships\" height=\"657\" src=\"\/images\/cs12\/000007.png\" width=\"927\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 10.1: The Northwind database tables and relationships<\/figcaption><\/figure>\n<p class=\"rights\">You will write code to work with the <code class=\"calibre9\">Categories<\/code> and <code class=\"calibre9\">Products<\/code> tables later in this chapter, and other tables in later chapters. But before we do, note that:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Each category has a unique identifier, name, description, and picture.<\/li>\n<li class=\"calibre3\">Each product has a unique identifier, name, unit price, units in stock, and other fields.<\/li>\n<li class=\"calibre3\">Each product is associated with a category by storing the category's unique identifier.<\/li>\n<li class=\"calibre3\">The relationship between <code class=\"calibre9\">Categories<\/code> and <code class=\"calibre9\">Products<\/code> is one-to-many, meaning each category can have zero or more products. This is indicated in <em class=\"calibre10\">Figure 10.1<\/em> by an infinity symbol at one end (meaning many) and a yellow key at the other end (meaning one).<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"11.2.7\" id=\"calibre_link-553\">\n<h3 data-number=\"11.2.7\" class=\"calibre8\">Using SQLite<\/h3>\n<p class=\"rights\">SQLite is a small, fast, cross-platform, self-contained RDBMS that is available in the public domain. It's the most common RDBMS for mobile platforms such as iOS (iPhone and iPad) and Android. SQLite is the most used database engine in the world and there are more than one trillion SQLite databases in active use. You can read more about this at the following link: <a href=\"https:\/\/www.sqlite.org\/mostdeployed.xhtml\">https:\/\/www.sqlite.org\/mostdeployed.xhtml<\/a>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">I decided to demonstrate databases using SQLite in this book, since important themes are cross-platform development and fundamental skills that only need basic database capabilities. I recommend that you initially complete the book code tasks using SQLite. If you also want to try the code tasks using SQL Server, then I provide documentation to do so in the online-only sections in the GitHub repository for this book.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"11.2.8\" id=\"calibre_link-554\">\n<h3 data-number=\"11.2.8\" class=\"calibre8\">Using SQL Server or other SQL systems<\/h3>\n<p class=\"rights\">Enterprises that standardize on Windows tend to also use SQL Server as their database. If you would prefer to use SQL Server, please see the online instructions at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/sql-server\/README.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/sql-server\/README.md<\/a>If you would prefer to use a different SQL system, then the SQL scripts that I provide should work with most SQL systems, for example, PostgreSQL or MySQL, but I have not written step-by-step instructions for them and I make no guarantees it will work.My recommendation is to complete this book using SQLite, so you focus on learning what's taught in the book about EF Core rather than adding the complication of trying to use a different database system. Learning is hard enough; don't bite off more than you can chew; don't make it harder on yourself. Once you've learned what's in the book, you can always repeat it with a different database system.<\/p>\n<\/section>\n<section data-number=\"11.2.9\" id=\"calibre_link-555\">\n<h3 data-number=\"11.2.9\" class=\"calibre8\">Setting up SQLite for Windows<\/h3>\n<p class=\"rights\">On Windows, we need to add the folder for SQLite to the system path so it will be found when we enter commands at a command prompt or terminal:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start your favorite browser and navigate to the following link: <a href=\"https:\/\/www.sqlite.org\/download.xhtml\">https:\/\/www.sqlite.org\/download.xhtml<\/a>.<\/li>\n<li class=\"calibre3\">Scroll down the page to the <strong class=\"calibre2\">Precompiled Binaries for Windows<\/strong> section.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Click <strong class=\"calibre2\">sqlite-tools-win32-x86-3420000.zip<\/strong> (or the file might have a higher version number), as shown in the following screenshot:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 10.2: Downloading SQLite for Windows\" height=\"427\" src=\"\/images\/cs12\/000020.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 10.2: Downloading SQLite for Windows<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Extract the ZIP file into a folder named <code class=\"calibre9\">C:\\Sqlite\\<\/code>. Make sure that the three extracted files including <code class=\"calibre9\">sqlite3.exe<\/code> are directly inside the <code class=\"calibre9\">C:\\SQLite<\/code> folder or the executable will not be found later when you try to use it.<\/li>\n<li class=\"calibre3\">In the Windows <strong class=\"calibre2\">Start<\/strong> menu, navigate to <strong class=\"calibre2\">Settings<\/strong>.<\/li>\n<li class=\"calibre3\">Search for <code class=\"calibre9\">environment<\/code> and choose <strong class=\"calibre2\">Edit the system environment variables<\/strong>. On non-English versions of Windows, please search for the equivalent word in your local language to find the setting.<\/li>\n<li class=\"calibre3\">Click the <strong class=\"calibre2\">Environment Variables<\/strong> button.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">System variables<\/strong>, select <strong class=\"calibre2\">Path<\/strong> in the list, and then click <strong class=\"calibre2\">Edit\u2026<\/strong>.<\/li>\n<li class=\"calibre3\">If <code class=\"calibre9\">C:\\SQLite<\/code> is not already in the path, then click <strong class=\"calibre2\">New<\/strong>, enter <code class=\"calibre9\">C:\\Sqlite<\/code>, and press <span>Enter<\/span>.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">OK<\/strong>, then <strong class=\"calibre2\">OK<\/strong>, then <strong class=\"calibre2\">OK<\/strong> again, and then close <strong class=\"calibre2\">Settings<\/strong>.<\/li>\n<li class=\"calibre3\">To confirm that the path to SQLite has been configured correctly, at any command prompt or terminal, enter a command to start SQLite, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">sqlite3<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SQLite version 3.42.0 2023-05-16 12:36:15\nEnter \".help\" for usage hints.\nConnected to a transient in-memory database.\nUse \".open FILENAME\" to reopen on a persistent database.\nsqlite&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">To exit the SQLite command prompt:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">On Windows, press <span>Ctrl<\/span> + <span>C<\/span> twice.<\/li>\n<li class=\"calibre3\">On macOS, press <span>Ctrl<\/span> + <span>D<\/span>.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"11.2.10\" id=\"calibre_link-556\">\n<h3 data-number=\"11.2.10\" class=\"calibre8\">Setting up SQLite for macOS and Linux<\/h3>\n<p class=\"rights\">On macOS, SQLite is included in the <code class=\"calibre9\">\/usr\/bin\/<\/code> directory as a command-line application named <code class=\"calibre9\">sqlite3<\/code>.On Linux, you can get set up with SQLite using the following command:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">sudo apt-get install sqlite3<\/code><\/pre>\n<\/div>\n<p class=\"rights\">SQLite can be downloaded and installed for other OSs from the following link: <a href=\"https:\/\/www.sqlite.org\/download.xhtml\">https:\/\/www.sqlite.org\/download.xhtml<\/a>.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"11.3\" id=\"calibre_link-557\">\n<h2 data-number=\"11.3\" class=\"calibre5\">Setting up EF Core in a .NET project<\/h2>\n<p class=\"rights\">Now that we have a database system set up, we can create a database and .NET project that use it.<\/p>\n<section data-number=\"11.3.1\" id=\"calibre_link-558\">\n<h3 data-number=\"11.3.1\" class=\"calibre8\">Creating a console app for working with EF Core<\/h3>\n<p class=\"rights\">First, we will create a console app project for this chapter:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to create a new project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">WorkingWithEFCore<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter10<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"11.3.2\" id=\"calibre_link-559\">\n<h3 data-number=\"11.3.2\" class=\"calibre8\">Creating the Northwind sample database for SQLite<\/h3>\n<p class=\"rights\">Now we can create the Northwind sample database for SQLite using an SQL script:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you have not previously cloned or downloaded the ZIP for the GitHub repository for this book, then do so now using the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\">https:\/\/github.com\/markjprice\/cs12dotnet8<\/a>.<\/li>\n<li class=\"calibre3\">Copy the script to create the Northwind database for SQLite from the following path in your local Git repository or where you extracted the ZIP: <code class=\"calibre9\">\/scripts\/sql-scripts\/Northwind4SQLite.sql<\/code> into the <code class=\"calibre9\">WorkingWithEFCore<\/code> folder.<\/li>\n<li class=\"calibre3\">Start a command prompt or terminal in the <code class=\"calibre9\">WorkingWithEFCore<\/code> project folder:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">On Windows, start <strong class=\"calibre2\">File Explorer<\/strong>, right-click the <code class=\"calibre9\">WorkingWithEFCore<\/code> folder, and select <strong class=\"calibre2\">New Command Prompt at Folder<\/strong> or <strong class=\"calibre2\">Open in Windows Terminal<\/strong>.<\/li>\n<li class=\"calibre3\">On macOS, start <strong class=\"calibre2\">Finder<\/strong>, right-click the <code class=\"calibre9\">WorkingWithEFCore<\/code> folder, and select <strong class=\"calibre2\">New Terminal at Folder<\/strong>.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Enter the command to execute the SQL script using SQLite to create the <code class=\"calibre9\">Northwind.db<\/code> database, as shown here:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">sqlite3 Northwind.db -init Northwind4SQLite.sql<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Be patient because this command might take a while to create the database structure. Eventually, you will see the SQLite command prompt, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">-- Loading resources from Northwind4SQLite.sql\nSQLite version 3.42.0 2023-05-16 12:36:15\nEnter \".help\" for usage hints.\nsqlite&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">To exit the SQLite command prompt:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">On Windows, press <span>Ctrl<\/span> + <span>C<\/span> twice.<\/li>\n<li class=\"calibre3\">On macOS or Linux, press <span>Ctrl<\/span> + <span>D<\/span>.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">You can leave the command prompt or terminal window open because you will use it again soon.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"11.3.3\" id=\"calibre_link-560\">\n<h3 data-number=\"11.3.3\" class=\"calibre8\">If you are using Visual Studio 2022<\/h3>\n<p class=\"rights\">If you are using Visual Studio Code and the <code class=\"calibre9\">dotnet run<\/code> command, the compiled application executes in the <code class=\"calibre9\">WorkingWithEFCore<\/code> folder, allowing it to locate the database file stored therein. But if you are using Visual Studio 2022, or JetBrains Rider, then the compiled application executes in the <code class=\"calibre9\">WorkingWithEFCore\\bin\\Debug\\net8.0<\/code> folder, so it will not find the database file because it is not in that directory.Let's tell Visual Studio 2022 to copy the database file to the directory that it runs the code in so that it can find the file, but only if the database file is newer or is missing so it will not overwrite any database changes we make during runtime:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, right-click the <code class=\"calibre9\">Northwind.db<\/code> file and select <strong class=\"calibre2\">Properties<\/strong>.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">Properties<\/strong>, set <strong class=\"calibre2\">Copy to Output Directory<\/strong> to <strong class=\"calibre2\">Copy if newer<\/strong>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">WorkingWithEFCore.csproj<\/code>, note the new elements, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;None Update=\"Northwind.db\"&gt;\n    &lt;CopyToOutputDirectory&gt;PreserveNewest&lt;\/CopyToOutputDirectory&gt;\n  &lt;\/None&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you prefer to overwrite the data changes every time you start the project, then set <code class=\"calibre9\">CopyToOutputDirectory<\/code> to <code class=\"calibre9\">Always<\/code>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"11.3.4\" id=\"calibre_link-561\">\n<h3 data-number=\"11.3.4\" class=\"calibre8\">Managing the Northwind sample database with SQLiteStudio<\/h3>\n<p class=\"rights\">You can use a cross-platform graphical database manager named <strong class=\"calibre2\">SQLiteStudio<\/strong> to easily manage SQLite databases:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to the following link, <a href=\"https:\/\/sqlitestudio.pl\">https:\/\/sqlitestudio.pl<\/a>, and then download and install the application.<\/li>\n<li class=\"calibre3\">Start <strong class=\"calibre2\">SQLiteStudio<\/strong>.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Database<\/strong> | <strong class=\"calibre2\">Add a database<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <strong class=\"calibre2\">Database<\/strong> dialog, in the <strong class=\"calibre2\">File<\/strong> section, click on the yellow folder button to browse for an existing database file on the local computer, select the <code class=\"calibre9\">Northwind.db<\/code> file in the <code class=\"calibre9\">WorkingWithEFCore<\/code> project folder, and then click <strong class=\"calibre2\">OK<\/strong>, as shown in <em class=\"calibre10\">Figure 10.3<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 10.3: Adding the Northwind.db database file to SQLiteStudio\" height=\"465\" src=\"\/images\/cs12\/000039.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 10.3: Adding the Northwind.db database file to SQLiteStudio<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">If you cannot see the database, then navigate to <strong class=\"calibre2\">View<\/strong> | <strong class=\"calibre2\">Databases<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Databases<\/strong> window, right-click on the <strong class=\"calibre2\">Northwind<\/strong> database and choose <strong class=\"calibre2\">Connect to the database<\/strong> (or just double-click <strong class=\"calibre2\">Northwind<\/strong>). You will see the 10 tables that were created by the script. (The script for SQLite is simpler than the one for SQL Server; it does not create as many tables or other database objects.)<\/li>\n<li class=\"calibre3\">Right-click on the <strong class=\"calibre2\">Products<\/strong> table and choose <strong class=\"calibre2\">Edit the table<\/strong>, or just double-click the table.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the table editor window, note the structure of the <code class=\"calibre9\">Products<\/code> table, including column names, data types, keys, and constraints, as shown in <em class=\"calibre10\">Figure 10.4<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 10.4: The table editor in SQLiteStudio showing the structure of the Products table\" height=\"894\" src=\"\/images\/cs12\/000133.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 10.4: The table editor in SQLiteStudio showing the structure of the Products table<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the table editor window, click the <strong class=\"calibre2\">Data<\/strong> tab, and you will see 77 products, as shown in <em class=\"calibre10\">Figure 10.5<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 10.5: The Data tab showing the 77 rows in the Products table\" height=\"664\" src=\"\/images\/cs12\/000150.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 10.5: The Data tab showing the 77 rows in the Products table<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Database<\/strong> window, right-click <strong class=\"calibre2\">Northwind<\/strong> and select <strong class=\"calibre2\">Disconnect from the database<\/strong>.<\/li>\n<li class=\"calibre3\">Quit SQLiteStudio.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"11.3.5\" id=\"calibre_link-562\">\n<h3 data-number=\"11.3.5\" class=\"calibre8\">Using the lightweight ADO.NET database providers<\/h3>\n<p class=\"rights\">Before Entity Framework, there was <strong class=\"calibre2\">ADO.NET<\/strong>. Compared to EF, this is a simpler and more efficient API for working with databases. It provides abstract classes like <code class=\"calibre9\">DbConnection<\/code>, <code class=\"calibre9\">DbCommand<\/code>, and <code class=\"calibre9\">DbReader<\/code>, and provider-specific implementations of them like <code class=\"calibre9\">SqlConnection<\/code> and <code class=\"calibre9\">SqlCommand<\/code>. In this chapter, if you choose to use SQL Server then you should use the <code class=\"calibre9\">SqlConnectionStringBuilder<\/code> class to help write a valid connection string. This is because it has properties for all possible parts of a database connection string that you set individually and then it returns the complete string. You should also get sensitive secrets like passwords from an environment variable or a secret management system instead of writing them in your source code.For SQLite, the connection string is so simple you do not need to use the <code class=\"calibre9\">SqliteConnectionStringBuilder<\/code> class.The EF Core database providers for SQLite and SQL Server are built on top of the ADO.NET libraries, so EF Core is always inherently slower than ADO.NET. ADO.NET can be used independently for better performance because the EF Core database providers are \"closer to the metal.\"If you want to use native <strong class=\"calibre2\">ahead-of-time<\/strong> (<strong class=\"calibre2\">AOT<\/strong>) publishing, be aware that EF Core does not yet support it. This means you can only use the ADO.NET libraries if you plan to compile to native code. The EF Core team is investigating how they can support native AOT, but it is challenging so it is unlikely to happen with EF Core 8 this year. Hopefully, it will happen for EF Core 9 in 2024 or EF Core 10 in 2025.Apart from <code class=\"calibre9\">SqlConnectionStringBuilder<\/code>, this book does not cover using the ADO.NET library, but I do cover examples of how to publish native AOT minimal API web services using the ADO.NET for SQL Server library in the companion book, <em class=\"calibre10\">Apps and Services with .NET 8<\/em>. You can learn more about the ADO.NET for SQLite library at the following link:<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/data\/sqlite\/\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/data\/sqlite\/<\/a>You can learn more about the ADO.NET for SQL Server library at the following link:<a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/connect\/ado-net\/microsoft-ado-net-sql-server\">https:\/\/learn.microsoft.com\/en-us\/sql\/connect\/ado-net\/microsoft-ado-net-sql-server<\/a><\/p>\n<\/section>\n<section data-number=\"11.3.6\" id=\"calibre_link-563\">\n<h3 data-number=\"11.3.6\" class=\"calibre8\">Choosing an EF Core database provider<\/h3>\n<p class=\"rights\">Before we dive into the practicalities of managing data using EF Core, let's briefly talk about choosing between EF Core database providers. To manage data in a specific database, we need classes that know how to efficiently talk to that database.EF Core database providers are sets of classes that are optimized for a specific data store. There is even a provider for storing the data in the memory of the current process, which can be useful for high-performance unit testing since it avoids hitting an external system.They are distributed as NuGet packages, as shown in <em class=\"calibre10\">Table 10.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">To manage this data store<\/td>\n<td class=\"calibre21\">Reference this NuGet package<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">SQL Server 2012 or later<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Microsoft.EntityFrameworkCore.SqlServer<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">SQLite 3.7 or later<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Microsoft.EntityFrameworkCore.SQLite<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">In-memory<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Microsoft.EntityFrameworkCore.InMemory<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Azure Cosmos DB SQL API<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Microsoft.EntityFrameworkCore.Cosmos<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">MySQL<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">MySQL.EntityFrameworkCore<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Oracle DB 11.2<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Oracle.EntityFrameworkCore<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">PostgreSQL<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Npgsql.EntityFrameworkCore.PostgreSQL<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 10.1: NuGet packages for common EF Core database providers<\/p>\n<p class=\"rights\">You can reference as many EF Core database providers in the same project as you need. Each package includes the common shared types as well as provider-specific types.<\/p>\n<\/section>\n<section data-number=\"11.3.7\" id=\"calibre_link-564\">\n<h3 data-number=\"11.3.7\" class=\"calibre8\">Connecting to a named SQLite database<\/h3>\n<p class=\"rights\">To connect to an SQLite database, we just need to know the database path and filename, set using the legacy parameter <code class=\"calibre9\">Filename<\/code> or the modern equivalent <code class=\"calibre9\">Data Source<\/code>. The path can be relative to the current directory or an absolute path. We specify this information in a <strong class=\"calibre2\">connection string<\/strong>.<\/p>\n<\/section>\n<section data-number=\"11.3.8\" id=\"calibre_link-565\">\n<h3 data-number=\"11.3.8\" class=\"calibre8\">Defining the Northwind database context class<\/h3>\n<p class=\"rights\">A class named <code class=\"calibre9\">Northwind<\/code> will be used to represent the database. To use EF Core, the class must inherit from <code class=\"calibre9\">DbContext<\/code>. The <code class=\"calibre9\">DbContext<\/code> class understands how to communicate with databases and dynamically generate SQL statements to query and manipulate data.Your <code class=\"calibre9\">DbContext<\/code>-derived class should have an overridden method named <code class=\"calibre9\">OnConfiguring<\/code>, which will set the database connection string.We will create a project that uses SQLite, but feel free to use SQL Server or some other database system if you feel comfortable doing so instead:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithEFCore<\/code> project, add a package reference to the EF Core provider for SQLite and globally and statically import the <code class=\"calibre9\">System.Console<\/code> class for all C# files, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n&lt;\/ItemGroup&gt;\n&lt;ItemGroup&gt;\n  &lt;PackageReference Version=\"8.0.0\"\n    Include=\"Microsoft.EntityFrameworkCore.Sqlite\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Build the <code class=\"calibre9\">WorkingWithEFCore<\/code> project to restore packages.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">After February 2024, you will be able to try out previews of EF Core 9 by specifying version <code class=\"calibre9\">9.0-*<\/code>. The target framework for your project should continue to use <code class=\"calibre9\">net8.0<\/code>. By using a wildcard, you will automatically download the latest monthly preview when you restore the packages for the project. Once the EF Core 9 GA version is released in November 2024, change the package version to <code class=\"calibre9\">9.0.0<\/code>. After February 2025, you will be able to do the same with EF Core 10 but that will likely require a project targeting <code class=\"calibre9\">net10.0<\/code>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">In the project folder, add a new class file named <code class=\"calibre9\">NorthwindDb.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">NorthwindDb.cs<\/code>, import the main namespace for EF Core, define a class named <code class=\"calibre9\">Northwind<\/code>, and make the class inherit from <code class=\"calibre9\">DbContext<\/code>. Then, in an <code class=\"calibre9\">OnConfiguring<\/code> method, configure the options builder to use SQLite with an appropriate database connection string, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.EntityFrameworkCore; \/\/ To use DbContext and so on.\nnamespace Northwind.EntityModels;\n\/\/ This manages interactions with the Northwind database.\npublic class NorthwindDb : DbContext\n{\n  protected override void OnConfiguring(\n    DbContextOptionsBuilder optionsBuilder)\n  {\n    string databaseFile = \"Northwind.db\";\n    string path = Path.Combine(\n      Environment.CurrentDirectory, databaseFile);\n    string connectionString = $\"Data Source={path}\";\n    WriteLine($\"Connection: {connectionString}\");\n    optionsBuilder.UseSqlite(connectionString);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements. Then, import the <code class=\"calibre9\">Northwind.EntityModels<\/code> namespace and output the database provider, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.EntityModels; \/\/ To use Northwind.\nusing NorthwindDb db = new();\nWriteLine($\"Provider: {db.Database.ProviderName}\");\n\/\/ Disposes the database context.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app and note the output showing the database connection string and which database provider you are using, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Connection: Data Source=C:\\cs12dotnet8\\Chapter10\\WorkingWithEFCore\\bin\\Debug\\net8.0\\Northwind.db\nProvider: Microsoft.EntityFrameworkCore.Sqlite<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You now know how to connect to a database by defining an EF Core data context. Next, we need to define a model that represents the tables in the database.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"11.4\" id=\"calibre_link-566\">\n<h2 data-number=\"11.4\" class=\"calibre5\">Defining EF Core models<\/h2>\n<p class=\"rights\">EF Core uses a combination of <strong class=\"calibre2\">conventions<\/strong>, <strong class=\"calibre2\">annotation attributes<\/strong>, and <strong class=\"calibre2\">Fluent API<\/strong> statements to build an <strong class=\"calibre2\">entity model<\/strong> at runtime, which enables any actions performed on the classes to later be automatically translated into actions performed on the actual database. An <strong class=\"calibre2\">entity class<\/strong> represents the structure of a table, and an instance of the class represents a row in that table.First, we will review the three ways to define a model, with code examples, and then we will create some classes that implement those techniques.<\/p>\n<section data-number=\"11.4.1\" id=\"calibre_link-567\">\n<h3 data-number=\"11.4.1\" class=\"calibre8\">Using EF Core conventions to define the model<\/h3>\n<p class=\"rights\">The code we will write will use the following conventions:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The name of a table is assumed to match the name of a <code class=\"calibre9\">DbSet&lt;T&gt;<\/code> property in the <code class=\"calibre9\">DbContext<\/code> class, for example, <code class=\"calibre9\">Products<\/code>.<\/li>\n<li class=\"calibre3\">The names of the columns are assumed to match the names of properties in the entity model class, for example, <code class=\"calibre9\">ProductId<\/code>.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">string<\/code> .NET type is assumed to be a <code class=\"calibre9\">nvarchar<\/code> type in the database.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">int<\/code> .NET type is assumed to be an <code class=\"calibre9\">int<\/code> type in the database.<\/li>\n<li class=\"calibre3\">The primary key is assumed to be a property that is named <code class=\"calibre9\">Id<\/code> or <code class=\"calibre9\">ID<\/code>, or when the entity model class is named <code class=\"calibre9\">Product<\/code>, then the property can be named <code class=\"calibre9\">ProductId<\/code> or <code class=\"calibre9\">ProductID<\/code>. If this property is an integer type or the <code class=\"calibre9\">Guid<\/code> type, then it is also assumed to be an <code class=\"calibre9\">IDENTITY<\/code> column (a column type that automatically assigns a value when inserting).<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: There are many other conventions that you should know, and you can even define your own, but that is beyond the scope of this book. You can read about them at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/ef\/core\/modeling\/\">https:\/\/learn.microsoft.com\/en-us\/ef\/core\/modeling\/<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"11.4.2\" id=\"calibre_link-568\">\n<h3 data-number=\"11.4.2\" class=\"calibre8\">Using EF Core annotation attributes to define the model<\/h3>\n<p class=\"rights\">Conventions often aren't enough to completely map the classes to the database objects. A simple way of making your model smarter is to apply annotation attributes. Some common attributes recognized by EF Core are shown in <em class=\"calibre10\">Table 10.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Attribute<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[Required]<\/code><\/td>\n<td class=\"calibre21\">Ensures the value is not null. In .NET 8, it has a <code class=\"calibre9\">DisallowAllDefaultValues<\/code> parameter to prevent value types having their default value. For example, an <code class=\"calibre9\">int<\/code> cannot be <code class=\"calibre9\">0<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[StringLength(50)]<\/code><\/td>\n<td class=\"calibre21\">Ensures the value is up to 50 characters in length.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[Column(TypeName = \"money\",  Name = \"UnitPrice\")]<\/code><\/td>\n<td class=\"calibre21\">Specifies the column type and column name used in the table.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 10.2: Common EF Core annotation attributes<\/p>\n<p class=\"rights\">Some additional attributes that can be used to validate entities and are recognized by platforms like ASP.NET Core and Blazor for validation are shown in <em class=\"calibre10\">Table 10.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Attribute<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[RegularExpression(expression)]<\/code><\/td>\n<td class=\"calibre21\">Ensures the value matches the specified regular expression.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[EmailAddress]<\/code><\/td>\n<td class=\"calibre21\">Ensures the value contains one <code class=\"calibre9\">@<\/code> symbol, but not as the first or last character. It does not use a regular expression.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[Range(1, 10)]<\/code><\/td>\n<td class=\"calibre21\">Ensures a <code class=\"calibre9\">double<\/code> , <code class=\"calibre9\">int<\/code> , or <code class=\"calibre9\">string<\/code> value within a specified range. New in .NET 8 are parameters <code class=\"calibre9\">MinimumIsExclusive<\/code> and <code class=\"calibre9\">MaximumIsExclusive<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[Length(10, 20)]<\/code><\/td>\n<td class=\"calibre21\">Ensures a string or collection is within a specified length range, for example, minimum 10 characters or items, maximum 20 characters or items.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[Base64String]<\/code><\/td>\n<td class=\"calibre21\">Ensures the value is a well-formed Base64 string.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[AllowedValues]<\/code><\/td>\n<td class=\"calibre21\">Ensures value is one of the items in the params array of objects. For example, \"alpha\", \"beta\", \"gamma\", or 1, 2, 3.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[DeniedValues]<\/code><\/td>\n<td class=\"calibre21\">Ensures value is not one of the items in the params array of objects. For example, \"alpha\", \"beta\", \"gamma\", or 1, 2, 3.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 10.3: Validation annotation attributes<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Why does the <code class=\"calibre9\">EmailAddress<\/code> attribute seem so basic? \u201cThe check is intentionally naive because doing something infallible is very hard. The email really should be validated in some other way, such as through an email confirmation flow where an email is actually sent. The validation attribute is designed only to catch egregiously wrong values such as for a U.I.\u201d You can read the debate at the following link: <a href=\"https:\/\/github.com\/dotnet\/runtime\/issues\/27592\">https:\/\/github.com\/dotnet\/runtime\/issues\/27592<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">For example, in the database, the maximum length of a product name is 40, and the value cannot be null, as shown highlighted in the following <strong class=\"calibre2\">Data Definition Language<\/strong> (<strong class=\"calibre2\">DDL<\/strong>) code from the <code class=\"calibre9\">Northwind4SQLite.sql<\/code> script file, which defines how to create a table named <code class=\"calibre9\">Products<\/code> with its columns, data types, keys, and other constraints:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CREATE TABLE Products (\n    ProductId       INTEGER       PRIMARY KEY,\n    ProductName     NVARCHAR (40) NOT NULL,\n    SupplierId      \"INT\",\n    CategoryId      \"INT\",\n    QuantityPerUnit NVARCHAR (20),\n    UnitPrice       \"MONEY\"       CONSTRAINT DF_Products_UnitPrice DEFAULT (0),\n    UnitsInStock    \"SMALLINT\"    CONSTRAINT DF_Products_UnitsInStock DEFAULT (0),\n    UnitsOnOrder    \"SMALLINT\"    CONSTRAINT DF_Products_UnitsOnOrder DEFAULT (0),\n    ReorderLevel    \"SMALLINT\"    CONSTRAINT DF_Products_ReorderLevel DEFAULT (0),\n    Discontinued    \"BIT\"         NOT NULL\n                                  CONSTRAINT DF_Products_Discontinued DEFAULT (0),\n    CONSTRAINT FK_Products_Categories FOREIGN KEY (\n        CategoryId\n    )\n    REFERENCES Categories (CategoryId),\n    CONSTRAINT FK_Products_Suppliers FOREIGN KEY (\n        SupplierId\n    )\n    REFERENCES Suppliers (SupplierId),\n    CONSTRAINT CK_Products_UnitPrice CHECK (UnitPrice &gt;= 0),\n    CONSTRAINT CK_ReorderLevel CHECK (ReorderLevel &gt;= 0),\n    CONSTRAINT CK_UnitsInStock CHECK (UnitsInStock &gt;= 0),\n    CONSTRAINT CK_UnitsOnOrder CHECK (UnitsOnOrder &gt;= 0) \n);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">In a <code class=\"calibre9\">Product<\/code> class, we could apply attributes to specify this, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[Required]\n[StringLength(40)]\npublic string ProductName { get; set; }<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When there isn't an obvious map between .NET types and database types, an attribute can be used.For example, in the database, the column type of <code class=\"calibre9\">UnitPrice<\/code> for the <code class=\"calibre9\">Products<\/code> table is <code class=\"calibre9\">money<\/code>. .NET does not have a <code class=\"calibre9\">money<\/code> type, so it should use <code class=\"calibre9\">decimal<\/code> instead, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[Column(TypeName = \"money\")]\npublic decimal? UnitPrice { get; set; }<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"11.4.3\" id=\"calibre_link-569\">\n<h3 data-number=\"11.4.3\" class=\"calibre8\">Using the EF Core Fluent API to define the model<\/h3>\n<p class=\"rights\">The last way that the model can be defined is by using the Fluent API. This API can be used instead of attributes, as well as being used in addition to them. For example, to define the <code class=\"calibre9\">ProductName<\/code> property, instead of decorating the property with two attributes, an equivalent Fluent API statement could be written in the <code class=\"calibre9\">OnModelCreating<\/code> method of the database context class, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">modelBuilder.Entity&lt;Product&gt;()\n  .Property(product =&gt; product.ProductName)\n  .IsRequired()\n  .HasMaxLength(40);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This keeps the entity model class simpler.<\/p>\n<\/section>\n<section data-number=\"11.4.4\" id=\"calibre_link-570\">\n<h3 data-number=\"11.4.4\" class=\"calibre8\">Understanding data seeding with the Fluent API<\/h3>\n<p class=\"rights\">Another benefit of the Fluent API is to provide initial data to populate a database. EF Core automatically works out what insert, update, or delete operations must be executed.For example, if we wanted to make sure that a new database has at least one row in the <code class=\"calibre9\">Product<\/code> table, then we would call the <code class=\"calibre9\">HasData<\/code> method, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">modelBuilder.Entity&lt;Product&gt;()\n  .HasData(new Product\n  {\n    ProductId = 1,\n    ProductName = \"Chai\",\n    UnitPrice = 8.99M\n  });<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Calls to <code class=\"calibre9\">HasData<\/code> take effect either during a data migration executed by the command <code class=\"calibre9\">dotnet ef database update<\/code> or when you call the <code class=\"calibre9\">Database.EnsureCreated<\/code> method.Our model will map to an existing database that is already populated with data, so we will not need to use this technique in our code.<\/p>\n<\/section>\n<section data-number=\"11.4.5\" id=\"calibre_link-571\">\n<h3 data-number=\"11.4.5\" class=\"calibre8\">Building EF Core models for the Northwind tables<\/h3>\n<p class=\"rights\">Now that you've learned about ways to define EF Core models, let's build models to represent two of the tables in the <code class=\"calibre9\">Northwind<\/code> database. For reuse, we will do this in a separate class library project.The two entity classes will refer to each other, so to avoid compiler errors, we will create the classes without any members first:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to create a new project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Class Library<\/strong> \/ <code class=\"calibre9\">classlib<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">Northwind.EntityModels<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter10<\/code><\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.EntityModels<\/code> project, delete the file named <code class=\"calibre9\">Class1.cs<\/code> and then add two class files named <code class=\"calibre9\">Category.cs<\/code> and <code class=\"calibre9\">Product.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Category.cs<\/code>, define a class named <code class=\"calibre9\">Category<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Northwind.EntityModels;\npublic class Category\n{\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Product.cs<\/code>, define a class named <code class=\"calibre9\">Product<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Northwind.EntityModels;\npublic class Product\n{\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithEFCore<\/code> project, add a project reference to the <code class=\"calibre9\">Northwind.EntityModels<\/code> project, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;ProjectReference Include=\"..\\Northwind.EntityModels\\\nNorthwind.EntityModels.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The project reference path and filename must all go on one line.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">WorkingWithEFCore<\/code> project.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"11.4.6\" id=\"calibre_link-572\">\n<h3 data-number=\"11.4.6\" class=\"calibre8\">Defining the Category and Product entity classes<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">Category<\/code> class, also known as an entity model, will be used to represent a row in the <code class=\"calibre9\">Categories<\/code> table. This table has four columns, as shown in the following DDL taken from the <code class=\"calibre9\">Northwind4SQLite.sql<\/code> script file:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CREATE TABLE Categories (\n  CategoryId   INTEGER       PRIMARY KEY,\n  CategoryName NVARCHAR (15) NOT NULL,\n  Description  \"NTEXT\",\n  Picture      \"IMAGE\"\n);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">We will use conventions to define:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Three of the four properties (we will not map the <code class=\"calibre9\">Picture<\/code> column).<\/li>\n<li class=\"calibre3\">The primary key.<\/li>\n<li class=\"calibre3\">The one-to-many relationship to the <code class=\"calibre9\">Products<\/code> table.<\/li>\n<\/ul>\n<p class=\"rights\">To map the <code class=\"calibre9\">Description<\/code> column to the correct database type, we will need to decorate the <code class=\"calibre9\">string<\/code> property with the <code class=\"calibre9\">Column<\/code> attribute.Later in this chapter, we will use the Fluent API to define that <code class=\"calibre9\">CategoryName<\/code> cannot be null and is limited to a maximum of 15 characters.Let's go:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.EntityModels<\/code> project, modify the <code class=\"calibre9\">Category<\/code> entity model class, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.ComponentModel.DataAnnotations.Schema; \/\/ To use [Column].\nnamespace Northwind.EntityModels;\npublic class Category\n{\n  \/\/ These properties map to columns in the database.\n  public int CategoryId { get; set; } \/\/ The primary key.\n  public string CategoryName { get; set; } = null!;\n  [Column(TypeName = \"ntext\")]\n  public string? Description { get; set; }\n  \/\/ Defines a navigation property for related rows.\n  public virtual ICollection&lt;Product&gt; Products { get; set; }\n    \/\/ To enable developers to add products to a Category, we must\n    \/\/ initialize the navigation property to an empty collection.\n    \/\/ This also avoids an exception if we get a member like Count.\n    = new HashSet&lt;Product&gt;();\n}<\/code><\/pre>\n<\/div>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Note the following:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">The <code class=\"calibre9\">Category<\/code> class will be in the <code class=\"calibre9\">Northwind.EntityModels<\/code> namespace.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">CategoryId<\/code> property follows the primary key naming convention, so it will be mapped to a column marked as the primary key with an index.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">CategoryName<\/code> property maps to a column that does not allow database <code class=\"calibre9\">NULL<\/code> values so it is a non-nullable string, and to disable nullability warnings we have assigned the null-forgiving operator.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">CategoryName<\/code> property maps to a column with the <code class=\"calibre9\">ntext<\/code> data type instead of the default mapping for string values to <code class=\"calibre9\">nvarchar<\/code>.<\/li>\n<li class=\"calibre3\">We initialize the collection of <code class=\"calibre9\">Product<\/code> objects to a new, empty <code class=\"calibre9\">HashSet<\/code>. A hash set is more efficient than a list because it is unordered. If you do not initialize <code class=\"calibre9\">Products<\/code>, then it will be <code class=\"calibre9\">null<\/code> and if you try to get its <code class=\"calibre9\">Count<\/code> then you will get an exception.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the <code class=\"calibre9\">Product<\/code> class, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.ComponentModel.DataAnnotations; \/\/ To use [Required].\nusing System.ComponentModel.DataAnnotations.Schema; \/\/ To use [Column].\nnamespace Northwind.EntityModels;\npublic class Product\n{\n  public int ProductId { get; set; } \/\/ The primary key.\n  [Required]\n  [StringLength(40)]\n  public string ProductName { get; set; } = null!;\n  \/\/ Property name is different from the column name.\n  [Column(\"UnitPrice\", TypeName = \"money\")]\n  public decimal? Cost { get; set; }\n  [Column(\"UnitsInStock\")]\n  public short? Stock { get; set; }\n  public bool Discontinued { get; set; }\n  \/\/ These two properties define the foreign key relationship\n  \/\/ to the Categories table.\n  public int CategoryId { get; set; }\n  public virtual Category Category { get; set; } = null!;\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The <code class=\"calibre9\">Product<\/code> class will be used to represent a row in the <code class=\"calibre9\">Products<\/code> table, which has ten columns.<\/li>\n<li class=\"calibre3\">You do not need to include all columns from a table as properties of a class. We will only map six properties: <code class=\"calibre9\">ProductId<\/code>, <code class=\"calibre9\">ProductName<\/code>, <code class=\"calibre9\">UnitPrice<\/code>, <code class=\"calibre9\">UnitsInStock<\/code>, <code class=\"calibre9\">Discontinued<\/code>, and <code class=\"calibre9\">CategoryId<\/code>.<\/li>\n<li class=\"calibre3\">Columns that are not mapped to properties cannot be read or set using the class instances. If you use the class to create a new object, then the new row in the table will have <code class=\"calibre9\">NULL<\/code> or some other default value for the unmapped column values in that row. You must make sure that those missing columns are optional or have default values set by the database or an exception will be thrown at runtime. In this scenario, the rows already have data values and I have decided that I do not need to read those values in this application.<\/li>\n<li class=\"calibre3\">We can rename a column by defining a property with a different name, like <code class=\"calibre9\">Cost<\/code>, and then decorating the property with the <code class=\"calibre9\">[Column]<\/code> attribute and specifying its column name, like <code class=\"calibre9\">UnitPrice<\/code>.<\/li>\n<li class=\"calibre3\">The final property, <code class=\"calibre9\">CategoryId<\/code>, is associated with a <code class=\"calibre9\">Category<\/code> property that will be used to map each product to its parent category.<\/li>\n<\/ul>\n<p class=\"rights\">The two properties that relate the two entities, <code class=\"calibre9\">Category.Products<\/code> and <code class=\"calibre9\">Product.Category<\/code>, are both marked as <code class=\"calibre9\">virtual<\/code>. This allows EF Core to inherit and override the properties to provide extra features, such as lazy loading.<\/p>\n<\/section>\n<section data-number=\"11.4.7\" id=\"calibre_link-573\">\n<h3 data-number=\"11.4.7\" class=\"calibre8\">Adding tables to the Northwind database context class<\/h3>\n<p class=\"rights\">Inside your <code class=\"calibre9\">DbContext<\/code>-derived class, you must define at least one property of the <code class=\"calibre9\">DbSet&lt;T&gt;<\/code> type. These properties represent the tables. To tell EF Core what columns each table has, the <code class=\"calibre9\">DbSet&lt;T&gt;<\/code> properties use generics to specify a class that represents a row in the table. That entity model class has properties that represent its columns.The <code class=\"calibre9\">DbContext<\/code>-derived class can optionally have an overridden method named <code class=\"calibre9\">OnModelCreating<\/code>. This is where you can write Fluent API statements as an alternative to decorating your entity classes with attributes.Let's write the code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithEFCore<\/code> project, modify the <code class=\"calibre9\">NorthwindDb<\/code> class to add statements to define two properties for the two tables and an <code class=\"calibre9\">OnModelCreating<\/code> method, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class NorthwindDb : DbContext\n{\n  \/\/ These two properties map to tables in the database.\n  public DbSet&lt;Category&gt;? Categories { get; set; }\n  public DbSet&lt;Product&gt;? Products { get; set; }\n  protected override void OnConfiguring(\n    DbContextOptionsBuilder optionsBuilder)\n  {\n    ...\n  }\n  protected override void OnModelCreating(\n    ModelBuilder modelBuilder)\n  {\n    \/\/ Example of using Fluent API instead of attributes\n    \/\/ to limit the length of a category name to 15.\n    modelBuilder.Entity&lt;Category&gt;()\n      .Property(category =&gt; category.CategoryName)\n      .IsRequired() \/\/ NOT NULL\n      .HasMaxLength(15);\n    \/\/ Some SQLite-specific configuration.\n    if (Database.ProviderName?.Contains(\"Sqlite\") ?? false)\n    {\n      \/\/ To \"fix\" the lack of decimal support in SQLite.\n      modelBuilder.Entity&lt;Product&gt;()\n        .Property(product =&gt; product.Cost)\n        .HasConversion&lt;double&gt;();\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">decimal<\/code> type is not supported by the SQLite database provider for sorting and other operations. We can fix this by telling the model that <code class=\"calibre9\">decimal<\/code> values can be treated as <code class=\"calibre9\">double<\/code> values when using the SQLite database provider. This does not actually perform any conversion at runtime.Now that you have seen some examples of defining an entity model manually, let's see a tool that can do some of the work for you.<\/p>\n<\/section>\n<section data-number=\"11.4.8\" id=\"calibre_link-574\">\n<h3 data-number=\"11.4.8\" class=\"calibre8\">Setting up the dotnet-ef tool<\/h3>\n<p class=\"rights\">The .NET CLI tool named <code class=\"calibre9\">dotnet<\/code> can be extended with capabilities useful for working with EF Core. It can perform design-time tasks like creating and applying migrations from an older model to a newer model and generating code for a model from an existing database.The <code class=\"calibre9\">dotnet<\/code> <code class=\"calibre9\">ef<\/code> command-line tool is not automatically installed. You must install this package as either a <strong class=\"calibre2\">global<\/strong> or <strong class=\"calibre2\">local tool<\/strong>. If you have already installed an older version of the tool, then you should update it to the latest version:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At a command prompt or terminal, check if you have already installed <code class=\"calibre9\">dotnet-ef<\/code> as a global tool, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet tool list --global<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Check in the list if an older version of the tool has been installed, like the one for .NET 7, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Package Id      Version     Commands\n-------------------------------------\ndotnet-ef       7.0.0       dotnet-ef<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">If an old version is already installed, then update the tool, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet tool update --global dotnet-ef<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">If it is not already installed, then install the latest version, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet tool install --global dotnet-ef<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If necessary, follow any OS-specific instructions to add the <code class=\"calibre9\">dotnet tools<\/code> directory to your <code class=\"calibre9\">PATH<\/code> environment variable, as described in the output of installing the <code class=\"calibre9\">dotnet-ef<\/code> tool.By default, the latest GA release of .NET will be used to install the tool. To explicitly set a version, for example, to use a preview, add the <code class=\"calibre9\">--version<\/code> switch. For example, to update to the latest .NET 9 preview version available from February 2024 to October 2024, use the following command with a version wildcard:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet tool update --global dotnet-ef --version 9.0-*<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Once the .NET 9 GA release happens in November 2024, you can just use the command without the <code class=\"calibre9\">--version<\/code> switch to upgrade.You can also remove the tool, as shown in the following command:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet tool uninstall --global dotnet-ef<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"11.4.9\" id=\"calibre_link-575\">\n<h3 data-number=\"11.4.9\" class=\"calibre8\">Scaffolding models using an existing database<\/h3>\n<p class=\"rights\">Scaffolding is the process of using a tool to create classes that represent the model of an existing database using reverse engineering. A good scaffolding tool allows you to extend the automatically generated classes because they are <code class=\"calibre9\">partial<\/code> and then regenerate those classes without losing your <code class=\"calibre9\">partial<\/code> classes.If you know that you will never regenerate the classes using the tool, then feel free to change the code for the automatically generated classes as much as you want. The code generated by the tool is just the best approximation.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Do not be afraid to overrule a tool when you know better.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's see if the tool generates the same model as we did manually:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add the latest version of the <code class=\"calibre9\">Microsoft.EntityFrameworkCore.Design<\/code> package to the <code class=\"calibre9\">WorkingWithEFCore<\/code> project, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;PackageReference Version=\"8.0.0\"\n                    Include=\"Microsoft.EntityFrameworkCore.Design\"&gt;\n    &lt;PrivateAssets&gt;all&lt;\/PrivateAssets&gt;\n    &lt;IncludeAssets&gt;runtime; build; native; contentfiles; analyzers; buildtransitive&lt;\/IncludeAssets&gt;\n  &lt;\/PackageReference&gt;\n  &lt;PackageReference Version=\"8.0.0\" \n                    Include=\"Microsoft.EntityFrameworkCore.Sqlite\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: If you are unfamiliar with how packages like <code class=\"calibre9\">Microsoft.EntityFrameworkCore.Design<\/code> can manage their assets, then you can learn more at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/nuget\/consume-packages\/package-references-in-project-files#controlling-dependency-assets\">https:\/\/learn.microsoft.com\/en-us\/nuget\/consume-packages\/package-references-in-project-files#controlling-dependency-assets<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">WorkingWithEFCore<\/code> project to restore packages.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Start a command prompt or terminal in the <code class=\"calibre9\">WorkingWithEFCore<\/code> project folder. For example:<\/p>\n<ul class=\"calibre16\">\n<li class=\"calibre3\">If you are using Visual Studio 2022, in <strong class=\"calibre2\">Solution Explorer<\/strong>, right-click the <code class=\"calibre9\">WorkingWithEFCore<\/code> project and select <strong class=\"calibre2\">Open in Terminal<\/strong>.<\/li>\n<li class=\"calibre3\">On Windows, start <strong class=\"calibre2\">File Explorer<\/strong>, right-click the <code class=\"calibre9\">WorkingWithEFCore<\/code> folder, and select <strong class=\"calibre2\">New Command Prompt at Folder<\/strong> or <strong class=\"calibre2\">Open in Windows Terminal<\/strong>.<\/li>\n<li class=\"calibre3\">On macOS, start <strong class=\"calibre2\">Finder<\/strong>, right-click the <code class=\"calibre9\">WorkingWithEFCore<\/code> folder, and select <strong class=\"calibre2\">New Terminal at Folder<\/strong>.<\/li>\n<li class=\"calibre3\">If you are using JetBrains Rider, in <strong class=\"calibre2\">Solution Explorer<\/strong>, right-click the <code class=\"calibre9\">WorkingWithEFCore<\/code> project and select <strong class=\"calibre2\">Open In<\/strong> | <strong class=\"calibre2\">Terminal<\/strong>.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> When I say the <code class=\"calibre9\">WorkingWithEFCore<\/code> project folder, I mean the folder that contains the <code class=\"calibre9\">WorkingWithEFCore.csproj<\/code> project file. If you enter the command in a folder that does not contain a project file, then you will see the following error: <code class=\"calibre9\">No project was found. Change the current working directory or use the --project option.<\/code><\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You are about to enter a long command. I recommend that you type from the print book or copy and paste long commands like this from the eBook into a plain text editor like Notepad. Then make sure that the whole command is properly formatted as a single line with correct spacing. Only then should you copy and paste it into the command prompt or terminal. Copying and pasting directly from the eBook is likely to include newline characters and missing spaces that break the command if you aren't careful. Also remember that all commands are available to copy from at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/command-lines.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/command-lines.md<\/a>.<\/p>\n<\/blockquote>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">At a command prompt or terminal, use the <code class=\"calibre9\">dotnet-ef<\/code> tool to generate a model for the <code class=\"calibre9\">Categories<\/code> and <code class=\"calibre9\">Products<\/code> tables in a new folder named <code class=\"calibre9\">AutoGenModels<\/code>, as shown in the following command and in <em class=\"calibre10\">Figure 10.6<\/em>:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet ef dbcontext scaffold \"Data Source=Northwind.db\" Microsoft.EntityFrameworkCore.Sqlite --table Categories --table Products --output-dir AutoGenModels --namespace WorkingWithEFCore.AutoGen --data-annotations --context NorthwindDb<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The command action: <code class=\"calibre9\">dbcontext scaffold<\/code><\/li>\n<li class=\"calibre3\">The connection string: <code class=\"calibre9\">\"Data Source=Northwind.db\"<\/code><\/li>\n<li class=\"calibre3\">The database provider: <code class=\"calibre9\">Microsoft.EntityFrameworkCore.Sqlite<\/code><\/li>\n<li class=\"calibre3\">The tables to generate models for: <code class=\"calibre9\">--table Categories --table Products<\/code><\/li>\n<li class=\"calibre3\">The output folder: <code class=\"calibre9\">--output-dir AutoGenModels<\/code><\/li>\n<li class=\"calibre3\">The namespace: <code class=\"calibre9\">--namespace WorkingWithEFCore.AutoGen<\/code><\/li>\n<li class=\"calibre3\">To use data annotations as well as the Fluent API: <code class=\"calibre9\">--data-annotations<\/code><\/li>\n<li class=\"calibre3\">To rename the context from <code class=\"calibre9\">[database_name]Context<\/code>: <code class=\"calibre9\">--context NorthwindDb<\/code><\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you prefer to use SQL Server, then the equivalent command is found at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/sql-server\/README.md#scaffolding-models-using-an-existing-database\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/sql-server\/README.md#scaffolding-models-using-an-existing-database<\/a>.<\/p>\n<\/blockquote>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 10.6: Entering a dotnet-ef command in Terminal using Visual Studio 2022\" height=\"785\" src=\"\/images\/cs12\/000167.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 10.6: Entering a dotnet-ef command in Terminal using Visual Studio 2022<\/figcaption><\/figure>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the build messages and warnings, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Build started...\nBuild succeeded.\nTo protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https:\/\/go.microsoft.com\/fwlink\/?linkid=2131148. For more guidance on storing connection strings, see http:\/\/go.microsoft.com\/fwlink\/?LinkId=723263.\nSkipping foreign key with identity '0' on table 'Products' since principal table 'Suppliers' was not found in the model. This usually happens when the principal table was not included in the selection set.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">AutoGenModels<\/code> folder, note the three class files that were automatically generated: <code class=\"calibre9\">Category.cs<\/code>, <code class=\"calibre9\">NorthwindDb.cs<\/code>, and <code class=\"calibre9\">Product.cs<\/code>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">AutoGenModels<\/code> folder, in <code class=\"calibre9\">Category.cs<\/code>, note the differences compared to the one you created manually. I have not included namespace imports to save space, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace WorkingWithEFCore.AutoGen;\n[Index(\"CategoryName\", Name = \"CategoryName\")]\npublic partial class Category\n{\n  [Key]\n  public int CategoryId { get; set; }\n  [Column(TypeName = \"nvarchar (15)\")]\n  public string CategoryName { get; set; } = null!;\n  [Column(TypeName = \"ntext\")]\n  public string? Description { get; set; }\n  [Column(TypeName = \"image\")]\n  public byte[]? Picture { get; set; }\n  [InverseProperty(\"Category\")]\n  public virtual ICollection&lt;Product&gt; Products { get; set; }\n    = new List&lt;Product&gt;();\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">It decorates the entity class with the <code class=\"calibre9\">[Index]<\/code> attribute, which was introduced in EF Core 5. This indicates properties that should have an index when using the Code First approach to generate a database at runtime. Since we are using Database First with an existing database, this is not needed. But if we wanted to recreate a new, empty database from our code, then this information would be needed.<\/li>\n<li class=\"calibre3\">The table name in the database is <code class=\"calibre9\">Categories<\/code> but the <code class=\"calibre9\">dotnet-ef<\/code> tool uses the <strong class=\"calibre2\">Humanizer<\/strong> third-party library to automatically singularize the class name to <code class=\"calibre9\">Category<\/code>, which is a more natural name when creating a single entity that represents a row in the table.<\/li>\n<li class=\"calibre3\">The entity class is declared using the <code class=\"calibre9\">partial<\/code> keyword so that you can create a matching <code class=\"calibre9\">partial<\/code> class for adding additional code. This allows you to rerun the tool and regenerate the entity class without losing that extra code.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">CategoryId<\/code> property is decorated with the <code class=\"calibre9\">[Key]<\/code> attribute to indicate that it is the primary key for this entity. The data type for this property is <code class=\"calibre9\">int<\/code> for SQL Server and <code class=\"calibre9\">long<\/code> for SQLite. We did not do this because we followed the naming primary key convention.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">CategoryName<\/code> property is decorated with the <code class=\"calibre9\">[Column(TypeName = \"nvarchar (15)\")]<\/code> attribute, which is only needed if you want to generate a database from the model.<\/li>\n<li class=\"calibre3\">We chose not to include the <code class=\"calibre9\">Picture<\/code> column as a property because this is a binary object that we will not use in our console app.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">Products<\/code> property uses the <code class=\"calibre9\">[InverseProperty]<\/code> attribute to define the foreign key relationship to the <code class=\"calibre9\">Category<\/code> property on the <code class=\"calibre9\">Product<\/code> entity class, and it initializes the collection to a new empty list.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">AutoGenModels<\/code> folder, in <code class=\"calibre9\">Product.cs<\/code>, note the differences compared to the one you created manually.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">AutoGenModels<\/code> folder, in <code class=\"calibre9\">NorthwindDb.cs<\/code>, note the differences compared to the one you created manually, as shown in the following edited-for-space code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.EntityFrameworkCore;\nnamespace WorkingWithEFCore.AutoGen;\npublic partial class NorthwindDb : DbContext\n{\n  public NorthwindDb()\n  {\n  }\n  public NorthwindDb(DbContextOptions&lt;NorthwindDb&gt; options)\n      : base(options)\n  {\n  }\n  public virtual DbSet&lt;Category&gt; Categories { get; set; }\n  public virtual DbSet&lt;Product&gt; Products { get; set; }\n  protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)\n#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https:\/\/go.microsoft.com\/fwlink\/?linkid=2131148. For more guidance on storing connection strings, see http:\/\/go.microsoft.com\/fwlink\/?LinkId=723263.\n      =&gt; optionsBuilder.UseSqlite(\"Data Source=Northwind.db\");\n  protected override void OnModelCreating(ModelBuilder modelBuilder)\n  {\n    modelBuilder.Entity&lt;Category&gt;(entity =&gt;\n    {\n      entity.Property(e =&gt; e.CategoryId).ValueGeneratedNever();\n    });\n    modelBuilder.Entity&lt;Product&gt;(entity =&gt;\n    {\n      entity.Property(e =&gt; e.ProductId).ValueGeneratedNever();\n      entity.Property(e =&gt; e.Discontinued).HasDefaultValueSql(\"0\");\n      entity.Property(e =&gt; e.ReorderLevel).HasDefaultValueSql(\"0\");\n      entity.Property(e =&gt; e.UnitPrice).HasDefaultValueSql(\"0\");\n      entity.Property(e =&gt; e.UnitsInStock).HasDefaultValueSql(\"0\");\n      entity.Property(e =&gt; e.UnitsOnOrder).HasDefaultValueSql(\"0\");\n    });\n    OnModelCreatingPartial(modelBuilder);\n  }\n  partial void OnModelCreatingPartial(ModelBuilder modelBuilder);\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The <code class=\"calibre9\">NorthwindDb<\/code> data context class is <code class=\"calibre9\">partial<\/code> to allow you to extend it and regenerate it in the future.<\/li>\n<li class=\"calibre3\">It has two constructors: a default parameter-less one and one that allows options to be passed in. This is useful in apps where you want to specify the connection string at runtime.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">OnConfiguring<\/code> method, if options have not been specified in the constructor, then it defaults to using a connection string that looks for the database file in the current folder. It has a compiler warning to remind you that you should not hardcode security information in this connection string.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">OnModelCreating<\/code> method, the Fluent API is used to configure the two entity classes, and then a partial method named <code class=\"calibre9\">OnModelCreatingPartial<\/code> is invoked. This allows you to implement that partial method in your own partial <code class=\"calibre9\">Northwind<\/code> class to add your own Fluent API configuration that will not be lost if you regenerate the model classes.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close the automatically generated class files.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"11.4.10\" id=\"calibre_link-576\">\n<h3 data-number=\"11.4.10\" class=\"calibre8\">Customizing the reverse engineering templates<\/h3>\n<p class=\"rights\">One of the features introduced with EF Core 7 was the ability to customize the code that is automatically generated by the <code class=\"calibre9\">dotnet-ef<\/code> scaffolding tool. This is an advanced technique, so I do not cover it in this book. Usually, it is easier to just modify the code that is generated by default anyway. If you would like to learn how to modify the T4 templates used by the <code class=\"calibre9\">dotnet-ef<\/code> scaffolding tool, then you can find that information at the following link:<a href=\"https:\/\/learn.microsoft.com\/en-us\/ef\/core\/managing-schemas\/scaffolding\/templates\">https:\/\/learn.microsoft.com\/en-us\/ef\/core\/managing-schemas\/scaffolding\/templates<\/a><\/p>\n<\/section>\n<section data-number=\"11.4.11\" id=\"calibre_link-577\">\n<h3 data-number=\"11.4.11\" class=\"calibre8\">Configuring preconvention models<\/h3>\n<p class=\"rights\">Along with support for the <code class=\"calibre9\">DateOnly<\/code> and <code class=\"calibre9\">TimeOnly<\/code> types for use with the SQLite database provider, one of the features introduced with EF Core 6 was configuring preconvention models.As models become more complex, relying on conventions to discover entity types and their properties and successfully map them to tables and columns becomes harder. It would be useful if you could configure the conventions themselves before they are used to analyze and build a model.For example, you might want to define a convention to say that all <code class=\"calibre9\">string<\/code> properties should have a maximum length of 50 characters as a default, or any property types that implement a custom interface should not be mapped, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">protected override void ConfigureConventions(\n  ModelConfigurationBuilder configurationBuilder)\n{\n  configurationBuilder.Properties&lt;string&gt;().HaveMaxLength(50);\n  configurationBuilder.IgnoreAny&lt;IDoNotMap&gt;();\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">In the rest of this chapter, we will use the classes that you manually created.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"11.5\" id=\"calibre_link-578\">\n<h2 data-number=\"11.5\" class=\"calibre5\">Querying EF Core models<\/h2>\n<p class=\"rights\">Now that we have a model that maps to the Northwind database and two of its tables, we can write some simple LINQ queries to fetch data. You will learn much more about writing LINQ queries in <em class=\"calibre10\">Chapter 11<\/em>, <em class=\"calibre10\">Querying and Manipulating Data Using LINQ<\/em>.For now, just write the code and view the results:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithEFCore<\/code> project, add a new class file named <code class=\"calibre9\">Program.Helpers.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Helpers.cs<\/code>, add a partial <code class=\"calibre9\">Program<\/code> class with a <code class=\"calibre9\">SectionTitle<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">partial class Program\n{\n  private static void ConfigureConsole(string culture = \"en-US\",\n    bool useComputerCulture = false)\n  {\n    \/\/ To enable Unicode characters like Euro symbol in the console.\n    OutputEncoding = System.Text.Encoding.UTF8;\n    if (!useComputerCulture)\n    {\n      CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo(culture);\n    }\n    WriteLine($\"CurrentCulture: {CultureInfo.CurrentCulture.DisplayName}\");\n  }\n  private static void WriteLineInColor(string text, ConsoleColor color)\n  {\n    ConsoleColor previousColor = ForegroundColor;\n    ForegroundColor = color;\n    WriteLine(text);\n    ForegroundColor = previousColor;\n  }\n  private static void SectionTitle(string title)\n  {\n    WriteLineInColor($\"*** {title} ***\", ConsoleColor.DarkYellow);\n  }\n  private static void Fail(string message)\n  {\n    WriteLineInColor($\"Fail &gt; {message}\", ConsoleColor.Red);\n  }\n  private static void Info(string message)\n  {\n    WriteLineInColor($\"Info &gt; {message}\", ConsoleColor.Cyan);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Program.Queries.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Queries.cs<\/code>, define a partial <code class=\"calibre9\">Program<\/code> class with a <code class=\"calibre9\">QueryingCategories<\/code> method, and add statements to do these tasks, as shown in the following code:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Create an instance of the <code class=\"calibre9\">Northwind<\/code> class that will manage the database. Database context instances are designed for short lifetimes in a unit of work. They should be disposed of as soon as possible. So, we will wrap our instance in a <code class=\"calibre9\">using<\/code> statement. In <em class=\"calibre10\">Chapter 13<\/em>, <em class=\"calibre10\">Building Websites Using ASP.NET Core Razor Pages<\/em>, you will learn how to get a database context using dependency injection.<\/li>\n<li class=\"calibre3\">Create a query for all categories that includes their related products. <code class=\"calibre9\">Include<\/code> is an extension method that requires you to import the <code class=\"calibre9\">Microsoft.EntityFrameworkCore<\/code> namespace.<\/li>\n<li class=\"calibre3\">Enumerate through the categories, outputting the name and number of products for each one:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.EntityFrameworkCore; \/\/ To use Include method.\nusing Northwind.EntityModels; \/\/ To use Northwind, Category, Product.\npartial class Program\n{\n  private static void QueryingCategories()\n  {\n    using NorthwindDb db = new();\n    SectionTitle(\"Categories and how many products they have\");\n    \/\/ A query to get all categories and their related products.\n    IQueryable&lt;Category&gt;? categories = db.Categories?\n      .Include(c =&gt; c.Products);\n    if (categories is null || !categories.Any())\n    {\n      Fail(\"No categories found.\");\n      return;\n    }\n    \/\/ Execute query and enumerate results.\n    foreach (Category c in categories)\n    {\n      WriteLine($\"{c.CategoryName} has {c.Products.Count} products.\");\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Note that the order of the clauses in the <code class=\"calibre9\">if<\/code> statement is important. We must check that <code class=\"calibre9\">categories<\/code> is <code class=\"calibre9\">null<\/code> first. If this is <code class=\"calibre9\">true<\/code>, then the code will never execute the second clause and therefore won't throw a <code class=\"calibre9\">NullReferenceException<\/code> when accessing the <code class=\"calibre9\">Any()<\/code> member.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the two statements that create a Northwind instance and output the database provider name, and then call the <code class=\"calibre9\">ConfigureConsole<\/code> and <code class=\"calibre9\">QueryingCategories<\/code> methods, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ConfigureConsole();\nQueryingCategories();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Beverages has 12 products.\nCondiments has 12 products.\nConfections has 13 products.\nDairy Products has 10 products.\nGrains\/Cereals has 7 products.\nMeat\/Poultry has 6 products.\nProduce has 5 products.\nSeafood has 12 products.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> If you see the following exception, the most likely problem is that the <code class=\"calibre9\">Northwind.db<\/code> file is not being copied to the output directory: <code class=\"calibre9\">Unhandled exception. Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such table: Categories'<\/code>. Make sure that <strong class=\"calibre2\">Copy to Output Directory<\/strong> is set, but even when it is, some code editors do not always copy the file when they should. You might need to manually copy the <code class=\"calibre9\">Northwind.db<\/code> file to the appropriate directory.<\/p>\n<\/blockquote>\n<section data-number=\"11.5.1\" id=\"calibre_link-579\">\n<h3 data-number=\"11.5.1\" class=\"calibre8\">Filtering included entities<\/h3>\n<p class=\"rights\">EF Core 5 introduced <strong class=\"calibre2\">filtered includes<\/strong>, which means you can specify a lambda expression in the <code class=\"calibre9\">Include<\/code> method call to filter which entities are returned in the results:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Queries.cs<\/code>, define a <code class=\"calibre9\">FilteredIncludes<\/code> method, and add statements to do these tasks, as shown in the following code:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Create an instance of the <code class=\"calibre9\">Northwind<\/code> class that will manage the database.<\/li>\n<li class=\"calibre3\">Prompt the user to enter a minimum value for units in stock.<\/li>\n<li class=\"calibre3\">Create a query for categories that have products with that minimum number of units in stock.<\/li>\n<li class=\"calibre3\">Enumerate through the categories and products, outputting the name and units in stock for each one:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void FilteredIncludes()\n{\n  using NorthwindDb db = new();\n  SectionTitle(\"Products with a minimum number of units in stock\");\n  string? input;\n  int stock;\n  do\n  {\n    Write(\"Enter a minimum for units in stock: \");\n    input = ReadLine();\n  } while (!int.TryParse(input, out stock));\n  IQueryable&lt;Category&gt;? categories = db.Categories?\n    .Include(c =&gt; c.Products.Where(p =&gt; p.Stock &gt;= stock));\n  if (categories is null || !categories.Any())\n  {\n    Fail(\"No categories found.\");\n    return;\n  }\n  foreach (Category c in categories)\n  {\n    WriteLine(\n      \"{0} has {1} products with a minimum {2} units in stock.\",\n      arg0: c.CategoryName, arg1: c.Products.Count, arg2: stock);\n    foreach(Product p in c.Products)\n    {\n      WriteLine($\"  {p.ProductName} has {p.Stock} units in stock.\");\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, call the <code class=\"calibre9\">FilteredIncludes<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">FilteredIncludes();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter a minimum value for units in stock, like <code class=\"calibre9\">100<\/code>, and view the result, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter a minimum for units in stock: 100\nBeverages has 2 products with a minimum of 100 units in stock.\n  Sasquatch Ale has 111 units in stock.\n  Rh\u00f6nbr\u00e4u Klosterbier has 125 units in stock.\nCondiments has 2 products with a minimum of 100 units in stock.\n  Grandma's Boysenberry Spread has 120 units in stock.\n  Sirop d'\u00e9rable has 113 units in stock.\nConfections has 0 products with a minimum of 100 units in stock. \nDairy Products has 1 products with a minimum of 100 units in stock.\n  Geitost has 112 units in stock.\nGrains\/Cereals has 1 products with a minimum of 100 units in stock.\n  Gustaf's Kn\u00e4ckebr\u00f6d has 104 units in stock.\nMeat\/Poultry has 1 products with a minimum of 100 units in stock.\n  P\u00e2t\u00e9 chinois has 115 units in stock.\nProduce has 0 products with a minimum of 100 units in stock. \nSeafood has 3 products with a minimum of 100 units in stock.\n  Inlagd Sill has 112 units in stock.\n  Boston Crab Meat has 123 units in stock. \n  R\u00f6d Kaviar has 101 units in stock.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Unicode characters in the Windows console:<\/strong> There is a limitation with the console provided by Microsoft on versions of Windows before the Windows 10 Fall Creators Update. By default, the console cannot display Unicode characters, for example, in the name Rh\u00f6nbr\u00e4u.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you have this issue, then you can temporarily change the code page (also known as the character set) in a console to Unicode UTF-8 by entering the following command at the prompt before running the app:<\/p>\n<\/blockquote>\n<\/blockquote>\n<pre class=\"calibre22\"><code class=\"calibre23\">chcp 65001<\/code><\/pre>\n<\/section>\n<section data-number=\"11.5.2\" id=\"calibre_link-580\">\n<h3 data-number=\"11.5.2\" class=\"calibre8\">Filtering and sorting products<\/h3>\n<p class=\"rights\">Let's explore a more complex query that will filter and sort data:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Queries.cs<\/code>, define a <code class=\"calibre9\">QueryingProducts<\/code> method, and add statements to do the following, as shown in the following code:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Create an instance of the <code class=\"calibre9\">Northwind<\/code> class that will manage the database.<\/li>\n<li class=\"calibre3\">Prompt the user for a price for products.<\/li>\n<li class=\"calibre3\">Create a query for products that cost more than the price using LINQ.<\/li>\n<li class=\"calibre3\">Loop through the results, outputting the ID, name, cost (formatted in US dollars), and the number of units in stock:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void QueryingProducts()\n{\n  using NorthwindDb db = new();\n  SectionTitle(\"Products that cost more than a price, highest at top\");\n  string? input;\n  decimal price;\n  do\n  {\n    Write(\"Enter a product price: \");\n    input = ReadLine();\n  } while (!decimal.TryParse(input, out price));\n  IQueryable&lt;Product&gt;? products = db.Products?\n    .Where(product =&gt; product.Cost &gt; price)\n    .OrderByDescending(product =&gt; product.Cost);\n  if (products is null || !products.Any())\n  {\n    Fail(\"No products found.\");\n    return;\n  }\n  foreach (Product p in products)\n  {\n    WriteLine(\n      \"{0}: {1} costs {2:$#,##0.00} and has {3} in stock.\",\n      p.ProductId, p.ProductName, p.Cost, p.Stock);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, call the <code class=\"calibre9\">QueryingProducts<\/code> method.<\/li>\n<li class=\"calibre3\">Run the code, enter <code class=\"calibre9\">50<\/code> when prompted to enter a product price, view the result, and note the descending order by cost, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter a product price: 50\n38: C\u00f4te de Blaye costs $263.50 and has 17 in stock.\n29: Th\u00fcringer Rostbratwurst costs $123.79 and has 0 in stock. \n9: Mishi Kobe Niku costs $97.00 and has 29 in stock.\n20: Sir Rodney's Marmalade costs $81.00 and has 40 in stock. \n18: Carnarvon Tigers costs $62.50 and has 42 in stock.\n59: Raclette Courdavault costs $55.00 and has 79 in stock. \n51: Manjimup Dried Apples costs $53.00 and has 20 in stock.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter <code class=\"calibre9\">500<\/code> when prompted to enter a product price, and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Fail &gt; No products found.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"11.5.3\" id=\"calibre_link-581\">\n<h3 data-number=\"11.5.3\" class=\"calibre8\">Getting the generated SQL<\/h3>\n<p class=\"rights\">You might be wondering how well written the SQL statements are that are generated from the C# queries we write. EF Core 5 introduced a quick and easy way to see the SQL generated:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">FilteredIncludes<\/code> method, before using the <code class=\"calibre9\">foreach<\/code> statement to enumerate the query, add a statement to output the generated SQL, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Info($\"ToQueryString: {categories.ToQueryString()}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">QueryingProducts<\/code> method, before using the <code class=\"calibre9\">foreach<\/code> statement to enumerate the query, add a statement to output the generated SQL, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Info($\"ToQueryString: {products.ToQueryString()}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, enter a minimum value for units in stock, like <code class=\"calibre9\">99<\/code>, and view the result, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter a minimum for units in stock: 95\nConnection: Data Source=C:\\cs12dotnet8\\Chapter10\\WorkingWithEFCore\\bin\\Debug\\net8.0\\Northwind.db\nInfo &gt; ToQueryString: .param set @__stock_0 95\nSELECT \"c\".\"CategoryId\", \"c\".\"CategoryName\", \"c\".\"Description\", \"t\".\"ProductId\", \"t\".\"CategoryId\", \"t\".\"UnitPrice\", \"t\".\"Discontinued\", \"t\".\"ProductName\", \"t\".\"UnitsInStock\"\nFROM \"Categories\" AS \"c\"\nLEFT JOIN (\n    SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n    FROM \"Products\" AS \"p\"\n    WHERE \"p\".\"UnitsInStock\" &gt;= @__stock_0\n) AS \"t\" ON \"c\".\"CategoryId\" = \"t\".\"CategoryId\"\nORDER BY \"c\".\"CategoryId\"\nBeverages has 2 products with a minimum of 95 units in stock.\n  Sasquatch Ale has 111 units in stock.\n  Rh\u00f6nbr\u00e4u Klosterbier has 125 units in stock.\n...<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the SQL parameter named <code class=\"calibre9\">@__stock_0<\/code> has been set to a minimum stock value of <code class=\"calibre9\">95<\/code>.If you used SQL Server, the generated SQL will be slightly different. For example, it uses square brackets instead of double quotes around object names, as shown in the following output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Info &gt; ToQueryString: DECLARE @__stock_0 smallint = CAST(95 AS smallint);\nSELECT .[CategoryId], .[CategoryName], .[Description], [t].[ProductId], [t].[CategoryId], [t].[UnitPrice], [t].[Discontinued], [t].[ProductName], [t].[UnitsInStock]\nFROM [Categories] AS \nLEFT JOIN (\n    SELECT [p].[ProductId], [p].[CategoryId], [p].[UnitPrice], [p].[Discontinued], [p].[ProductName], [p].[UnitsInStock]\n    FROM [Products] AS [p]\n    WHERE [p].[UnitsInStock] &gt;= @__stock_0\n) AS [t] ON .[CategoryId] = [t].[CategoryId]\nORDER BY .[CategoryId]<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"11.5.4\" id=\"calibre_link-582\">\n<h3 data-number=\"11.5.4\" class=\"calibre8\">Logging EF Core<\/h3>\n<p class=\"rights\">To monitor the interaction between EF Core and the database, we can enable logging. Logging could be to the console, to <code class=\"calibre9\">Debug<\/code> or <code class=\"calibre9\">Trace<\/code>, or to a file.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: By default, EF Core logging will exclude any data in case it is sensitive. You can include this data by calling the <code class=\"calibre9\">EnableSensitiveDataLogging<\/code> method, especially during development. You should disable it before deploying to production. You can also call <code class=\"calibre9\">EnableDetailedErrors<\/code>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's see an example of this in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">NorthwindDb.cs<\/code>, at the bottom of the <code class=\"calibre9\">OnConfiguring<\/code> method, add statements to log to the console and to include sensitive data like parameter values for commands being sent to the database if we compile the debug configuration, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">optionsBuilder.LogTo(WriteLine) \/\/ This is the Console method.\n#if DEBUG\n  .EnableSensitiveDataLogging() \/\/ Include SQL parameters.\n  .EnableDetailedErrors()\n#endif\n;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">LogTo<\/code> requires an <code class=\"calibre9\">Action&lt;string&gt;<\/code> delegate. EF Core will call this delegate, passing a <code class=\"calibre9\">string<\/code> value for each log message. Passing the <code class=\"calibre9\">Console<\/code> class <code class=\"calibre9\">WriteLine<\/code> method, therefore, tells the logger to write each method to the console.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Note that when the solution configuration is <strong class=\"calibre2\">Debug<\/strong>, the calls to the <code class=\"calibre9\">EnableSensitiveDataLogging<\/code> and <code class=\"calibre9\">EnableDetailedErrors<\/code> methods are included in the compilation, but if you change the solution configuration to <strong class=\"calibre2\">Release<\/strong>, the method calls are grayed out to indicate that they are not compiled, as shown in <em class=\"calibre10\">Figure 10.7<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 10.7: Including SQL parameters in logging for debug configuration\" height=\"712\" src=\"\/images\/cs12\/000083.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 10.7: Including SQL parameters in logging for debug configuration<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Run the code and view the log messages, which are shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">warn: 7\/16\/2023 14:03:40.255 CoreEventId.SensitiveDataLoggingEnabledWarning[10400] (Microsoft.EntityFrameworkCore.Infrastructure)\n      Sensitive data logging is enabled. Log entries and exception messages may include sensitive application data; this mode should only be enabled during development.\n...\ndbug: 05\/03\/2023 12:36:11.702 RelationalEventId.ConnectionOpening[20000] (Microsoft.EntityFrameworkCore.Database.Connection)\n      Opening connection to database 'main' on server 'C:\\cs12dotnet8\\Chapter10\\WorkingWithEFCore\\bin\\Debug\\net8.0\\Northwind.db'.\ndbug: 05\/03\/2023 12:36:11.718 RelationalEventId.ConnectionOpened[20001] (Microsoft.EntityFrameworkCore.Database.Connection)\n      Opened connection to database 'main' on server 'C:\\cs12dotnet8\\Chapter10\\WorkingWithEFCore\\bin\\Debug\\net8.0\\Northwind.db'.\ndbug: 05\/03\/2023 12:36:11.721 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']\n      SELECT \"c\".\"CategoryId\", \"c\".\"CategoryName\", \"c\".\"Description\", \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n      FROM \"Categories\" AS \"c\"\n      LEFT JOIN \"Products\" AS \"p\" ON \"c\".\"CategoryId\" = \"p\".\"CategoryId\"\n      ORDER BY \"c\".\"CategoryId\"\n...<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Your logs might vary from those shown above based on your chosen database provider and code editor and future improvements to EF Core. For now, note that different events like opening a connection or executing a command have different event IDs, as shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">20000<\/code> <code class=\"calibre9\">RelationalEventId.ConnectionOpening<\/code>: Includes the database file path<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">20001<\/code> <code class=\"calibre9\">RelationalEventId.ConnectionOpened<\/code>: Includes the database file path<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">20100<\/code> <code class=\"calibre9\">RelationalEventId.CommandExecuting<\/code>: Includes the SQL statement<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"11.5.5\" id=\"calibre_link-583\">\n<h3 data-number=\"11.5.5\" class=\"calibre8\">Filtering logs by provider-specific values<\/h3>\n<p class=\"rights\">The event ID values and what they mean will be specific to the EF Core provider. If we want to know how the LINQ query has been translated into SQL statements and is executing, then the event ID to output has an <code class=\"calibre9\">Id<\/code> value of <code class=\"calibre9\">20100<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">NorthwindDb.cs<\/code>, import the namespace for working for EF Core diagnostics, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ To use RelationalEventId.\nusing Microsoft.EntityFrameworkCore.Diagnostics;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the <code class=\"calibre9\">LogTo<\/code> method call to only output events with an <code class=\"calibre9\">Id<\/code> of <code class=\"calibre9\">20100<\/code>, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">optionsBuilder.LogTo(WriteLine, \/\/ This is the Console method.\n  new[] { RelationalEventId.CommandExecuting })\n#if DEBUG\n  .EnableSensitiveDataLogging()\n  .EnableDetailedErrors()\n#endif\n;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the following SQL statements that were logged, as shown in the following output, which has been edited for space:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dbug: 05\/03\/2022 12:48:43.153 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']\n      SELECT \"c\".\"CategoryId\", \"c\".\"CategoryName\", \"c\".\"Description\", \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n      FROM \"Categories\" AS \"c\"\n      LEFT JOIN \"Products\" AS \"p\" ON \"c\".\"CategoryId\" = \"p\".\"CategoryId\"\n      ORDER BY \"c\".\"CategoryId\"\nBeverages has 12 products.\nCondiments has 12 products.\nConfections has 13 products.\nDairy Products has 10 products.\nGrains\/Cereals has 7 products.\nMeat\/Poultry has 6 products.\nProduce has 5 products.\nSeafood has 12 products.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"11.5.6\" id=\"calibre_link-584\">\n<h3 data-number=\"11.5.6\" class=\"calibre8\">Logging with query tags<\/h3>\n<p class=\"rights\">When logging LINQ queries, it can be tricky to correlate log messages in complex scenarios. EF Core 2.2 introduced the query tags feature to help by allowing you to add SQL comments to the log.You can annotate a LINQ query using the <code class=\"calibre9\">TagWith<\/code> method, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">IQueryable&lt;Product&gt;? products = db.Products?\n  .TagWith(\"Products filtered by price and sorted.\")\n  .Where(product =&gt; product.Cost &gt; price)\n  .OrderByDescending(product =&gt; product.Cost);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This will add a SQL comment to the log, as shown in the following output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">-- Products filtered by price and sorted.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"11.5.7\" id=\"calibre_link-585\">\n<h3 data-number=\"11.5.7\" class=\"calibre8\">Getting a single entity<\/h3>\n<p class=\"rights\">There are two LINQ methods to get a single entity: <code class=\"calibre9\">First<\/code> and <code class=\"calibre9\">Single<\/code>. It is important to understand the difference between them when using an EF Core database provider. Let\u2019s see an example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Queries.cs<\/code>, define a <code class=\"calibre9\">GettingOneProduct<\/code> method, and add statements to do the following, as shown in the following code:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Create an instance of the <code class=\"calibre9\">Northwind<\/code> class that will manage the database.<\/li>\n<li class=\"calibre3\">Prompt the user for a product ID.<\/li>\n<li class=\"calibre3\">Create a query for products with that product ID using the <code class=\"calibre9\">First<\/code> and <code class=\"calibre9\">Single<\/code> methods.<\/li>\n<li class=\"calibre3\">Write to SQL statement for each query to the console:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void GettingOneProduct()\n{\n  using NorthwindDb db = new();\n  SectionTitle(\"Getting a single product\");\n  string? input;\n  int id;\n  do\n  {\n    Write(\"Enter a product ID: \");\n    input = ReadLine();\n  } while (!int.TryParse(input, out id));\n  Product? product = db.Products?\n    .First(product =&gt; product.ProductId == id);\n  Info($\"First: {product?.ProductName}\");\n  if (product is null) Fail(\"No product found using First.\");\n  product = db.Products?\n    .Single(product =&gt; product.ProductId == id);\n  Info($\"Single: {product?.ProductName}\");\n  if (product is null) Fail(\"No product found using Single.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, call the <code class=\"calibre9\">GettingOneProduct<\/code> method.<\/li>\n<li class=\"calibre3\">Run the code, enter <code class=\"calibre9\">1<\/code> when prompted to enter a product ID, view the result, and note the SQL statements used by <code class=\"calibre9\">First<\/code> and <code class=\"calibre9\">Single<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter a product ID: 1\nConnection: Data Source=C:\\cs12dotnet8\\Chapter10\\WorkingWithEFCore\\bin\\Debug\\net8.0\\Northwind.db\ndbug: 9\/17\/2023 18:04:14.210 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@__id_0='1'], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n      FROM \"Products\" AS \"p\"\n      WHERE NOT (\"p\".\"Discontinued\") AND \"p\".\"ProductId\" &gt; @__id_0\n      LIMIT 1\nInfo &gt; First: Chang\ndbug: 9\/17\/2023 18:04:14.286 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@__id_0='1'], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n      FROM \"Products\" AS \"p\"\n      WHERE NOT (\"p\".\"Discontinued\") AND \"p\".\"ProductId\" &gt; @__id_0\n      LIMIT 2\nInfo &gt; Single: Chang<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note that both methods execute the same SQL statement except for the <code class=\"calibre9\">LIMIT<\/code> clauses highlighted in the preceding code. For <code class=\"calibre9\">First<\/code>, it sets <code class=\"calibre9\">LIMIT 1<\/code> but for <code class=\"calibre9\">Single<\/code>, it sets <code class=\"calibre9\">LIMIT 2<\/code>. Why?For <code class=\"calibre9\">First<\/code>, the query can match one or more entities and only the first will be returned. If there are no matches, an exception is thrown, but you can call <code class=\"calibre9\">FirstOrDefault<\/code> to return <code class=\"calibre9\">null<\/code> if there are no matches.For <code class=\"calibre9\">Single<\/code>, the query must match only one entity and it will be returned. If there are more than one match, an exception must be thrown. But the only way for EF Core to know if there are more than one match is to request more than one and check. So, it has to set <code class=\"calibre9\">LIMIT 2<\/code> and check if there is a second entity match.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If you do not need to make sure that only one entity matches, use <code class=\"calibre9\">First<\/code> instead of <code class=\"calibre9\">Single<\/code> to avoid retrieving two records.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"11.5.8\" id=\"calibre_link-586\">\n<h3 data-number=\"11.5.8\" class=\"calibre8\">Pattern matching with Like<\/h3>\n<p class=\"rights\">EF Core supports common SQL statements including <code class=\"calibre9\">Like<\/code> for pattern matching:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Queries.cs<\/code>, add a method named <code class=\"calibre9\">QueryingWithLike<\/code>, as shown in the following code, and note:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">We have enabled logging.<\/li>\n<li class=\"calibre3\">We prompt the user to enter part of a product name and then use the <code class=\"calibre9\">EF.Functions.Like<\/code> method to search anywhere in the <code class=\"calibre9\">ProductName<\/code> property.<\/li>\n<li class=\"calibre3\">For each matching product, we output its name, stock, and if it is discontinued:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void QueryingWithLike()\n{\n  using NorthwindDb db = new();\n  SectionTitle(\"Pattern matching with LIKE\");\n  Write(\"Enter part of a product name: \");\n  string? input = ReadLine();\n  if (string.IsNullOrWhiteSpace(input))\n  {\n    Fail(\"You did not enter part of a product name.\");\n    return;\n  }\n  IQueryable&lt;Product&gt;? products = db.Products?\n    .Where(p =&gt; EF.Functions.Like(p.ProductName, $\"%{input}%\"));\n  if (products is null || !products.Any())\n  {\n    Fail(\"No products found.\");\n    return;\n  }\n  foreach (Product p in products)\n  {\n    WriteLine(\"{0} has {1} units in stock. Discontinued: {2}\", \n      p.ProductName, p.Stock, p.Discontinued);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the existing methods and call <code class=\"calibre9\">QueryingWithLike<\/code>.<\/li>\n<li class=\"calibre3\">Run the code, enter a partial product name such as <code class=\"calibre9\">che<\/code>, and view the result, as shown in the following edited output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter part of a product name: che\ndbug: 07\/16\/2023 13:03:42.793 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@__Format_1='%che%' (Size = 5)], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n      FROM \"Products\" AS \"p\"\n      WHERE \"p\".\"ProductName\" LIKE @__Format_1\nChef Anton's Cajun Seasoning has 53 units in stock. Discontinued: False\nChef Anton's Gumbo Mix has 0 units in stock. Discontinued: True\nQueso Manchego La Pastora has 86 units in stock. Discontinued: False<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about wildcards with <strong class=\"calibre2\">LIKE<\/strong> at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/framework\/data\/adonet\/ef\/language-reference\/like-entity-sql\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/framework\/data\/adonet\/ef\/language-reference\/like-entity-sql<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"11.5.9\" id=\"calibre_link-587\">\n<h3 data-number=\"11.5.9\" class=\"calibre8\">Generating a random number in queries<\/h3>\n<p class=\"rights\">EF Core 6 introduced a useful function, <code class=\"calibre9\">EF.Functions.Random<\/code>, that maps to a database function returning a pseudo-random number between 0 and 1, exclusive. For example, you could multiply the random number by the count of rows in a table to select one random row from that table.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Queries.cs<\/code>, add a method named <code class=\"calibre9\">GetRandomProduct<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void GetRandomProduct()\n{\n  using NorthwindDb db = new();\n  SectionTitle(\"Get a random product\");\n  int? rowCount = db.Products?.Count();\n  if (rowCount is null)\n  {\n    Fail(\"Products table is empty.\");\n    return;\n  }\n  Product? p = db.Products?.FirstOrDefault(\n    p =&gt; p.ProductId == (int)(EF.Functions.Random() * rowCount));\n  if (p is null)\n  {\n    Fail(\"Product not found.\");\n    return;\n  }\n  WriteLine($\"Random product: {p.ProductId} - {p.ProductName}\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a call to <code class=\"calibre9\">GetRandomProduct<\/code>.<\/li>\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dbug: 05\/03\/2023 13:19:01.783 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']\n      SELECT COUNT(*)\n      FROM \"Products\" AS \"p\"\ndbug: 05\/03\/2022 13:19:01.848 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@__p_1='77' (Nullable = true)], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n      FROM \"Products\" AS \"p\"\n      WHERE \"p\".\"ProductId\" = CAST((abs(random() \/ 9.2233720368547799E+18) * @__p_1) AS INTEGER)\n      LIMIT 1\nRandom product: 42 - Singaporean Hokkien Fried Mee<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"11.5.10\" id=\"calibre_link-588\">\n<h3 data-number=\"11.5.10\" class=\"calibre8\">Defining global filters<\/h3>\n<p class=\"rights\">Northwind products can be discontinued, so it might be useful to ensure that discontinued products are never returned in results, even if the programmer does not use <code class=\"calibre9\">Where<\/code> to filter them out in their queries:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">NorthwindDb.cs<\/code>, at the bottom of the <code class=\"calibre9\">OnModelCreating<\/code> method, add a global filter to remove discontinued products, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ A global filter to remove discontinued products.\nmodelBuilder.Entity&lt;Product&gt;()\n  .HasQueryFilter(p =&gt; !p.Discontinued);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, uncomment the call to <code class=\"calibre9\">QueryingWithLike<\/code>, and comment out all the other method calls.<\/li>\n<li class=\"calibre3\">Run the code, enter the partial product name <code class=\"calibre9\">che<\/code>, view the result, and note that <strong class=\"calibre2\">Chef Anton's Gumbo Mix<\/strong> is now missing, because the SQL statement generated includes a filter for the <code class=\"calibre9\">Discontinued<\/code> column, as shown highlighted in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter part of a product name: che\ndbug: 05\/03\/2022 13:34:27.290 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@__Format_1='%che%' (Size = 5)], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n      FROM \"Products\" AS \"p\"\n      WHERE NOT (\"p\".\"Discontinued\") AND (\"p\".\"ProductName\" LIKE @__Format_1)\nChef Anton's Cajun Seasoning has 53 units in stock. Discontinued? False\nQueso Manchego La Pastora has 86 units in stock. Discontinued? False\nGumb\u00e4r Gummib\u00e4rchen has 15 units in stock. Discontinued? False<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You've now seen many common ways to query data using EF Core. Next, we will look at how data is loaded and tracked and why you might want to control how EF Core does that.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"11.6\" id=\"calibre_link-589\">\n<h2 data-number=\"11.6\" class=\"calibre5\">Loading and tracking patterns with EF Core<\/h2>\n<p class=\"rights\">There are three loading patterns that are commonly used with EF Core:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Eager loading<\/strong>: Load data early.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Lazy loading<\/strong>: Load data automatically just before it is needed.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Explicit loading<\/strong>: Load data manually.<\/li>\n<\/ul>\n<p class=\"rights\">In this section, we're going to introduce each of them.<\/p>\n<section data-number=\"11.6.1\" id=\"calibre_link-590\">\n<h3 data-number=\"11.6.1\" class=\"calibre8\">Eager loading entities using the Include extension method<\/h3>\n<p class=\"rights\">In the <code class=\"calibre9\">QueryingCategories<\/code> method, the code currently uses the <code class=\"calibre9\">Categories<\/code> property to loop through each category, outputting the category name and the number of products in that category.This works because when we wrote the query, we enabled eager loading by calling the <code class=\"calibre9\">Include<\/code> method for the related products.Let's see what happens if we do not call <code class=\"calibre9\">Include<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Queries.cs<\/code>, in the <code class=\"calibre9\">QueryingCategories<\/code> method, modify the query to comment out the <code class=\"calibre9\">Include<\/code> method call, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">IQueryable&lt;Category&gt;? categories = db.Categories;\n  \/\/.Include(c =&gt; c.Products);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out all method calls except <code class=\"calibre9\">ConfigureConsole<\/code> and <code class=\"calibre9\">QueryingCategories<\/code>.<\/li>\n<li class=\"calibre3\">Run the code and view the result, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Beverages has 0 products. \nCondiments has 0 products. \nConfections has 0 products.\nDairy Products has 0 products. \nGrains\/Cereals has 0 products. \nMeat\/Poultry has 0 products.\nProduce has 0 products. \nSeafood has 0 products.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Each item in <code class=\"calibre9\">foreach<\/code> is an instance of the <code class=\"calibre9\">Category<\/code> class, which has a property named <code class=\"calibre9\">Products<\/code>, that is, the list of products in that category. Since the original query is only selected from the <code class=\"calibre9\">Categories<\/code> table, this property is empty for each category.<\/p>\n<\/section>\n<section data-number=\"11.6.2\" id=\"calibre_link-591\">\n<h3 data-number=\"11.6.2\" class=\"calibre8\">Enabling lazy loading<\/h3>\n<p class=\"rights\">Lazy loading was introduced in EF Core 2.1, and it can automatically load missing related data. To enable lazy loading, developers must:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Reference a NuGet package for proxies.<\/li>\n<li class=\"calibre3\">Configure lazy loading to use a proxy.<\/li>\n<\/ul>\n<p class=\"rights\">Let's see this in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithEFCore<\/code> project, add a package reference for EF Core proxies, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PackageReference Version=\"8.0.0\"\n  Include=\"Microsoft.EntityFrameworkCore.Proxies\" \/&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">WorkingWithEFCore<\/code> project to restore packages.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">NorthwindDb.cs<\/code>, at the bottom of the <code class=\"calibre9\">OnConfiguring<\/code> method, call an extension method to use lazy loading proxies, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">optionsBuilder.UseLazyLoadingProxies();<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Now, every time the loop enumerates and an attempt is made to read the <code class=\"calibre9\">Products<\/code> property, the lazy loading proxy will check if they are loaded. If they're not loaded, it will load them for us \"lazily\" by executing a <code class=\"calibre9\">SELECT<\/code> statement to load just that set of products for the current category, and then the correct count will be returned to the output.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note that the product counts are now correct. But you will see that the problem with lazy loading is that multiple round trips to the database server are required to eventually fetch all the data. For example, getting all the categories and then getting the products for the first category, <code class=\"calibre9\">Beverages<\/code>, requires the execution of two SQL commands, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dbug: 05\/03\/2022 13:41:40.221 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']\n      SELECT \"c\".\"CategoryId\", \"c\".\"CategoryName\", \"c\".\"Description\"\n      FROM \"Categories\" AS \"c\"\ndbug: 05\/03\/2022 13:41:40.331 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@__p_0='1'], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n      FROM \"Products\" AS \"p\"\n      WHERE NOT (\"p\".\"Discontinued\") AND \"p\".\"CategoryId\" = @__p_0\nBeverages has 11 products.\n...<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"11.6.3\" id=\"calibre_link-592\">\n<h3 data-number=\"11.6.3\" class=\"calibre8\">Explicit loading entities using the Load method<\/h3>\n<p class=\"rights\">Another type of loading is explicit loading. It works in a similar way to lazy loading, with the difference being that you are in control of exactly what related data is loaded and when:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">Program.Queries.cs<\/code>, import the change tracking namespace to enable us to use the <code class=\"calibre9\">CollectionEntry<\/code> class to manually load related entities, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ To use CollectionEntry.\nusing Microsoft.EntityFrameworkCore.ChangeTracking;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">QueryingCategories<\/code>, modify the statements to disable lazy loading and then prompt the user as to whether they want to enable eager loading and explicit loading, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">IQueryable&lt;Category&gt;? categories;\n  \/\/ = db.Categories;\n  \/\/ .Include(c =&gt; c.Products);\ndb.ChangeTracker.LazyLoadingEnabled = false;\nWrite(\"Enable eager loading? (Y\/N): \");\nbool eagerLoading = (ReadKey().Key == ConsoleKey.Y); \nbool explicitLoading = false;\nWriteLine();\nif (eagerLoading)\n{\n  categories = db.Categories?.Include(c =&gt; c.Products);\n}\nelse\n{\n  categories = db.Categories;\n  Write(\"Enable explicit loading? (Y\/N): \");\n  explicitLoading = (ReadKey().Key == ConsoleKey.Y);\n  WriteLine();\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">foreach<\/code> loop, before the <code class=\"calibre9\">WriteLine<\/code> method call, add statements to check if explicit loading is enabled, and if so, prompt the user as to whether they want to explicitly load each individual category, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (explicitLoading)\n{\n  Write($\"Explicitly load products for {c.CategoryName}? (Y\/N): \"); \n  ConsoleKeyInfo key = ReadKey();\n  WriteLine();\n  if (key.Key == ConsoleKey.Y)\n  {\n    CollectionEntry&lt;Category, Product&gt; products =\n      db.Entry(c).Collection(c2 =&gt; c2.Products);\n    if (!products.IsLoaded) products.Load();\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code:\n<ol class=\"toc1\">\n<li class=\"calibre3\">Press <span>N<\/span> to disable eager loading.<\/li>\n<li class=\"calibre3\">Then, press <span>Y<\/span> to enable explicit loading.<\/li>\n<li class=\"calibre3\">For each category, press <span>Y<\/span> or <span>N<\/span> to load its products as you wish.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p class=\"rights\">I chose to load products for only two of the eight categories, <code class=\"calibre9\">Beverages<\/code> and <code class=\"calibre9\">Seafood<\/code>, as shown in the following output, which has been edited for space:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enable eager loading? (Y\/N): n\nEnable explicit loading? (Y\/N): y\ndbug: 05\/03\/2023 13:48:48.541 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']\n      SELECT \"c\".\"CategoryId\", \"c\".\"CategoryName\", \"c\".\"Description\"\n      FROM \"Categories\" AS \"c\"\nExplicitly load products for Beverages? (Y\/N): y\ndbug: 05\/03\/2023 13:49:07.416 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@__p_0='1'], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n      FROM \"Products\" AS \"p\"\n      WHERE NOT (\"p\".\"Discontinued\") AND \"p\".\"CategoryId\" = @__p_0\nBeverages has 11 products.\nExplicitly load products for Condiments? (Y\/N): n\nCondiments has 0 products.\nExplicitly load products for Confections? (Y\/N): n\nConfections has 0 products.\nExplicitly load products for Dairy Products? (Y\/N): n\nDairy Products has 0 products.\nExplicitly load products for Grains\/Cereals? (Y\/N): n\nGrains\/Cereals has 0 products.\nExplicitly load products for Meat\/Poultry? (Y\/N): n\nMeat\/Poultry has 0 products.\nExplicitly load products for Produce? (Y\/N): n\nProduce has 0 products.\nExplicitly load products for Seafood? (Y\/N): y\ndbug: 05\/03\/2023 13:49:16.682 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@__p_0='8'], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n      FROM \"Products\" AS \"p\"\n      WHERE NOT (\"p\".\"Discontinued\") AND \"p\".\"CategoryId\" = @__p_0\nSeafood has 12 products.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Carefully consider which loading pattern is best for your code. Lazy loading could literally make you a lazy database developer! Read more about loading patterns at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/ef\/core\/querying\/related-data\">https:\/\/learn.microsoft.com\/en-us\/ef\/core\/querying\/related-data<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"11.6.4\" id=\"calibre_link-593\">\n<h3 data-number=\"11.6.4\" class=\"calibre8\">Controlling the tracking of entities<\/h3>\n<p class=\"rights\">We need to start with the definition of entity <strong class=\"calibre2\">identity resolution<\/strong>. EF Core resolves each entity instance by reading its unique primary key value. This ensures no ambiguities about the identities of entities or relationships between them.By default, EF Core assumes that you want to track entities in local memory so that if you make changes, like adding a new entity, modifying an existing entity, or removing an existing entity, then you can call <code class=\"calibre9\">SaveChanges<\/code> and all those changes will be made in the underlying data store.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">EF Core can only track entities with keys because it uses the key to uniquely identify the entity in the database. Keyless entities, like those returned by views, are never tracked in any scenario.<\/p>\n<\/blockquote>\n<p class=\"rights\">In the Northwind database, in the <code class=\"calibre9\">Customers<\/code> table, there is a customer, as shown in the following record:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CustomerId: ALFKI\nCompanyName: Alfreds Futterkiste\nCountry: Germany\nPhone: 030-0074321<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you execute a query within a data context, like getting all customers in Germany, and then execute another query within the same data context, like getting all customers whose name starts with A, if one of those customer entities already exists in the context, it will be identified and not loaded again, which improves performance.However, if the telephone number of that customer is updated in the database between the executions of the two queries, then the entity being tracked in the data context is not refreshed with the new telephone number.If you do not need to track local changes, or you want to load new instances of an entity for every query execution with the latest data values, even if the entity is already loaded, then you can disable tracking.To disable tracking for an individual query, call the <code class=\"calibre9\">AsNoTracking<\/code> method as part of the query, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var products = db.Products\n  .AsNoTracking()\n  .Where(p =&gt; p.UnitPrice &gt; price)\n  .Select(p =&gt; new { p.ProductId, p.ProductName, p.UnitPrice });<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To disable tracking by default for an instance of a data context, set the change tracker's query-tracking behavior to <code class=\"calibre9\">NoTracking<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To disable tracking for an individual query, but retain identity resolution, call the <code class=\"calibre9\">AsNoTrackingWithIdentityResolution<\/code> method as part of the query, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var products = db.Products\n  .AsNoTrackingWithIdentityResolution()\n  .Where(p =&gt; p.UnitPrice &gt; price)\n  .Select(p =&gt; new { p.ProductId, p.ProductName, p.UnitPrice });<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To disable tracking but perform identity resolution by default for an instance of a data context, set the change tracker's query tracking behavior to <code class=\"calibre9\">NoTrackingWithIdentityResolution<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">db.ChangeTracker.QueryTrackingBehavior = \n  QueryTrackingBehavior.NoTrackingWithIdentityResolution;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To set defaults for all new instances of a data context, in its <code class=\"calibre9\">OnConfiguring<\/code> method, call the <code class=\"calibre9\">UseQueryTrackingBehavior<\/code> method, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)\n{\n  optionsBuilder.UseSqlServer(connectionString)\n    .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"11.6.5\" id=\"calibre_link-594\">\n<h3 data-number=\"11.6.5\" class=\"calibre8\">Three tracking scenarios<\/h3>\n<p class=\"rights\">First, let\u2019s review a scenario using default tracking. The default is tracking with identity resolution. Once an entity is loaded into the data context, underlying changes are not reflected and only one copy exists locally. Entities have local changes tracked and a call to <code class=\"calibre9\">SaveChanges<\/code> updates the database. Actions and states for scenario 1 are illustrated in <em class=\"calibre10\">Table 10.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Action<\/td>\n<td class=\"calibre21\">Entity in data context<\/td>\n<td class=\"calibre21\">Row in database<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Query for customers in Germany<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Change telephone in database<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Query for customers starting with A<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Query for customers in Germany<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Change telephone in local entity<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-1928<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Save changes<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-1928<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-1928<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 10.4: Scenario 1, change tracking with identity resolution<\/p>\n<p class=\"rights\">Second, let's compare the same set of actions using no tracking and no identity resolution. Every query loads another instance of a database row into the data context, including underlying changes, allowing duplicates and mixed out-of-date and updated data. No local entity changes are tracked, so <code class=\"calibre9\">SaveChanges<\/code> does nothing. Actions and states for scenario 2 are illustrated in <em class=\"calibre10\">Table 10.5<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre25\"><\/col>\n<col class=\"calibre25\"><\/col>\n<col class=\"calibre25\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Action<\/td>\n<td class=\"calibre21\">Entities in data context<\/td>\n<td class=\"calibre21\">Row in database<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Query for customers in Germany<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Change telephone in database<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Query for customers starting with A<\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Alfreds Futterkiste, 030-7432<\/p>\n<p class=\"rights\">Alfreds Futterkiste, 030-9876<\/p>\n<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Query for customers in Germany<\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Alfreds Futterkiste, 030-7432<\/p>\n<p class=\"rights\">Alfreds Futterkiste, 030-9876<\/p>\n<p class=\"rights\">Alfreds Futterkiste, 030-9876<\/p>\n<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Change telephone in local entity<\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Alfreds Futterkiste, 030-7432<\/p>\n<p class=\"rights\">Alfreds Futterkiste, 030-9876<\/p>\n<p class=\"rights\">Alfreds Futterkiste, 030-1928<\/p>\n<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Save changes<\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Alfreds Futterkiste, 030-7432<\/p>\n<p class=\"rights\">Alfreds Futterkiste, 030-9876<\/p>\n<p class=\"rights\">Alfreds Futterkiste, 030-1928<\/p>\n<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 10.5: Scenario 2, no change tracking with no identity resolution<\/p>\n<p class=\"rights\">Third, let's compare the same set of actions using no tracking with identity resolution. Once an entity is loaded into the data context, underlying changes are not reflected and only one copy exists. No local entity changes are tracked, so <code class=\"calibre9\">SaveChanges<\/code> does nothing. Actions and states for scenario 3 are illustrated in <em class=\"calibre10\">Table 10.6<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Action<\/td>\n<td class=\"calibre21\">Entities in data context<\/td>\n<td class=\"calibre21\">Row in database<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Query for customers in Germany<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Change telephone in database<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Query for customers starting with A<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Query for customers in Germany<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-7432<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Change telephone in local entity<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-1928<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Save changes<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-1928<\/td>\n<td class=\"calibre21\">Alfreds Futterkiste, 030-9876<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 10.6: Scenario 3, no change tracking with identity resolution<br \/>\n<\/section>\n<section data-number=\"11.6.6\" id=\"calibre_link-595\">\n<h3 data-number=\"11.6.6\" class=\"calibre8\">Lazy loading for no tracking queries<\/h3>\n<p class=\"rights\">In EF Core 7 or earlier, if you enable no tracking, then you cannot use the lazy-loading pattern. If you try, then you will see the following exception at runtime:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Unhandled exception. System.InvalidOperationException: An error was generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning': An attempt was made to lazy-load navigation 'Category' on a detached entity of type 'ProductProxy'. Lazy loading is not supported for detached entities or entities that are loaded with 'AsNoTracking'. This exception can be suppressed or logged by passing event ID 'CoreEventId.DetachedLazyLoadingWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">EF Core 8 enables support for the lazy loading of entities that are not being tracked.Let's try an example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Queries.cs<\/code>, add a method to request a no tracking query for products, and when you enumerate the products, use lazy loading to fetch the related category name, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void LazyLoadingWithNoTracking()\n{\n  using NorthwindDb db = new();\n  SectionTitle(\"Lazy-loading with no tracking\");\n  IQueryable&lt;Product&gt;? products = db.Products?.AsNoTracking();\n  if (products is null || !products.Any())\n  {\n    Fail(\"No products found.\");\n    return;\n  }\n  foreach (Product p in products)\n  {\n    WriteLine(\"{0} is in category named {1}.\",\n      p.ProductName, p.Category.CategoryName);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a call to <code class=\"calibre9\">LazyLoadingWithNoTracking<\/code>. You might want to comment out any other method calls except <code class=\"calibre9\">ConfigureConsole<\/code>, which ensures you see the same currency and other formatting as shown in the book.<\/li>\n<li class=\"calibre3\">Run the code and note that it works without throwing an exception as it would have done with previous versions of EF Core.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you want to see the runtime exception for yourself, in the project file, change the version numbers of the three EF Core packages from 8.0.0 to any older package version, like 7.0.0 or 6.0.0.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"11.6.7\" id=\"calibre_link-596\">\n<h3 data-number=\"11.6.7\" class=\"calibre8\">Summary of tracking<\/h3>\n<p class=\"rights\">Which should you choose? Of course, it depends on your specific scenarios.You will sometimes read blogs or LinkedIn posts that excitedly tell you that \"no one knows this one amazing trick to dramatically improve your EF Core queries\" by calling <code class=\"calibre9\">AsNoTracking<\/code>. But if you run a query that returns thousands of entities, and then run the same query again within the same data context, you\u2019ll now have thousands of duplicates! This wastes memory and negatively impacts performance, so the advice to \"call <code class=\"calibre9\">AsNoTracking<\/code>\" to improve performance is not always true.Understand how the three tracking choices work and select the best for your data context or individual queries.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"11.7\" id=\"calibre_link-597\">\n<h2 data-number=\"11.7\" class=\"calibre5\">Modifying data with EF Core<\/h2>\n<p class=\"rights\">Inserting, updating, and deleting entities using EF Core is an easy task to accomplish. This is often referred to as <strong class=\"calibre2\">CRUD<\/strong>, an acronym that includes the following operations:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">C<\/strong> for Create<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">R<\/strong> for Retrieve (or Read)<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">U<\/strong> for Update<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">D<\/strong> for Delete<\/li>\n<\/ul>\n<p class=\"rights\">By default, <code class=\"calibre9\">DbContext<\/code> maintains change tracking automatically, so the local entities can have multiple changes tracked, including adding new entities, modifying existing entities, and removing entities.When you are ready to send those changes to the underlying database, call the <code class=\"calibre9\">SaveChanges<\/code> method. The number of entities successfully changed will be returned.<\/p>\n<section data-number=\"11.7.1\" id=\"calibre_link-598\">\n<h3 data-number=\"11.7.1\" class=\"calibre8\">Inserting entities<\/h3>\n<p class=\"rights\">Let's start by looking at how to add a new row to a table:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">WorkingWithEFCore<\/code> project, add a new class file named <code class=\"calibre9\">Program.Modifications.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Modifications.cs<\/code>, create a partial <code class=\"calibre9\">Program<\/code> class with a method named<code class=\"calibre9\"> ListProducts<\/code> that outputs the ID, name, cost, stock, and discontinued properties of each product, sorted with the costliest first, and highlights any that match an array of <code class=\"calibre9\">int<\/code> values that can be optionally passed to the method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.EntityFrameworkCore; \/\/ To use ExecuteUpdate, ExecuteDelete.\nusing Microsoft.EntityFrameworkCore.ChangeTracking; \/\/ To use EntityEntry&lt;T&gt;.\nusing Northwind.EntityModels; \/\/ To use Northwind, Product.\npartial class Program\n{\n  private static void ListProducts(\n    int[]? productIdsToHighlight = null)\n  {\n    using NorthwindDb db = new();\n    if (db.Products is null || !db.Products.Any())\n    {\n      Fail(\"There are no products.\");\n      return;\n    }\n    WriteLine(\"| {0,-3} | {1,-35} | {2,8} | {3,5} | {4} |\",\n      \"Id\", \"Product Name\", \"Cost\", \"Stock\", \"Disc.\");\n    foreach (Product p in db.Products)\n    {\n      ConsoleColor previousColor = ForegroundColor;\n      if (productIdsToHighlight is not null &amp;&amp;\n        productIdsToHighlight.Contains(p.ProductId))\n      {\n        ForegroundColor = ConsoleColor.Green;\n      }\n      WriteLine(\"| {0:000} | {1,-35} | {2,8:$#,##0.00} | {3,5} | {4} |\",\n        p.ProductId, p.ProductName, p.Cost, p.Stock, p.Discontinued);\n      ForegroundColor = previousColor;\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Remember that <code class=\"calibre9\">1,-35<\/code> means left-align argument 1 within a 35-character-wide column, and <code class=\"calibre9\">3,5<\/code> means right-align argument 3 within a 5-character-wide column.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Modifications.cs<\/code>, add a method named <code class=\"calibre9\">AddProduct<\/code> that returns a two-integer-tuple, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static (int affected, int productId) AddProduct(\n  int categoryId, string productName, decimal? price, short? stock)\n{\n  using NorthwindDb db = new();\n  if (db.Products is null) return (0, 0);\n  Product p = new()\n  {\n    CategoryId = categoryId,\n    ProductName = productName,\n    Cost = price,\n    Stock = stock\n  };\n  \/\/ Set product as added in change tracking.\n  EntityEntry&lt;Product&gt; entity = db.Products.Add(p);\n  WriteLine($\"State: {entity.State}, ProductId: {p.ProductId}\");\n  \/\/ Save tracked change to database.\n  int affected = db.SaveChanges();\n  WriteLine($\"State: {entity.State}, ProductId: {p.ProductId}\");\n  return (affected, p.ProductId);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out previous method calls, and then call <code class=\"calibre9\">AddProduct<\/code> and <code class=\"calibre9\">ListProducts<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var resultAdd = AddProduct(categoryId: 6,\n  productName: \"Bob's Burgers\", price: 500M, stock: 72);\nif (resultAdd.affected == 1)\n{\n  WriteLine($\"Add product successful with ID: {resultAdd.productId}.\");\n}\nListProducts(productIdsToHighlight: new[] { resultAdd.productId });<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note the new product has been added, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">State: Added, ProductId: 0\ndbug: 05\/03\/2022 14:21:37.818 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@p0='6', @p1='500' (Nullable = true), @p2='False', @p3='Bob's Burgers' (Nullable = false) (Size = 13), @p4=NULL (DbType = Int16)], CommandType='Text', CommandTimeout='30']\n      INSERT INTO \"Products\" (\"CategoryId\", \"UnitPrice\", \"Discontinued\", \"ProductName\", \"UnitsInStock\")\n      VALUES (@p0, @p1, @p2, @p3, @p4);\n      SELECT \"ProductId\"\n      FROM \"Products\"\n      WHERE changes() = 1 AND \"rowid\" = last_insert_rowid();\nState: Unchanged, ProductId: 78\nAdd product successful with ID: 78.\n| Id  | Product Name                        |     Cost | Stock | Disc. |\n| 001 | Chai                                |   $18.00 |    39 | False |\n| 002 | Chang                               |   $19.00 |    17 | False | \n...\n| 078 | Bob's Burgers                       |  $500.00 |    72 | False |<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">When the new product is first created in memory and tracked by the EF Core change tracker, it has a state of <code class=\"calibre9\">Added<\/code> and its ID is 0. After the call to <code class=\"calibre9\">SaveChanges<\/code>, it has a state of <code class=\"calibre9\">Unchanged<\/code> and its ID is 78, the value assigned by the database.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"11.7.2\" id=\"calibre_link-599\">\n<h3 data-number=\"11.7.2\" class=\"calibre8\">Updating entities<\/h3>\n<p class=\"rights\">Now, let's modify an existing row in a table.We will find a product to update by specifying the start of a product name and only return the first match. In a real application, if you need to update a specific product, then you must use a unique identifier like <code class=\"calibre9\">ProductId<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">I do not know what the product ID will be for the products that you add. I do know that there are no products that start with \"Bob\" in the existing Northwind database. Finding a product to update using its name avoids having to tell you to first discover what the product ID is for a product that you've added. It is likely to be 78 because there are already 77 products in the table, but once you've added that and then deleted it, the next product to be added would be 79 and it all gets out of sync.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's go:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Modifications.cs<\/code>, add a method to increase the price of the first product with a name that begins with a specified value (we'll use <code class=\"calibre9\">Bob<\/code> in our example) by a specified amount, like <code class=\"calibre9\">$20<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static (int affected, int productId) IncreaseProductPrice(\n  string productNameStartsWith, decimal amount)\n{\n  using NorthwindDb db = new();\n  if (db.Products is null) return (0, 0);\n  \/\/ Get the first product whose name starts with the parameter value.\n  Product updateProduct = db.Products.First(\n    p =&gt; p.ProductName.StartsWith(productNameStartsWith));\n  updateProduct.Cost += amount;\n  int affected = db.SaveChanges();\n  return (affected, updateProduct.ProductId);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the statements to add a new product, and then add statements to call <code class=\"calibre9\">IncreaseProductPrice<\/code> and then <code class=\"calibre9\">ListProducts<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var resultUpdate = IncreaseProductPrice(\n  productNameStartsWith: \"Bob\", amount: 20M);\nif (resultUpdate.affected == 1)\n{\n  WriteLine($\"Increase price success for ID: {resultUpdate.productId}.\");\n}\nListProducts(productIdsToHighlight: new[] { resultUpdate.productId });<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, view the result, and note that the existing entity for <em class=\"calibre10\">Bob's Burgers<\/em> has increased in price by $20, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dbug: 05\/03\/2022 14:44:47.024 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@__productNameStartsWith_0='Bob' (Size = 3)], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"UnitPrice\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"UnitsInStock\"\n      FROM \"Products\" AS \"p\"\n      WHERE NOT (\"p\".\"Discontinued\") AND (@__productNameStartsWith_0 = '' OR ((\"p\".\"ProductName\" LIKE @__productNameStartsWith_0 || '%') AND substr(\"p\".\"ProductName\", 1, length(@__productNameStartsWith_0)) = @__productNameStartsWith_0) OR @__productNameStartsWith_0 = '')\n      LIMIT 1\ndbug: 05\/03\/2022 14:44:47.028 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@p1='78', @p0='520' (Nullable = true)], CommandType='Text', CommandTimeout='30']\n      UPDATE \"Products\" SET \"UnitPrice\" = @p0\n      WHERE \"ProductId\" = @p1;\n      SELECT changes(); \nIncrease price success for ID: 78.\n| Id  | Product Name                        |     Cost | Stock | Disc. |\n| 001 | Chai                                |   $18.00 |    39 | False |\n...\n| 078 | Bob's Burgers                       |  $520.00 |    72 | False |<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"11.7.3\" id=\"calibre_link-600\">\n<h3 data-number=\"11.7.3\" class=\"calibre8\">Deleting entities<\/h3>\n<p class=\"rights\">You can remove individual entities with the <code class=\"calibre9\">Remove<\/code> method. <code class=\"calibre9\">RemoveRange<\/code> is more efficient when you want to delete multiple entities.Let's see how to delete rows from a table:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Modifications.cs<\/code>, add a method to delete all products with a name that begins with a specified value (<code class=\"calibre9\">Bob<\/code> in our example), as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static int DeleteProducts(string productNameStartsWith)\n{\n  using NorthwindDb db = new();\n  IQueryable&lt;Product&gt;? products = db.Products?.Where(\n    p =&gt; p.ProductName.StartsWith(productNameStartsWith));\n  if (products is null || !products.Any())\n  {\n    WriteLine(\"No products found to delete.\");\n    return 0;\n  }\n  else\n  {\n    if (db.Products is null) return 0;\n    db.Products.RemoveRange(products);\n  }\n  int affected = db.SaveChanges();\n  return affected;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the statements to update the product, and then add statements to call <code class=\"calibre9\">DeleteProducts<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(\"About to delete all products whose name starts with Bob.\");\nWrite(\"Press Enter to continue or any other key to exit: \");\nif (ReadKey(intercept: true).Key == ConsoleKey.Enter)\n{\n  int deleted = DeleteProducts(productNameStartsWith: \"Bob\");\n  WriteLine($\"{deleted} product(s) were deleted.\");\n}\nelse\n{\n  WriteLine(\"Delete was canceled.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code, press <span>Enter<\/span>, and view the result, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">1 product(s) were deleted.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If multiple product names started with <code class=\"calibre9\">Bob<\/code>, then they would all be deleted. As an optional challenge, modify the statements to add three new products that start with <code class=\"calibre9\">Bob<\/code> and then delete them.<\/p>\n<\/section>\n<section data-number=\"11.7.4\" id=\"calibre_link-601\">\n<h3 data-number=\"11.7.4\" class=\"calibre8\">More efficient updates and deletes<\/h3>\n<p class=\"rights\">You have now seen the traditional way of modifying data using EF Core, as summarized in the following steps:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Create a database context. Change tracking is enabled by default.<\/li>\n<li class=\"calibre3\">To insert data, create a new instance of an entity class and then pass it as an argument to the <code class=\"calibre9\">Add<\/code> method of the appropriate collection, for example, <code class=\"calibre9\">db.Products.Add(product)<\/code>.<\/li>\n<li class=\"calibre3\">To update data, retrieve the entities that you want to modify and then change their properties.<\/li>\n<li class=\"calibre3\">To delete data, retrieve the entities that you want to remove and then pass them as an argument to the <code class=\"calibre9\">Remove<\/code> or <code class=\"calibre9\">RemoveRange<\/code> methods of the appropriate collection, for example, <code class=\"calibre9\">db.Products.Remove(product)<\/code>.<\/li>\n<li class=\"calibre3\">Call the <code class=\"calibre9\">SaveChanges<\/code> method of the database context. This uses the change tracker to generate SQL statements to perform the needed inserts, updates, and deletes, and then returns the number of entities affected.<\/li>\n<\/ol>\n<p class=\"rights\">EF Core 7 introduced two methods that can make updates and deletes more efficient because they do not require entities to be loaded into memory and have their changes tracked. The methods are named <code class=\"calibre9\">ExecuteDelete<\/code> and <code class=\"calibre9\">ExecuteUpdate<\/code> (and their <code class=\"calibre9\">Async<\/code> equivalents). They are called on a LINQ query and affect the entities in the query result, although the query is not used to retrieve entities, so no entities are loaded into the data context.For example, to delete all products, call the <code class=\"calibre9\">ExecuteDelete<\/code> or <code class=\"calibre9\">ExecuteDeleteAsync<\/code> method on any table, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">await db.Products.ExecuteDeleteAsync();<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The preceding code would execute an SQL statement in the database, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">DELETE FROM Products<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To delete all products that have a unit price greater than 50, use the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">await db.Products\n  .Where(product =&gt; product.UnitPrice &gt; 50)\n  .ExecuteDeleteAsync();<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The preceding code would execute an SQL statement in the database, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">DELETE FROM Products p WHERE p.UnitPrice &gt; 50<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">ExecuteUpdate<\/code> and <code class=\"calibre9\">ExecuteDelete<\/code> can only act on a single table, so although you can write quite complex LINQ queries, they can only update or delete from a single table.<\/p>\n<\/blockquote>\n<p class=\"rights\">To update all products that are not discontinued to increase their unit price by 10% due to inflation, use the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">await db.Products\n  .Where(product =&gt; !product.Discontinued)\n  .ExecuteUpdateAsync(s =&gt; s.SetProperty(\n    p =&gt; p.UnitPrice, \/\/ Selects the property to update.\n    p =&gt; p.UnitPrice * 0.1)); \/\/ Sets the value to update it to.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can chain multiple calls to <code class=\"calibre9\">SetProperty<\/code> in the same query to update multiple properties in one command.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's see some examples:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Modifications.cs<\/code>, add a method to update all products with a name that begins with a specified value using <code class=\"calibre9\">ExecuteUpdate<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static (int affected, int[]? productIds)\n  IncreaseProductPricesBetter(\n  string productNameStartsWith, decimal amount)\n{\n  using NorthwindDb db = new();\n  if (db.Products is null) return (0, null);\n  \/\/ Get products whose name starts with the parameter value.\n  IQueryable&lt;Product&gt;? products = db.Products.Where(\n    p =&gt; p.ProductName.StartsWith(productNameStartsWith));\n  int affected = products.ExecuteUpdate(s =&gt; s.SetProperty(\n    p =&gt; p.Cost, \/\/ Property selector lambda expression.\n    p =&gt; p.Cost + amount)); \/\/ Value to update to lambda expression.\n  int[] productIds = products.Select(p =&gt; p.ProductId).ToArray();\n  return (affected, productIds);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the statements to delete products, and then add statements to call <code class=\"calibre9\">IncreaseProductPricesBetter<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var resultUpdateBetter = IncreaseProductPricesBetter(\n  productNameStartsWith: \"Bob\", amount: 20M);\nif (resultUpdateBetter.affected &gt; 0)\n{\n  WriteLine(\"Increase product price successful.\");\n}\nListProducts(productIdsToHighlight: resultUpdateBetter.productIds);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Uncomment the statements that add a new product.<\/li>\n<li class=\"calibre3\">Run the console app multiple times and note that, each time, the existing products with the \u201cBob\u201d prefix are each updated with an incrementing cost, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">...\n| 078 | Bob's Burgers                       |  $560.00 |    72 | False |\n| 079 | Bob's Burgers                       |  $540.00 |    72 | False |\n| 080 | Bob's Burgers                       |  $520.00 |    72 | False |<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Modifications.cs<\/code>, add a method to delete any products with a name that begins with a specified value using <code class=\"calibre9\">ExecuteDelete<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static int DeleteProductsBetter(\n  string productNameStartsWith)\n{\n  using NorthwindDb db = new();\n  int affected = 0;\n  IQueryable&lt;Product&gt;? products = db.Products?.Where(\n    p =&gt; p.ProductName.StartsWith(productNameStartsWith));\n  if (products is null || !products.Any())\n  {\n    WriteLine(\"No products found to delete.\");\n    return 0;\n  }\n  else\n  {\n    affected = products.ExecuteDelete();\n  }\n  return affected;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out previous method calls except <code class=\"calibre9\">ConfigureConsole<\/code>, and then add statements to call <code class=\"calibre9\">DeleteProductsBetter<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(\"About to delete all products whose name starts with Bob.\");\nWrite(\"Press Enter to continue or any other key to exit: \");\nif (ReadKey(intercept: true).Key == ConsoleKey.Enter)\n{\n  int deleted = DeleteProductsBetter(productNameStartsWith: \"Bob\");\n  WriteLine($\"{deleted} product(s) were deleted.\");\n}\nelse\n{\n  WriteLine(\"Delete was canceled.\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app and confirm that the products are deleted, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">3 product(s) were deleted.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> If you mix traditional tracked changes with the <code class=\"calibre9\">ExecuteUpdate<\/code> and <code class=\"calibre9\">ExecuteDelete<\/code> methods, then note that they are not kept synchronized. The change tracker will not know what you have updated and deleted using those methods.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"11.7.5\" id=\"calibre_link-602\">\n<h3 data-number=\"11.7.5\" class=\"calibre8\">Pooling database contexts<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">DbContext<\/code> class is disposable and is designed following the single-unit-of-work principle. In the previous code examples, we created all the <code class=\"calibre9\">DbContext<\/code>-derived <code class=\"calibre9\">NorthwindDb<\/code> instances in a <code class=\"calibre9\">using<\/code> block so that <code class=\"calibre9\">Dispose<\/code> is properly called at the end of each unit of work.A feature of ASP.NET Core that is related to EF Core is that it makes your code more efficient by pooling database contexts when building websites and services. This allows you to create and dispose of as many <code class=\"calibre9\">DbContext<\/code>-derived objects as you want, knowing that your code is still as efficient as possible.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"11.8\" id=\"calibre_link-603\">\n<h2 data-number=\"11.8\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring this chapter's topics with deeper research.<\/p>\n<section data-number=\"11.8.1\" id=\"calibre_link-604\">\n<h3 data-number=\"11.8.1\" class=\"calibre8\">Exercise 10.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What type would you use for the property that represents a table, for example, the <code class=\"calibre9\">Products<\/code> property of a database context?<\/li>\n<li class=\"calibre3\">What type would you use for the property that represents a one-to-many relationship, for example, the <code class=\"calibre9\">Products<\/code> property of a <code class=\"calibre9\">Category<\/code> entity?<\/li>\n<li class=\"calibre3\">What is the EF Core convention for primary keys?<\/li>\n<li class=\"calibre3\">When might you use an annotation attribute in an entity class?<\/li>\n<li class=\"calibre3\">Why might you choose the Fluent API in preference to annotation attributes?<\/li>\n<li class=\"calibre3\">What does a transaction isolation level of <code class=\"calibre9\">Serializable<\/code> mean?<\/li>\n<li class=\"calibre3\">What does the <code class=\"calibre9\">DbContext.SaveChanges()<\/code> method return?<\/li>\n<li class=\"calibre3\">What is the difference between eager loading and explicit loading?<\/li>\n<li class=\"calibre3\">How should you define an EF Core entity class to match the following table?<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CREATE TABLE Employees(\n  EmpId INT IDENTITY,\n  FirstName NVARCHAR(40) NOT NULL,\n  Salary MONEY\n)<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">What benefit do you get from declaring entity navigation properties as <code class=\"calibre9\">virtual<\/code>?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"11.8.2\" id=\"calibre_link-605\">\n<h3 data-number=\"11.8.2\" class=\"calibre8\">Exercise 10.2 &ndash; Exporting data using different serialization formats<\/h3>\n<p class=\"rights\">In the <code class=\"calibre9\">Chapter10<\/code> solution, create a console app named <code class=\"calibre9\">Ch10Ex02DataSerialization<\/code> that queries the Northwind database for all the categories and products, and then serializes the data using at least three formats of serialization available to .NET. Which format of serialization uses the least number of bytes?<\/p>\n<\/section>\n<section data-number=\"11.8.3\" id=\"calibre_link-606\">\n<h3 data-number=\"11.8.3\" class=\"calibre8\">Exercise 10.3 &ndash; Working with transactions<\/h3>\n<p class=\"rights\">Add transactions to the modification code: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch10-transactions.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch10-transactions.md<\/a>.<\/p>\n<\/section>\n<section data-number=\"11.8.4\" id=\"calibre_link-607\">\n<h3 data-number=\"11.8.4\" class=\"calibre8\">Exercise 10.4 &ndash; Explore a Code First EF Core model<\/h3>\n<p class=\"rights\">Work through an example of a Code First model that generates an empty database, seeds it with sample data, and then queries the data: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch10-code-first.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch10-code-first.md<\/a>.<\/p>\n<\/section>\n<section data-number=\"11.8.5\" id=\"calibre_link-608\">\n<h3 data-number=\"11.8.5\" class=\"calibre8\">Exercise 10.5 &ndash; Explore app secrets<\/h3>\n<p class=\"rights\">When connecting to a database you often need to include sensitive secret values like a username or password. These values should never be stored in source code or even in a separate file that might be added to a code repository.Secrets should be stored locally during development and in secure systems for production. You can use <strong class=\"calibre2\">Secret Manager<\/strong> during local development and <strong class=\"calibre2\">Azure Key Vault<\/strong> for cloud production systems. To learn more about app secrets, I have written an online-only section that you can read at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch10-app-secrets.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch10-app-secrets.md<\/a><\/p>\n<\/section>\n<section data-number=\"11.8.6\" id=\"calibre_link-609\">\n<h3 data-number=\"11.8.6\" class=\"calibre8\">Exercise 10.6 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more details about the topics covered in this chapter:<\/p>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-10---working-with-data-using-entity-framework-core\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-10---working-with-data-using-entity-framework-core<\/a><\/p>\n<\/section>\n<section data-number=\"11.8.7\" id=\"calibre_link-610\">\n<h3 data-number=\"11.8.7\" class=\"calibre8\">Exercise 10.7 &ndash; Explore NoSQL databases<\/h3>\n<p class=\"rights\">This chapter focused on RDBMSs such as SQL Server and SQLite. If you wish to learn more about NoSQL databases, such as Cosmos DB and MongoDB, and how to use them with EF Core, then I recommend the following links:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Welcome to Azure Cosmos DB<\/strong>: <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/cosmos-db\/introduction\">https:\/\/learn.microsoft.com\/en-us\/azure\/cosmos-db\/introduction<\/a><\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Use NoSQL databases as a persistence infrastructure<\/strong>: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/microservices-architecture\/microservice-ddd-cqrs-patterns\/nosql-database-persistence-infrastructure\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/microservices-architecture\/microservice-ddd-cqrs-patterns\/nosql-database-persistence-infrastructure<\/a><\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Document Database Providers for Entity Framework Core<\/strong>: <a href=\"https:\/\/github.com\/BlueshiftSoftware\/EntityFrameworkCore\">https:\/\/github.com\/BlueshiftSoftware\/EntityFrameworkCore<\/a><\/li>\n<\/ul>\n<\/section>\n<\/section>\n<section data-number=\"11.9\" id=\"calibre_link-611\">\n<h2 data-number=\"11.9\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned how to:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Connect to and build entity data models for an existing database.<\/li>\n<li class=\"calibre3\">Execute a simple LINQ query and process the results.<\/li>\n<li class=\"calibre3\">Use filtered includes.<\/li>\n<li class=\"calibre3\">Control loading and tracking patterns.<\/li>\n<li class=\"calibre3\">Add, modify, and delete data.<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will learn how to write more advanced LINQ queries to select, filter, sort, join, and group.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-6\">\n<div id=\"calibre_link-1937\" class=\"calibre1\">\n<section data-number=\"12\" id=\"calibre_link-612\">\n<h1 data-number=\"12\" class=\"title\">11 Querying and Manipulating Data Using LINQ<\/h1>\n<section data-number=\"12.1\" id=\"calibre_link-613\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"12.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000098.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about <strong class=\"calibre2\">Language INtegrated Query<\/strong> (<strong class=\"calibre2\">LINQ<\/strong>) expressions. LINQ is a set of language extensions that add the ability to work with sequences of data and then filter, sort, and project them into different outputs.This chapter will cover the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Writing LINQ expressions<\/li>\n<li class=\"calibre3\">LINQ in practice<\/li>\n<li class=\"calibre3\">Sorting and more<\/li>\n<li class=\"calibre3\">Using LINQ with EF Core<\/li>\n<li class=\"calibre3\">Joining, grouping, and lookups<\/li>\n<li class=\"calibre3\">Aggregating and paging sequences<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"12.2\" id=\"calibre_link-614\">\n<h2 data-number=\"12.2\" class=\"calibre5\">Writing LINQ expressions<\/h2>\n<p class=\"rights\">The first question we need to answer is a fundamental one: <em class=\"calibre10\">why does LINQ exist?<\/em><\/p>\n<section data-number=\"12.2.1\" id=\"calibre_link-615\">\n<h3 data-number=\"12.2.1\" class=\"calibre8\">Comparing imperative and declarative language features<\/h3>\n<p class=\"rights\">LINQ was introduced in 2008 with C# 3 and .NET Framework 3. Before that, if a C# and .NET programmer wanted to process a sequence of items, they had to use procedural, aka imperative, code statements. For example, a loop:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Set the current position to the first item.<\/li>\n<li class=\"calibre3\">Check if the item is one that should be processed by comparing one or more properties against specified values. For example, is the unit price greater than 50, or is the country equal to Belgium?<\/li>\n<li class=\"calibre3\">If there\u2019s a match, process that item. For example, output one or more of its properties to the user, update one or more properties to new values, delete the item, or perform an aggregate calculation like counting or summing values.<\/li>\n<li class=\"calibre3\">Move on to the next item. Repeat until all items have been processed.<\/li>\n<\/ol>\n<p class=\"rights\">Procedural code tells the compiler <em class=\"calibre10\">how<\/em> to achieve a goal. Do this, then do that. Since the compiler does not know what you are trying to achieve, it cannot help you as much. You are 100% responsible for ensuring that every <em class=\"calibre10\">how-to<\/em> step is correct.LINQ makes these common tasks much easier with less opportunity to introduce subtle bugs. Instead of needing to explicitly state each individual action, like move, read, update, and so on, LINQ enables the programmer to use a declarative aka functional style of writing statements. Declarative, aka functional, code tells the compiler <em class=\"calibre10\">what<\/em> goal to achieve. The compiler works out the best way to achieve the goal. The statements also tend to be more concise.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If you do not fully understand how LINQ works, then the statements you write can introduce their own subtle bugs! A code teaser doing the rounds recently involves a sequence of tasks and understanding when they are executed (<a href=\"https:\/\/twitter.com\/amantinband\/status\/1559187912218099714\">https:\/\/twitter.com\/amantinband\/status\/1559187912218099714<\/a>). Most experienced developers got it wrong! To be fair, it is the combination of LINQ behavior with multi-threading behavior that confused most of them. But by the end of this chapter, you will be better informed to understand why the code was dangerous due to LINQ behavior.<\/p>\n<\/blockquote>\n<p class=\"rights\">Although we wrote a few LINQ expressions in <em class=\"calibre10\">Chapter 10<\/em>, <em class=\"calibre10\">Working with Data Using Entity Framework Core<\/em>, they weren't the focus, so I didn't properly explain how LINQ works. Let's now take time to properly understand them.<\/p>\n<\/section>\n<section data-number=\"12.2.2\" id=\"calibre_link-616\">\n<h3 data-number=\"12.2.2\" class=\"calibre8\">LINQ components<\/h3>\n<p class=\"rights\">LINQ has several parts; some are required, and some are optional:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Extension methods<\/strong> (<strong class=\"calibre2\">required<\/strong>): These include examples such as <code class=\"calibre9\">Where<\/code>, <code class=\"calibre9\">OrderBy<\/code>, and <code class=\"calibre9\">Select<\/code>. These are what provide the functionality of LINQ.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">LINQ providers<\/strong> (<strong class=\"calibre2\">required<\/strong>): These include <strong class=\"calibre2\">LINQ to Objects<\/strong> for processing in-memory objects, <strong class=\"calibre2\">LINQ to Entities<\/strong> for processing data stored in external databases and modeled with EF Core, and <strong class=\"calibre2\">LINQ to XML<\/strong> for processing data stored as XML. These providers are the part of LINQ that executes LINQ expressions in a way specific to different types of data.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Lambda expressions<\/strong> (<strong class=\"calibre2\">optional<\/strong>): These can be used instead of named methods to simplify LINQ queries, for example, for the conditional logic of the <code class=\"calibre9\">Where<\/code> method for filtering.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">LINQ query comprehension syntax<\/strong> (<strong class=\"calibre2\">optional<\/strong>): These include C# keywords like <code class=\"calibre9\">from<\/code>, <code class=\"calibre9\">in<\/code>, <code class=\"calibre9\">where<\/code>, <code class=\"calibre9\">orderby<\/code>, <code class=\"calibre9\">descending<\/code>, and <code class=\"calibre9\">select<\/code>. These are aliases for some of the LINQ extension methods, and their use can simplify the queries you write, especially if you already have experience with other query languages, such as <strong class=\"calibre2\">Structured Query Language<\/strong> (<strong class=\"calibre2\">SQL<\/strong>).<\/li>\n<\/ul>\n<p class=\"rights\">When programmers are first introduced to LINQ, they often believed that LINQ query comprehension syntax was LINQ but, ironically, that is one of the parts of LINQ that is optional!<\/p>\n<\/section>\n<section data-number=\"12.2.3\" id=\"calibre_link-617\">\n<h3 data-number=\"12.2.3\" class=\"calibre8\">Building LINQ expressions with the Enumerable class<\/h3>\n<p class=\"rights\">The LINQ extension methods, such as <code class=\"calibre9\">Where<\/code> and <code class=\"calibre9\">Select<\/code>, are appended by the <code class=\"calibre9\">Enumerable<\/code> static class to any type, known as a <strong class=\"calibre2\">sequence<\/strong>, that implements <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code>. A sequence contains zero, one, or more items.For example, an array of any type implements the <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> class, where <code class=\"calibre9\">T<\/code> is the type of item in the array. This means that all arrays support LINQ to query and manipulate them.All generic collections, such as <code class=\"calibre9\">List&lt;T&gt;<\/code>, <code class=\"calibre9\">Dictionary&lt;TKey, TValue&gt;<\/code>, <code class=\"calibre9\">Stack&lt;T&gt;<\/code>, and <code class=\"calibre9\">Queue&lt;T&gt;<\/code>, implement <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code>, so they can be queried and manipulated with LINQ too.<code class=\"calibre9\">Enumerable<\/code> defines more than 50 extension methods, as summarized in <em class=\"calibre10\">Table 11.1<\/em>:<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">This table will be useful for you for future reference, but for now, you might want to briefly scan it to get a feel for what extension methods exist and come back later to review it properly. An online version of this table is available at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch11-linq-methods.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch11-linq-methods.md<\/a>.<\/p>\n<\/blockquote>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Method(s)<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">First<\/code> , <code class=\"calibre9\">FirstOrDefault<\/code> , <code class=\"calibre9\">Last<\/code> , <code class=\"calibre9\">LastOrDefault<\/code><\/td>\n<td class=\"calibre21\">Get the first or last item in the sequence or throw an exception, or return the default value for the type, for example, <code class=\"calibre9\">0<\/code> for an <code class=\"calibre9\">int<\/code> and <code class=\"calibre9\">null<\/code> for a reference type, if there is not a first or last item.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Where<\/code><\/td>\n<td class=\"calibre21\">Return a sequence of items that match a specified filter.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Single<\/code> , <code class=\"calibre9\">SingleOrDefault<\/code><\/td>\n<td class=\"calibre21\">Return an item that matches a specific filter or throw an exception, or return the default value for the type if there is not exactly one match.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ElementAt<\/code> , <code class=\"calibre9\">ElementAtOrDefault<\/code><\/td>\n<td class=\"calibre21\">Return an item at a specified index position or throw an exception, or return the default value for the type if there is not an item at that position. New in .NET 6 are overloads that can be passed an <code class=\"calibre9\">Index<\/code> instead of an <code class=\"calibre9\">int<\/code> , which is more efficient when working with <code class=\"calibre9\">Span&lt;T&gt;<\/code> sequences.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Select<\/code> , <code class=\"calibre9\">SelectMany<\/code><\/td>\n<td class=\"calibre21\">Project items into a different shape, that is, a different type, and flatten a nested hierarchy of items.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">OrderBy<\/code> , <code class=\"calibre9\">OrderByDescending<\/code> , <code class=\"calibre9\">ThenBy<\/code> , <code class=\"calibre9\">ThenByDescending<\/code><\/td>\n<td class=\"calibre21\">Sort items by a specified field or property.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Order<\/code> , <code class=\"calibre9\">OrderDescending<\/code><\/td>\n<td class=\"calibre21\">Sort items by the item itself.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Reverse<\/code><\/td>\n<td class=\"calibre21\">Reverse the order of the items.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">GroupBy<\/code> , <code class=\"calibre9\">GroupJoin<\/code> , <code class=\"calibre9\">Join<\/code><\/td>\n<td class=\"calibre21\">Group and\/or join two sequences.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Skip<\/code> , <code class=\"calibre9\">SkipWhile<\/code><\/td>\n<td class=\"calibre21\">Skip a number of items; or skip when an expression is <code class=\"calibre9\">true<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Take<\/code> , <code class=\"calibre9\">TakeWhile<\/code><\/td>\n<td class=\"calibre21\">Take a number of items, or take items while an expression is <code class=\"calibre9\">true<\/code> . Introduced in .NET 6 is an overload that can be passed a <code class=\"calibre9\">Range<\/code> , for example, <code class=\"calibre9\">Take(range: 3..^5)<\/code> , meaning take a subset starting 3 items in from the start and ending 5 items in from the end, or instead of <code class=\"calibre9\">Skip(4)<\/code> you could use <code class=\"calibre9\">Take(4..)<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Aggregate<\/code> , <code class=\"calibre9\">Average<\/code> , <code class=\"calibre9\">Count<\/code> , <code class=\"calibre9\">LongCount<\/code> , <code class=\"calibre9\">Max<\/code> , <code class=\"calibre9\">Min<\/code> , <code class=\"calibre9\">Sum<\/code><\/td>\n<td class=\"calibre21\">Calculate aggregate values.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">TryGetNonEnumeratedCount<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">Count()<\/code> checks if a <code class=\"calibre9\">Count<\/code> property is implemented on the sequence and returns its value, or it enumerates the entire sequence to count its items. Introduced in .NET 6, this method only checks for <code class=\"calibre9\">Count<\/code> ; if it is missing, it returns <code class=\"calibre9\">false<\/code> and sets the <code class=\"calibre9\">out<\/code> parameter to <code class=\"calibre9\">0<\/code> to avoid a potentially poor-performing operation.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">All<\/code> , <code class=\"calibre9\">Any<\/code> , <code class=\"calibre9\">Contains<\/code><\/td>\n<td class=\"calibre21\">Return <code class=\"calibre9\">true<\/code> if all or any of the items match the filter, or if the sequence contains a specified item.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Cast&lt;T&gt;<\/code><\/td>\n<td class=\"calibre21\">Cast items into a specified type. It is useful to convert non-generic objects to a generic type in scenarios where the compiler would otherwise complain.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">OfType&lt;T&gt;<\/code><\/td>\n<td class=\"calibre21\">Remove items that do not match a specified type.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Distinct<\/code><\/td>\n<td class=\"calibre21\">Remove duplicate items.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Except<\/code> , <code class=\"calibre9\">Intersect<\/code> , <code class=\"calibre9\">Union<\/code><\/td>\n<td class=\"calibre21\">Perform operations that return sets. Sets cannot have duplicate items. Although the inputs can be any sequence and so the inputs can have duplicates, the result is always a set.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">DistinctBy<\/code> , <code class=\"calibre9\">ExceptBy<\/code> , <code class=\"calibre9\">IntersectBy<\/code> , <code class=\"calibre9\">UnionBy<\/code> , <code class=\"calibre9\">MinBy<\/code> , <code class=\"calibre9\">MaxBy<\/code><\/td>\n<td class=\"calibre21\">Allow the comparison to be performed on a subset of the items rather than the entire items. For example, instead of removing duplicates with <code class=\"calibre9\">Distinct<\/code> by comparing an entire <code class=\"calibre9\">Person<\/code> object, you could remove duplicates with <code class=\"calibre9\">DistinctBy<\/code> by comparing just their <code class=\"calibre9\">LastName<\/code> and <code class=\"calibre9\">DateOfBirth<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Chunk<\/code><\/td>\n<td class=\"calibre21\">Divide a sequence into sized batches. The <code class=\"calibre9\">size<\/code> parameter specified the number of items in each chunk. The last chunk will contain the remaining items and could be less than <code class=\"calibre9\">size<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Append<\/code> , <code class=\"calibre9\">Concat<\/code> , <code class=\"calibre9\">Prepend<\/code><\/td>\n<td class=\"calibre21\">Perform sequence-combining operations.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Zip<\/code><\/td>\n<td class=\"calibre21\">Perform a match operation on two or three sequences based on the position of items, for example, the item at position 1 in the first sequence matches the item at position 1 in the second sequence.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ToArray<\/code> , <code class=\"calibre9\">ToList<\/code> , <code class=\"calibre9\">ToDictionary<\/code> , <code class=\"calibre9\">ToHashSet<\/code> , <code class=\"calibre9\">ToLookup<\/code><\/td>\n<td class=\"calibre21\">Convert the sequence into an array or collection. These are the only extension methods that force the execution of a LINQ expression immediately rather than wait for deferred execution, which you will learn about shortly.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 11.1: LINQ extension methods<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Make sure that you understand and remember the difference between LINQ extension methods that start with <code class=\"calibre9\">As<\/code> and <code class=\"calibre9\">To<\/code>. Methods that start with <code class=\"calibre9\">As<\/code>, like <code class=\"calibre9\">AsEnumerable<\/code>, cast the sequence into a different type but do not allocate memory so those methods are fast. Methods that start with <code class=\"calibre9\">To<\/code>, like <code class=\"calibre9\">ToList<\/code>, allocate memory for a new sequence of items so can be slow and will always use more memory resources.<\/p>\n<\/blockquote>\n<p class=\"rights\">The <code class=\"calibre9\">Enumerable<\/code> class also has some methods that are not extension methods, as shown in <em class=\"calibre10\">Table 11.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Method<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Empty&lt;T&gt;<\/code><\/td>\n<td class=\"calibre21\">Returns an empty sequence of the specified type <code class=\"calibre9\">T<\/code> . It is useful for passing an empty sequence to a method that requires an <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Range<\/code><\/td>\n<td class=\"calibre21\">Returns a sequence of integers from the <code class=\"calibre9\">start<\/code> value with <code class=\"calibre9\">count<\/code> items. For example, <code class=\"calibre9\">Enumerable.Range(start: 5, count: 3)<\/code> would contain the integers 5, 6, and 7.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Repeat<\/code><\/td>\n<td class=\"calibre21\">Returns a sequence that contains the same element repeated <code class=\"calibre9\">count<\/code> times. For example, <code class=\"calibre9\">Enumerable.Repeat(element: \"5\", count: 3)<\/code> would contain the <code class=\"calibre9\">string<\/code> values <code class=\"calibre9\">\"5\"<\/code> , <code class=\"calibre9\">\"5\"<\/code> , and <code class=\"calibre9\">\"5\"<\/code> .<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 11.2: Enumerable non-extension methods<br \/>\n<\/section>\n<\/section>\n<section data-number=\"12.3\" id=\"calibre_link-618\">\n<h2 data-number=\"12.3\" class=\"calibre5\">LINQ in practice<\/h2>\n<p class=\"rights\">Now we can build a console app to explore practical examples of using LINQ.<\/p>\n<section data-number=\"12.3.1\" id=\"calibre_link-619\">\n<h3 data-number=\"12.3.1\" class=\"calibre8\">Understanding deferred execution<\/h3>\n<p class=\"rights\">LINQ uses <strong class=\"calibre2\">deferred execution<\/strong>. It is important to understand that calling most of the above extension methods does not execute the query and get the results. Most of these extension methods return a LINQ expression that represents a <em class=\"calibre10\">question<\/em>, not an <em class=\"calibre10\">answer<\/em>. Let's explore:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to create a new project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">LinqWithObjects<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">Chapter11<\/code><\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In the project file, globally and statically import the <code class=\"calibre9\">System.Console<\/code> class.<\/li>\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Program.Helpers.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Helpers.cs<\/code>, delete any existing statements and then define a partial <code class=\"calibre9\">Program<\/code> class with a method to output a section title, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">partial class Program\n{\n  private static void SectionTitle(string title)\n  {\n    ConsoleColor previousColor = ForegroundColor;\n    ForegroundColor = ConsoleColor.DarkYellow;\n    WriteLine($\"*** {title} ***\");\n    ForegroundColor = previousColor;\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a new class file named <code class=\"calibre9\">Program.Functions.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, delete any existing statements and then define a partial <code class=\"calibre9\">Program<\/code> class with a method named <code class=\"calibre9\">DeferredExecution<\/code> that is passed an array of <code class=\"calibre9\">string<\/code> values, and then define two queries, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">partial class Program\n{\n  private static void DeferredExecution(string[] names)\n  {\n    SectionTitle(\"Deferred execution\");\n    \/\/ Question: Which names end with an M?\n    \/\/ (using a LINQ extension method)\n    var query1 = names.Where(name =&gt; name.EndsWith(\"m\"));\n    \/\/ Question: Which names end with an M?\n    \/\/ (using LINQ query comprehension syntax)\n    var query2 = from name in names where name.EndsWith(\"m\") select name;\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete the existing statements and then add statements to define a sequence of <code class=\"calibre9\">string<\/code> values for people who work in an office, and then pass it as an argument to the <code class=\"calibre9\">DeferredExecution<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ A string array is a sequence that implements IEnumerable&lt;string&gt;.\nstring[] names = { \"Michael\", \"Pam\", \"Jim\", \"Dwight\", \n  \"Angela\", \"Kevin\", \"Toby\", \"Creed\" };\nDeferredExecution(names);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, in the <code class=\"calibre9\">DeferredExecution<\/code> method, to get the answer &ndash; in other words, to execute the query &ndash; you must <strong class=\"calibre2\">materialize<\/strong> it by either calling one of the \"To\" methods like <code class=\"calibre9\">ToArray<\/code>, <code class=\"calibre9\">ToDictionary<\/code>, or <code class=\"calibre9\">ToLookup<\/code>, or by enumerating the query. Add statements to do this, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Answer returned as an array of strings containing Pam and Jim.\nstring[] result1 = query1.ToArray();\n\/\/ Answer returned as a list of strings containing Pam and Jim.\nList&lt;string&gt; result2 = query2.ToList();\n\/\/ Answer returned as we enumerate over the results.\nforeach (string name in query1)\n{\n  WriteLine(name); \/\/ outputs Pam\n  names[2] = \"Jimmy\"; \/\/ Change Jim to Jimmy.\n  \/\/ On the second iteration Jimmy does not \n  \/\/ end with an \"m\" so it does not get output.\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the console app and note the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">*** Deferred execution ***\nPam<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Due to deferred execution, after outputting the first result, <code class=\"calibre9\">Pam<\/code>, if the original array values change, then by the time we loop back around, there are no more matches because <code class=\"calibre9\">Jim<\/code> has become <code class=\"calibre9\">Jimmy<\/code> and does not end with an <code class=\"calibre9\">m<\/code>, so only <code class=\"calibre9\">Pam<\/code> is output.Before we get too deep into the weeds, let's slow down and look at some common LINQ extension methods and how to use them, one at a time.<\/p>\n<\/section>\n<section data-number=\"12.3.2\" id=\"calibre_link-620\">\n<h3 data-number=\"12.3.2\" class=\"calibre8\">Filtering entities using Where<\/h3>\n<p class=\"rights\">The most common reason for using LINQ is to filter items in a sequence using the <code class=\"calibre9\">Where<\/code> extension method. Let's explore filtering by defining a sequence of names and then applying LINQ operations to it:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the project file, add an element to remove the <code class=\"calibre9\">System.Linq<\/code> namespace from automatically being imported globally, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n  &lt;Using Remove=\"System.Linq\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, add a new method named <code class=\"calibre9\">FilteringUsingWhere<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void FilteringUsingWhere(string[] names)\n{\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you are using Visual Studio 2022, navigate to <strong class=\"calibre2\">Tools<\/strong> | <strong class=\"calibre2\">Options<\/strong>, in the <strong class=\"calibre2\">Options<\/strong> dialog box, navigate to <strong class=\"calibre2\">Text Editor<\/strong> | <strong class=\"calibre2\">C#<\/strong> | <strong class=\"calibre2\">IntelliSense<\/strong>, clear the <strong class=\"calibre2\">Show items from unimported namespaces<\/strong> check box, and then click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">FilteringUsingWhere<\/code>, attempt to call the <code class=\"calibre9\">Where<\/code> extension method on the array of names, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SectionTitle(\"Filtering entities using Where\");\nvar query = names.W<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">As you type the <code class=\"calibre9\">W<\/code>, note that in older code editors (or code editors with the option to show items from unimported namespaces is disabled) the <code class=\"calibre9\">Where<\/code> method is missing from the IntelliSense list of members of a <code class=\"calibre9\">string<\/code> array, as shown in <em class=\"calibre10\">Figure 11.1<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 11.1: IntelliSense with the Where extension method missing\" height=\"777\" src=\"\/images\/cs12\/000116.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 11.1: IntelliSense with the Where extension method missing<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">This is because <code class=\"calibre9\">Where<\/code> is an extension method. It does not exist on the array type. To make the <code class=\"calibre9\">Where<\/code> extension method available, we must import the <code class=\"calibre9\">System.Linq<\/code> namespace. This is implicitly imported by default in new .NET 6 and later projects, but we removed it to illustrate the point. Recent versions of code editors are smart enough to suggest using the <code class=\"calibre9\">Where<\/code> method anyway and indicate that they will import the <code class=\"calibre9\">System.Linq<\/code> namespace for you automatically.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">If you are using Visual Studio 2022, navigate to <strong class=\"calibre2\">Tools<\/strong> | <strong class=\"calibre2\">Options<\/strong>, in the <strong class=\"calibre2\">Options<\/strong> dialog box, navigate to <strong class=\"calibre2\">Text Editor<\/strong> | <strong class=\"calibre2\">C#<\/strong> | <strong class=\"calibre2\">IntelliSense<\/strong>, select the <strong class=\"calibre2\">Show items from unimported namespaces<\/strong> check box, and then click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<li class=\"calibre3\">In the project file, comment out the element that removed <code class=\"calibre9\">System.Linq<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;!--&lt;Using Remove=\"System.Linq\" \/&gt;--&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Save the change and build the project.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Retype the <code class=\"calibre9\">W<\/code> for the <code class=\"calibre9\">Where<\/code> method and note that the IntelliSense list now includes the extension methods added by the <code class=\"calibre9\">Enumerable<\/code> class, as shown in <em class=\"calibre10\">Figure 11.2<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 11.2: IntelliSense showing LINQ extension methods when System.Linq is imported\" height=\"777\" src=\"\/images\/cs12\/000032.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 11.2: IntelliSense showing LINQ extension methods when System.Linq is imported<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Interestingly, as you can see in the screenshot of Visual Studio 2022 on my computer, GitHub Copilot is even suggesting autocompleting with a lambda expression very similar to the one that we will eventually end up writing. But there are some important intermediate steps you need to see before we get to that so do not press <span>Tab<\/span>, <span>Tab<\/span> to insert any GitHub Copilot suggestions if you have that feature enabled.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">As you type the parentheses for the <code class=\"calibre9\">Where<\/code> method, IntelliSense tells us that, to call <code class=\"calibre9\">Where<\/code>, we must pass in an instance of a <code class=\"calibre9\">Func&lt;string, bool&gt;<\/code> delegate.<\/li>\n<li class=\"calibre3\">Enter an expression to create a new instance of a <code class=\"calibre9\">Func&lt;string, bool&gt;<\/code> delegate, and for now note that we have not yet supplied a method name because we will define it in the next step, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var query = names.Where(new Func&lt;string, bool&gt;( ))<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Leave the statement unfinished for now.<\/li>\n<\/ol>\n<p class=\"rights\">The <code class=\"calibre9\">Func&lt;string, bool&gt;<\/code> delegate tells us that for each <code class=\"calibre9\">string<\/code> variable passed to the method, the method must return a <code class=\"calibre9\">bool<\/code> value. If the method returns <code class=\"calibre9\">true<\/code>, it indicates that we should include the <code class=\"calibre9\">string<\/code> in the results, and if the method returns <code class=\"calibre9\">false<\/code>, it indicates that we should exclude it.<\/p>\n<\/section>\n<section data-number=\"12.3.3\" id=\"calibre_link-621\">\n<h3 data-number=\"12.3.3\" class=\"calibre8\">Targeting a named method<\/h3>\n<p class=\"rights\">Let's define a method that only includes names that are longer than four characters:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, add a method that will return <code class=\"calibre9\">true<\/code> only for names longer than four characters, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static bool NameLongerThanFour(string name)\n{\n  \/\/ Returns true for a name longer than four characters.\n  return name.Length &gt; 4;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">FilteringUsingWhere<\/code> method, pass the method's name into the <code class=\"calibre9\">Func&lt;string, bool&gt;<\/code> delegate, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var query = names.Where(\n  new Func&lt;string, bool&gt;(NameLongerThanFour));<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">FilteringUsingWhere<\/code> method, add statements to enumerate the <code class=\"calibre9\">names<\/code> array using <code class=\"calibre9\">foreach<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">foreach (string item in query)\n{\n  WriteLine(item);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the call to <code class=\"calibre9\">DeferredExecution<\/code> and then pass <code class=\"calibre9\">names<\/code> as an argument to the <code class=\"calibre9\">FilteringUsingWhere<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ DeferredExecution(names);\nFilteringUsingWhere(names);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the results, noting that only names longer than four letters are listed, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Michael \nDwight \nAngela \nKevin \nCreed<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"12.3.4\" id=\"calibre_link-622\">\n<h3 data-number=\"12.3.4\" class=\"calibre8\">Simplifying the code by removing the explicit delegate instantiation<\/h3>\n<p class=\"rights\">We can simplify the code by deleting the explicit instantiation of the <code class=\"calibre9\">Func&lt;string, bool&gt;<\/code> delegate because the C# compiler can instantiate the delegate for us:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">To help you learn by seeing progressively improved code, in the <code class=\"calibre9\">FilteringUsingWhere<\/code> method, comment out the query and add a comment about how it works, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Explicitly creating the required delegate.\n\/\/ var query = names.Where(\n\/\/   new Func&lt;string, bool&gt;(NameLongerThanFour));<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Enter the query a second time, but this time without the explicit instantiation of the delegate, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ The compiler creates the delegate automatically.\nvar query = names.Where(NameLongerThanFour);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note that it has the same behavior.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"12.3.5\" id=\"calibre_link-623\">\n<h3 data-number=\"12.3.5\" class=\"calibre8\">Targeting a lambda expression<\/h3>\n<p class=\"rights\">We can simplify our code even further using a <strong class=\"calibre2\">lambda expression<\/strong> in place of a named method.Although it can look complicated at first, a lambda expression is simply a <em class=\"calibre10\">nameless function<\/em>. It uses the <code class=\"calibre9\">=&gt;<\/code> (read as \"goes to\") symbol to indicate the return value:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Comment out the second query, and then add a third version of the query that uses a lambda expression, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Using a lambda expression instead of a named method.\nvar query = names.Where(name =&gt; name.Length &gt; 4);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note that the syntax for a lambda expression includes all the important parts of the <code class=\"calibre9\">NameLongerThanFour<\/code> method, but nothing more. A lambda expression only needs to define the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The names of input parameters: <code class=\"calibre9\">name<\/code><\/li>\n<li class=\"calibre3\">A return value expression: <code class=\"calibre9\">name.Length &gt; 4<\/code><\/li>\n<\/ul>\n<p class=\"rights\">The type of the <code class=\"calibre9\">name<\/code> input parameter is inferred from the fact that the sequence contains <code class=\"calibre9\">string<\/code> values, and the return type must be a <code class=\"calibre9\">bool<\/code> value as defined by the delegate for <code class=\"calibre9\">Where<\/code> to work, so the expression after the <code class=\"calibre9\">=&gt;<\/code> symbol must return a <code class=\"calibre9\">bool<\/code> value. The compiler does most of the work for us, so our code can be as concise as possible.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note that it has the same behavior.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"12.3.6\" id=\"calibre_link-624\">\n<h3 data-number=\"12.3.6\" class=\"calibre8\">Lambda expressions with default parameter values<\/h3>\n<p class=\"rights\">Introduced with C# 12, you can now provide default values for parameters in lambda expressions, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var query = names.Where((string name = \"Bob\") =&gt; name.Length &gt; 4);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">For what we are using this lambda expression for, setting a default value is not necessary, but later you will see more useful examples.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"12.4\" id=\"calibre_link-625\">\n<h2 data-number=\"12.4\" class=\"calibre5\">Sorting and more<\/h2>\n<p class=\"rights\">Other commonly used extension methods are <code class=\"calibre9\">OrderBy<\/code> and <code class=\"calibre9\">ThenBy<\/code>, used for sorting a sequence.<\/p>\n<section data-number=\"12.4.1\" id=\"calibre_link-626\">\n<h3 data-number=\"12.4.1\" class=\"calibre8\">Sorting by a single property using OrderBy<\/h3>\n<p class=\"rights\">Extension methods can be chained if the previous method returns another sequence, that is, a type that implements the <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> interface.Let's continue working with the current project to explore sorting:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">FilteringUsingWhere<\/code> method, append a call to <code class=\"calibre9\">OrderBy<\/code> to the end of the existing query, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var query = names\n  .Where(name =&gt; name.Length &gt; 4)\n  .OrderBy(name =&gt; name.Length);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Format the LINQ statement so that each extension method call happens on its own line, to make it easier to read.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note that the names are now sorted by shortest first, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Kevin \nCreed \nDwight \nAngela \nMichael<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To put the longest name first, you would use <code class=\"calibre9\">OrderByDescending<\/code>.<\/p>\n<\/section>\n<section data-number=\"12.4.2\" id=\"calibre_link-627\">\n<h3 data-number=\"12.4.2\" class=\"calibre8\">Sorting by a subsequent property using ThenBy<\/h3>\n<p class=\"rights\">We might want to sort by more than one property, for example, to sort names of the same length in alphabetical order:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">FilteringUsingWhere<\/code> method, append a call to the <code class=\"calibre9\">ThenBy<\/code> method at the end of the existing query, as highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var query = names\n  .Where(name =&gt; name.Length &gt; 4)\n  .OrderBy(name =&gt; name.Length)\n  .ThenBy(name =&gt; name);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note the slight difference in the following sort order. Within a group of names of the same length, the names are sorted alphabetically by the full value of the <code class=\"calibre9\">string<\/code>, so <code class=\"calibre9\">Creed<\/code> comes before <code class=\"calibre9\">Kevin<\/code>, and <code class=\"calibre9\">Angela<\/code> comes before <code class=\"calibre9\">Dwight<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Creed\nKevin\nAngela\nDwight\nMichael<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"12.4.3\" id=\"calibre_link-628\">\n<h3 data-number=\"12.4.3\" class=\"calibre8\">Sorting by the item itself<\/h3>\n<p class=\"rights\">Introduced in .NET 7 are the <code class=\"calibre9\">Order<\/code> and <code class=\"calibre9\">OrderDescending<\/code> extension methods. These simplify ordering by the item itself. For example, if you have a sequence of <code class=\"calibre9\">string<\/code> values, then before .NET 7 you would have to call the <code class=\"calibre9\">OrderBy<\/code> method and pass a lambda that selects the items themselves, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var query = names.OrderBy(name =&gt; name);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">With .NET 7 or later, we can simplify the statement, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var query = names.Order();<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><code class=\"calibre9\">OrderDescending<\/code> does a similar thing but in descending order.Remember that the <code class=\"calibre9\">names<\/code> array contains instances of the <code class=\"calibre9\">string<\/code> type, which implements the <code class=\"calibre9\">IComparable<\/code> interface. This is why they can be ordered, aka sorted. If the array contained instances of a complex type like <code class=\"calibre9\">Person<\/code> or <code class=\"calibre9\">Product<\/code>, then those types would have to implement the <code class=\"calibre9\">IComparable<\/code> interface so they could be ordered too.<\/p>\n<\/section>\n<section data-number=\"12.4.4\" id=\"calibre_link-629\">\n<h3 data-number=\"12.4.4\" class=\"calibre8\">Declaring a query using var or a specified type<\/h3>\n<p class=\"rights\">While writing a LINQ expression, it is convenient to use <code class=\"calibre9\">var<\/code> to declare the query object. This is because the return type frequently changes as you work on a LINQ expression. For example, our query started as an <code class=\"calibre9\">IEnumerable&lt;string&gt;<\/code> and is currently an <code class=\"calibre9\">IOrderedEnumerable&lt;string&gt;<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Hover your mouse over the <code class=\"calibre9\">var<\/code> keyword and note that its type is <code class=\"calibre9\">IOrderedEnumerable&lt;string&gt;<\/code>, as shown in <em class=\"calibre10\">Figure 11.3<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 11.3: Hover over var to see the actual implied type of the query expression\" height=\"717\" src=\"\/images\/cs12\/000051.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 11.3: Hover over var to see the actual implied type of the query expression<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In <em class=\"calibre10\">Figure 11.3<\/em>, I added extra vertical space between <code class=\"calibre9\">names<\/code> and <code class=\"calibre9\">.Where<\/code> so that the tooltip did not cover up the query.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Replace <code class=\"calibre9\">var<\/code> with the actual type, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">IOrderedEnumerable&lt;string&gt; query = names\n  .Where(name =&gt; name.Length &gt; 4)\n  .OrderBy(name =&gt; name.Length)\n  .ThenBy(name =&gt; name);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good practice<\/strong>: Once you have finished working on a query, you could change the declared type from <code class=\"calibre9\">var<\/code> to the actual type to make it clearer what the type is. This is easy because your code editor can tell you what it is. Doing this is just for clarity. It has no effect on performance because C# changes all <code class=\"calibre9\">var<\/code> declarations to the actual types at compile time.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note that it has the same behavior.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"12.4.5\" id=\"calibre_link-630\">\n<h3 data-number=\"12.4.5\" class=\"calibre8\">Filtering by type<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">Where<\/code> extension method is great for filtering by values, such as text and numbers. But what if the sequence contains multiple types, and you want to filter by a specific type and respect any inheritance hierarchy?Imagine that you have a sequence of exceptions. There are hundreds of exception types that form a complex inheritance hierarchy, as partially shown in <em class=\"calibre10\">Figure 11.4<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 11.4: A partial exception inheritance hierarchy\" height=\"260\" src=\"\/images\/cs12\/000066.png\" width=\"927\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 11.4: A partial exception inheritance hierarchy<\/figcaption><\/figure>\n<p class=\"rights\">Let's explore filtering by type:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, define a new method to list and then filter exception-derived objects using the <code class=\"calibre9\">OfType&lt;T&gt;<\/code> extension method to remove exceptions that are not arithmetic exceptions and write only the arithmetic exceptions to the console, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void FilteringByType()\n{\n  SectionTitle(\"Filtering by type\");\n  List&lt;Exception&gt; exceptions = new()\n  {\n    new ArgumentException(), new SystemException(),\n    new IndexOutOfRangeException(), new InvalidOperationException(),\n    new NullReferenceException(), new InvalidCastException(),\n    new OverflowException(), new DivideByZeroException(),\n    new ApplicationException()\n  };\n  IEnumerable&lt;ArithmeticException&gt; arithmeticExceptionsQuery = \n    exceptions.OfType&lt;ArithmeticException&gt;();\n  foreach (ArithmeticException exception in arithmeticExceptionsQuery)\n  {\n    WriteLine(exception);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the call to <code class=\"calibre9\">FilteringUsingWhere<\/code>, and then add a call to the <code class=\"calibre9\">FilteringByType<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ FilteringUsingWhere(names);\nFilteringByType();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and note that the results only include exceptions of the <code class=\"calibre9\">ArithmeticException<\/code> type, or the <code class=\"calibre9\">ArithmeticException<\/code>-derived types, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">System.OverflowException: Arithmetic operation resulted in an overflow.\nSystem.DivideByZeroException: Attempted to divide by zero.<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"12.4.6\" id=\"calibre_link-631\">\n<h3 data-number=\"12.4.6\" class=\"calibre8\">Working with sets and bags<\/h3>\n<p class=\"rights\">Sets are one of the most fundamental concepts in mathematics. A <strong class=\"calibre2\">set<\/strong> is a collection of one or more unique objects. A <strong class=\"calibre2\">multiset<\/strong>, aka a <strong class=\"calibre2\">bag<\/strong>, is a collection of one or more objects that can have duplicates.You might remember being taught about Venn diagrams in school. Common set operations include the <strong class=\"calibre2\">intersect<\/strong> or <strong class=\"calibre2\">union<\/strong> between sets.Let's write some code that will define three arrays of <code class=\"calibre9\">string<\/code> values for cohorts of apprentices and then perform some common set and multiset operations on them:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, add a method that outputs any sequence of <code class=\"calibre9\">string<\/code> variables as a comma-separated single <code class=\"calibre9\">string<\/code> to the console output, along with an optional description, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void Output(IEnumerable&lt;string&gt; cohort, string description = \"\")\n{\n  if (!string.IsNullOrEmpty(description))\n  {\n    WriteLine(description);\n  }\n  Write(\" \");\n  WriteLine(string.Join(\", \", cohort.ToArray()));\n  WriteLine();\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, add a method that defines three arrays of names, outputs them, and then performs various set operations on them, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">static void WorkingWithSets()\n{\n  string[] cohort1 =\n    { \"Rachel\", \"Gareth\", \"Jonathan\", \"George\" };\n  string[] cohort2 =\n    { \"Jack\", \"Stephen\", \"Daniel\", \"Jack\", \"Jared\" };\n  string[] cohort3 =\n    { \"Declan\", \"Jack\", \"Jack\", \"Jasmine\", \"Conor\" };\n  SectionTitle(\"The cohorts\");\n  Output(cohort1, \"Cohort 1\");\n  Output(cohort2, \"Cohort 2\");\n  Output(cohort3, \"Cohort 3\");\n  SectionTitle(\"Set operations\");\n  Output(cohort2.Distinct(), \"cohort2.Distinct()\"); \n  Output(cohort2.DistinctBy(name =&gt; name.Substring(0, 2)), \n    \"cohort2.DistinctBy(name =&gt; name.Substring(0, 2)):\");\n  Output(cohort2.Union(cohort3), \"cohort2.Union(cohort3)\"); \n  Output(cohort2.Concat(cohort3), \"cohort2.Concat(cohort3)\"); \n  Output(cohort2.Intersect(cohort3), \"cohort2.Intersect(cohort3)\"); \n  Output(cohort2.Except(cohort3), \"cohort2.Except(cohort3)\"); \n  Output(cohort1.Zip(cohort2,(c1, c2) =&gt; $\"{c1} matched with {c2}\"), \n    \"cohort1.Zip(cohort2)\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the call to <code class=\"calibre9\">FilteringByType<\/code>, and then add a call to the <code class=\"calibre9\">WorkingWithSets<\/code> method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ FilteringByType();\nWorkingWithSets();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Cohort 1\n  Rachel, Gareth, Jonathan, George \nCohort 2\n  Jack, Stephen, Daniel, Jack, Jared \nCohort 3\n  Declan, Jack, Jack, Jasmine, Conor\ncohort2.Distinct()\n  Jack, Stephen, Daniel, Jared \ncohort2.DistinctBy(name =&gt; name.Substring(0, 2)):\n  Jack, Stephen, Daniel \ncohort2.Union(cohort3)\n  Jack, Stephen, Daniel, Jared, Declan, Jasmine, Conor \ncohort2.Concat(cohort3)\n  Jack, Stephen, Daniel, Jack, Jared, Declan, Jack, Jack, Jasmine, Conor \ncohort2.Intersect(cohort3)\n  Jack \ncohort2.Except(cohort3)\n  Stephen, Daniel, Jared \ncohort1.Zip(cohort2)\n  Rachel matched with Jack, Gareth matched with Stephen, Jonathan matched with Daniel, George matched with Jack<\/code><\/pre>\n<\/div>\n<p class=\"rights\">With <code class=\"calibre9\">Zip<\/code>, if there are unequal numbers of items in the two sequences, then some items will not have a matching partner. Those without a partner, like <code class=\"calibre9\">Jared<\/code>, will not be included in the result.For the <code class=\"calibre9\">DistinctBy<\/code> example, instead of removing duplicates by comparing the whole name, we define a lambda key selector to remove duplicates by comparing the first two characters, so <code class=\"calibre9\">Jared<\/code> is removed because <code class=\"calibre9\">Jack<\/code> already is a name that starts with <code class=\"calibre9\">Ja<\/code>.So far, we have used the LINQ to Objects provider to work with in-memory objects. Next, we will use the LINQ to Entities provider to work with entities stored in a database.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"12.5\" id=\"calibre_link-632\">\n<h2 data-number=\"12.5\" class=\"calibre5\">Using LINQ with EF Core<\/h2>\n<p class=\"rights\">We have looked at LINQ queries that filter and sort, but none that change the shape of the items in the sequence. This is called <strong class=\"calibre2\">projection<\/strong> because it's about projecting items of one shape into another shape. To learn about projection, it is best to have some more complex types to work with, so in the next project, instead of using <code class=\"calibre9\">string<\/code> sequences, we will use sequences of entities from the Northwind sample database that you were introduced to in <em class=\"calibre10\">Chapter 10<\/em>, <em class=\"calibre10\">Working with Data Using Entity Framework Core<\/em>.I will give instructions to use SQLite because it is cross-platform, but if you prefer to use SQL Server then feel free to do so. I have included some commented code to enable SQL Server if you choose.<\/p>\n<section data-number=\"12.5.1\" id=\"calibre_link-633\">\n<h3 data-number=\"12.5.1\" class=\"calibre8\">Creating a console app for exploring LINQ to Entities<\/h3>\n<p class=\"rights\">First, we must create a console app and Northwind database to work with:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to add a new <strong class=\"calibre2\">Console App<\/strong> \/ <code class=\"calibre9\">console<\/code> project named <code class=\"calibre9\">LinqWithEFCore<\/code> to the <code class=\"calibre9\">Chapter11<\/code> solution.<\/li>\n<li class=\"calibre3\">In the project file, globally and statically import the <code class=\"calibre9\">System.Console<\/code> class.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">LinqWithEFCore<\/code> project, add a package reference to the EF Core provider for SQLite and\/or SQL Server, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;!--To use SQLite--&gt;\n  &lt;PackageReference Version=\"8.0.0\"\n    Include=\"Microsoft.EntityFrameworkCore.Sqlite\" \/&gt;\n  &lt;!--To use SQL Server--&gt;\n  &lt;PackageReference Version=\"8.0.0\"\n    Include=\"Microsoft.EntityFrameworkCore.SqlServer\" \/&gt;\n  &lt;PackageReference Version=\"5.1.1\"\n    Include=\"Microsoft.Data.SqlClient\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">LinqWithEFCore<\/code> project to restore packages.<\/li>\n<li class=\"calibre3\">Copy the <code class=\"calibre9\">Northwind4Sqlite.sql<\/code> file to the <code class=\"calibre9\">LinqWithEFCore<\/code> folder.<\/li>\n<li class=\"calibre3\">At a command prompt or terminal in the <code class=\"calibre9\">LinqWithEFCore<\/code> folder, create the Northwind database by executing the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">sqlite3 Northwind.db -init Northwind4Sqlite.sql<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Be patient because this command might take a while to create the database structure. Eventually, you will see the SQLite command prompt, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\"> -- Loading resources from Northwind4Sqlite.sql \nSQLite version 3.38.0 2022-02-22 15:20:15\nEnter \".help\" for usage hints.\nsqlite&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">To exit SQLite command mode, press <span>Ctrl<\/span> + <span>C<\/span> twice on Windows or <span>cmd<\/span> + <span>D<\/span> on macOS or Linux.<\/li>\n<li class=\"calibre3\">If you prefer to work with SQL Server, then you should already have the Northwind database created in SQL Server from the previous chapter.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"12.5.2\" id=\"calibre_link-634\">\n<h3 data-number=\"12.5.2\" class=\"calibre8\">Building an EF Core model<\/h3>\n<p class=\"rights\">We must define an EF Core model to represent the database and tables that we will work with. We will define the model manually to take complete control and to prevent a relationship from being automatically defined between the <code class=\"calibre9\">Categories<\/code> and <code class=\"calibre9\">Products<\/code> tables. Later, you will use LINQ to join the two entity sets:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">LinqWithEFCore<\/code> project, add a new folder named <code class=\"calibre9\">EntityModels<\/code>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">EntityModels<\/code> folder, add three class files to the project, named <code class=\"calibre9\">NorthwindDb.cs<\/code>, <code class=\"calibre9\">Category.cs<\/code>, and <code class=\"calibre9\">Product.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify the class file named <code class=\"calibre9\">Category.cs<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ To use [Required] and [StringLength].\nusing System.ComponentModel.DataAnnotations;\nnamespace Northwind.EntityModels;\npublic class Category\n{\n  public int CategoryId { get; set; }\n  [Required]\n  [StringLength(15)]\n  public string CategoryName { get; set; } = null!;\n  public string? Description { get; set; }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the class file named <code class=\"calibre9\">Product.cs<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ To use [Required] and [StringLength].\nusing System.ComponentModel.DataAnnotations; \n\/\/ To use [Column].\nusing System.ComponentModel.DataAnnotations.Schema;\nnamespace Northwind.EntityModels;\npublic class Product\n{\n  public int ProductId { get; set; }\n  [Required]\n  [StringLength(40)]\n  public string ProductName { get; set; } = null!;\n  public int? SupplierId { get; set; }\n  public int? CategoryId { get; set; }\n  [StringLength(20)]\n  public string? QuantityPerUnit { get; set; }\n  \/\/ Required for SQL Server provider.\n  [Column(TypeName = \"money\")]\n  public decimal? UnitPrice { get; set; }\n  public short? UnitsInStock { get; set; }\n  public short? UnitsOnOrder { get; set; }\n  public short? ReorderLevel { get; set; }\n  public bool Discontinued { get; set; }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">We have deliberately not defined any relationships between <code class=\"calibre9\">Category<\/code> and <code class=\"calibre9\">Product<\/code> so that we can see how to manually associate them with each other using LINQ later.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the class file named <code class=\"calibre9\">NorthwindDb.cs<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.Data.SqlClient; \/\/ To use SqlConnectionStringBuilder.\nusing Microsoft.EntityFrameworkCore; \/\/ To use DbContext, DbSet&lt;T&gt;.\nnamespace Northwind.EntityModels;\npublic class NorthwindDb : DbContext\n{\n  public DbSet&lt;Category&gt; Categories { get; set; } = null!;\n  public DbSet&lt;Product&gt; Products { get; set; } = null!;\n  protected override void OnConfiguring(\n    DbContextOptionsBuilder optionsBuilder)\n  {\n    #region To use SQLite\n    string database = \"Northwind.db\";\n    string dir = Environment.CurrentDirectory;\n    string path = string.Empty;\n    \/\/ The database file will stay in the project folder.\n    \/\/ We will automatically adjust the relative path to \n    \/\/ account for running in VS2022 or from terminal.\n    if (dir.EndsWith(\"net8.0\"))\n    {\n      \/\/ Running in the &lt;project&gt;\\bin\\&lt;Debug|Release&gt;\\net8.0 directory.\n      path = Path.Combine(\"..\", \"..\", \"..\", database);\n    }\n    else\n    {\n      \/\/ Running in the &lt;project&gt; directory.\n      path = database;\n    }\n    path = Path.GetFullPath(path); \/\/ Convert to absolute path.\n    WriteLine($\"SQLite database path: {path}\");\n    if (!File.Exists(path))\n    {\n      throw new FileNotFoundException(\n        message: $\"{path} not found.\", fileName: path);\n    }\n    \/\/ To use SQLite.\n    optionsBuilder.UseSqlite($\"Data Source={path}\");\n    #endregion\n    #region To use SQL Server\n    SqlConnectionStringBuilder builder = new();\n    builder.DataSource = \".\";\n    builder.InitialCatalog = \"Northwind\";\n    builder.IntegratedSecurity = true;\n    builder.Encrypt = true;\n    builder.TrustServerCertificate = true;\n    builder.MultipleActiveResultSets = true;\n    string connection = builder.ConnectionString;\n    \/\/ WriteLine($\"SQL Server connection: {connection}\");\n    \/\/ To use SQL Server.\n    \/\/ optionsBuilder.UseSqlServer(connection);\n    #endregion\n  }\n  protected override void OnModelCreating(\n    ModelBuilder modelBuilder)\n  {\n    if (Database.ProviderName is not null &amp;&amp;\n      Database.ProviderName.Contains(\"Sqlite\"))\n    {\n      \/\/ SQLite data provider does not directly support the\n      \/\/ decimal type so we can convert to double instead.\n      modelBuilder.Entity&lt;Product&gt;()\n        .Property(product =&gt; product.UnitPrice)\n        .HasConversion&lt;double&gt;();\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you want to use SQL Server, then comment out the statement that calls <code class=\"calibre9\">UseSqlite<\/code> and uncomment the statement that calls <code class=\"calibre9\">UseSqlServer<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the project and fix any compiler errors.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"12.5.3\" id=\"calibre_link-635\">\n<h3 data-number=\"12.5.3\" class=\"calibre8\">Filtering and sorting sequences<\/h3>\n<p class=\"rights\">Now let's write statements to filter and sort sequences of rows from the tables:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">LinqWithEFCore<\/code> project, add a new class file named <code class=\"calibre9\">Program.Helpers.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Helpers.cs<\/code>, define a partial <code class=\"calibre9\">Program<\/code> class with a method to configure the console to support special characters like the Euro currency symbol and control the current culture, and a method to output a section title, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Globalization; \/\/ To use CultureInfo.\npartial class Program\n{\n  private static void ConfigureConsole(string culture = \"en-US\",\n    bool useComputerCulture = false)\n  {\n    \/\/ To enable Unicode characters like Euro symbol in the console.\n    OutputEncoding = System.Text.Encoding.UTF8;\n    if (!useComputerCulture)\n    {\n      CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo(culture);\n    }\n    WriteLine($\"CurrentCulture: {CultureInfo.CurrentCulture.DisplayName}\");\n  }\n  private static void SectionTitle(string title)\n  {\n    ConsoleColor previousColor = ForegroundColor;\n    ForegroundColor = ConsoleColor.DarkYellow;\n    WriteLine($\"*** {title} ***\");\n    ForegroundColor = previousColor;\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">LinqWithEFCore<\/code> project, add a new class file named <code class=\"calibre9\">Program.Functions.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, define a partial <code class=\"calibre9\">Program<\/code> class and add a method to filter and sort products, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.EntityModels; \/\/ To use NorthwindDb, Category, Product.\nusing Microsoft.EntityFrameworkCore; \/\/ To use DbSet&lt;T&gt;.\npartial class Program\n{\n  private static void FilterAndSort()\n  {\n    SectionTitle(\"Filter and sort\");\n    using NorthwindDb db = new();\n    DbSet&lt;Product&gt; allProducts = db.Products;\n    IQueryable&lt;Product&gt; filteredProducts = \n      allProducts.Where(product =&gt; product.UnitPrice &lt; 10M);\n    IOrderedQueryable&lt;Product&gt; sortedAndFilteredProducts = \n      filteredProducts.OrderByDescending(product =&gt; product.UnitPrice);\n    WriteLine(\"Products that cost less than $10:\");\n    foreach (Product p in sortedAndFilteredProducts)\n    {\n      WriteLine(\"{0}: {1} costs {2:$#,##0.00}\",\n        p.ProductId, p.ProductName, p.UnitPrice);\n    }\n    WriteLine();\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following about the preceding code:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">DbSet&lt;T&gt;<\/code> implements <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code>, so LINQ can be used to query and manipulate sequences of entities in models built for EF Core. (Actually, I should say <code class=\"calibre9\">TEntity<\/code> instead of <code class=\"calibre9\">T<\/code>, but the name of this generic type has no functional effect. The only requirement is that the type is a <code class=\"calibre9\">class<\/code>. The name just indicates the class is expected to be an entity model.)<\/li>\n<li class=\"calibre3\">The sequences implement <code class=\"calibre9\">IQueryable&lt;T&gt;<\/code> (or <code class=\"calibre9\">IOrderedQueryable&lt;T&gt;<\/code> after a call to an ordering LINQ method) instead of <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> or <code class=\"calibre9\">IOrderedEnumerable&lt;T&gt;<\/code>. This is an indication that we are using a LINQ provider that builds the query using expression trees. They represent code in a tree-like data structure and enable the creation of dynamic queries, which is useful for building LINQ queries for external data providers like SQLite.<\/li>\n<li class=\"calibre3\">The LINQ expression will be converted into another query language, such as SQL. Enumerating the query with <code class=\"calibre9\">foreach<\/code> or calling a method such as <code class=\"calibre9\">ToArray<\/code> will force the execution of the query and materialize the results.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, delete any existing statements and then call the <code class=\"calibre9\">ConfigureConsole<\/code> and <code class=\"calibre9\">FilterAndSort<\/code> methods, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ConfigureConsole(); \/\/ Sets US English by default.\nFilterAndSort();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the project and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CurrentCulture: English (United States)\n*** Filter and sort ***\nSQLite database path: C:\\cs12dotnet8\\Chapter11\\LinqWithEFCore\\Northwind.db\nProducts that cost less than $10:\n41: Jack's New England Clam Chowder costs $9.65 \n45: Rogede sild costs $9.50\n47: Zaanse koeken costs $9.50\n19: Teatime Chocolate Biscuits costs $9.20 \n23: Tunnbr\u00f6d costs $9.00\n75: Rh\u00f6nbr\u00e4u Klosterbier costs $7.75 \n54: Tourti\u00e8re costs $7.45\n52: Filo Mix costs $7.00 \n13: Konbu costs $6.00\n24: Guaran\u00e1 Fant\u00e1stica costs $4.50 \n33: Geitost costs $2.50<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Although this query outputs the information we want, it does so inefficiently because it gets all columns from the <code class=\"calibre9\">Products<\/code> table instead of just the three columns we need. Let's log the generated SQL:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">FilterAndSort<\/code> method, before enumerating the results using <code class=\"calibre9\">foreach<\/code>, add a statement to output the SQL, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">WriteLine(\"Products that cost less than $10:\");\nWriteLine(sortedAndFilteredProducts.ToQueryString());<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the result that shows the SQL executed before the product details, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Products that cost less than $10:\nSELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"QuantityPerUnit\", \"p\".\"ReorderLevel\", \"p\".\"SupplierId\", \"p\".\"UnitPrice\", \"p\".\"UnitsInStock\", \"p\".\"UnitsOnOrder\"\nFROM \"Products\" AS \"p\"\nWHERE \"p\".\"UnitPrice\" &lt; 10.0\nORDER BY \"p\".\"UnitPrice\" DESC\n41: Jack's New England Clam Chowder costs $9.65\n...<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"12.5.4\" id=\"calibre_link-636\">\n<h3 data-number=\"12.5.4\" class=\"calibre8\">Projecting sequences into new types<\/h3>\n<p class=\"rights\">Before we look at <strong class=\"calibre2\">projection<\/strong>, we should review object initialization syntax. If you have a class defined, then you can instantiate an object using the class name, <code class=\"calibre9\">new()<\/code>, and curly braces to set initial values for fields and properties, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Person.cs\npublic class Person\n{\n  public string Name { get; set; }\n  public DateTime DateOfBirth { get; set; }\n}\n\/\/ Program.cs\nPerson knownTypeObject = new()\n{\n  Name = \"Boris Johnson\",\n  DateOfBirth = new(year: 1964, month: 6, day: 19)\n};<\/code><\/pre>\n<\/div>\n<p class=\"rights\">C# 3 and later allow instances of <strong class=\"calibre2\">anonymous types<\/strong> to be instantiated using the <code class=\"calibre9\">var<\/code> keyword, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var anonymouslyTypedObject = new\n{\n  Name = \"Boris Johnson\",\n  DateOfBirth = new DateTime(year: 1964, month: 6, day: 19)\n};<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Although we did not specify a type, the compiler can infer an anonymous type from the setting of two properties named <code class=\"calibre9\">Name<\/code> and <code class=\"calibre9\">DateOfBirth<\/code>. The compiler can infer the types of the two properties from the values assigned: a literal <code class=\"calibre9\">string<\/code> and a new instance of a date\/time value.This capability is especially useful when writing LINQ queries to project an existing type into a new type without having to explicitly define the new type. Since the type is anonymous, this can only work with <code class=\"calibre9\">var<\/code>-declared local variables.Let's make the SQL command executed against the database table more efficient by adding a call to the <code class=\"calibre9\">Select<\/code> method to project instances of the <code class=\"calibre9\">Product<\/code> class into instances of a new anonymous type with only three properties:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, in the <code class=\"calibre9\">FilterAndSort<\/code> method, add a statement to extend the LINQ query to use the <code class=\"calibre9\">Select<\/code> method to return only the three properties (that is, table columns) that we need, and modify the call to <code class=\"calibre9\">ToQueryString<\/code> to use the new <code class=\"calibre9\">projectedProducts<\/code> query, and the <code class=\"calibre9\">foreach<\/code> statement to use the <code class=\"calibre9\">var<\/code> keyword and the new <code class=\"calibre9\">projectedProducts<\/code> query, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">IOrderedQueryable&lt;Product&gt; sortedAndFilteredProducts = \n  filteredProducts.OrderByDescending(product =&gt; product.UnitPrice);\nvar projectedProducts = sortedAndFilteredProducts\n  .Select(product =&gt; new \/\/ Anonymous type.\n  {\n    product.ProductId,\n    product.ProductName, \n    product.UnitPrice\n  });\nWriteLine(\"Products that cost less than $10:\");\nWriteLine(projectedProducts.ToQueryString());\nforeach (var p in projectedProducts)\n{<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Hover your mouse over the <code class=\"calibre9\">new<\/code> keyword in the <code class=\"calibre9\">Select<\/code> method call, or the <code class=\"calibre9\">var<\/code> keyword in the <code class=\"calibre9\">foreach<\/code> statement, and note that it is an anonymous type, as shown in <em class=\"calibre10\">Figure 11.5<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 11.5: An anonymous type used during LINQ projection\" height=\"292\" src=\"\/images\/cs12\/000160.png\" width=\"852\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 11.5: An anonymous type used during LINQ projection<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Run the project and confirm that the output is the same as before and the generated SQL is more efficient, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">SELECT \"p\".\"ProductId\", \"p\".\"ProductName\", \"p\".\"UnitPrice\"\nFROM \"Products\" AS \"p\"\nWHERE \"p\".\"UnitPrice\" &lt; 10.0\nORDER BY \"p\".\"UnitPrice\" DESC<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More information<\/strong>: You can learn more about projection using the <code class=\"calibre9\">Select<\/code> method at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/projection-operations\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/projection-operations<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's continue to look at common LINQ queries by learning how to join, group, and perform lookups.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"12.6\" id=\"calibre_link-637\">\n<h2 data-number=\"12.6\" class=\"calibre5\">Joining, grouping, and lookups<\/h2>\n<p class=\"rights\">There are three extension methods for joining, grouping, and creating grouped lookups:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Join<\/code>: This method has four parameters: the sequence that you want to join with, the property or properties on the <em class=\"calibre10\">left<\/em> sequence to match on, the property or properties on the <em class=\"calibre10\">right<\/em> sequence to match on, and a projection.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">GroupJoin<\/code>: This method has the same parameters, but it combines the matches into a group object with a <code class=\"calibre9\">Key<\/code> property for the matching value and an <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> type for the multiple matches.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">ToLookup<\/code>: This method creates a new data structure with the sequence grouped by a key.<\/li>\n<\/ul>\n<section data-number=\"12.6.1\" id=\"calibre_link-638\">\n<h3 data-number=\"12.6.1\" class=\"calibre8\">Joining sequences<\/h3>\n<p class=\"rights\">Let's explore these methods when working with two tables, <code class=\"calibre9\">Categories<\/code> and <code class=\"calibre9\">Products<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, add a method to select categories and products, join them, and output them, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void JoinCategoriesAndProducts()\n{\n  SectionTitle(\"Join categories and products\");\n  using NorthwindDb db = new();\n  \/\/ Join every product to its category to return 77 matches.\n  var queryJoin = db.Categories.Join(\n    inner: db.Products,\n    outerKeySelector: category =&gt; category.CategoryId,\n    innerKeySelector: product =&gt; product.CategoryId,\n    resultSelector: (c, p) =&gt;\n      new { c.CategoryName, p.ProductName, p.ProductId });\n  foreach (var p in queryJoin)\n  {\n    WriteLine($\"{p.ProductId}: {p.ProductName} in {p.CategoryName}.\");\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In a join, there are two sequences, <code class=\"calibre9\">outer<\/code> and <code class=\"calibre9\">inner<\/code>. In the preceding example, <code class=\"calibre9\">categories<\/code> is the outer sequence and <code class=\"calibre9\">products<\/code> is the inner sequence.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out the call to <code class=\"calibre9\">FilterAndSort<\/code>, and then call the <code class=\"calibre9\">JoinCategoriesAndProducts<\/code> method, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ConfigureConsole(); \/\/ Sets US English by default.\n\/\/ FilterAndSort();\nJoinCategoriesAndProducts();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the results. Note that there is a single line of output for each of the 77 products, as shown in the following output (edited to only include the first four items):<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">1: Chai in Beverages. \n2: Chang in Beverages.\n3: Aniseed Syrup in Condiments.\n4: Chef Anton's Cajun Seasoning in Condiments. \n...<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, in the <code class=\"calibre9\">JoinCategoriesAndProducts<\/code> method, at the end of the existing query, call the <code class=\"calibre9\">OrderBy<\/code> method to sort by <code class=\"calibre9\">CategoryName<\/code>, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var queryJoin = db.Categories.Join(\n  inner: db.Products,\n  outerKeySelector: category =&gt; category.CategoryId,\n  innerKeySelector: product =&gt; product.CategoryId,\n  resultSelector: (c, p) =&gt;\n    new { c.CategoryName, p.ProductName, p.ProductId })\n  .OrderBy(cp =&gt; cp.CategoryName);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the code and view the results. Note that there is a single line of output for each of the 77 products, and the results show all products in the <code class=\"calibre9\">Beverages<\/code> category first, then the <code class=\"calibre9\">Condiments<\/code> category, and so on, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">1: Chai in Beverages. \n2: Chang in Beverages.\n24: Guaran\u00e1 Fant\u00e1stica in Beverages. \n34: Sasquatch Ale in Beverages.\n...<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"12.6.2\" id=\"calibre_link-639\">\n<h3 data-number=\"12.6.2\" class=\"calibre8\">Group-joining sequences<\/h3>\n<p class=\"rights\">Let's explore group joining when working with the same two tables as we used to explore joining, <code class=\"calibre9\">Categories<\/code> and <code class=\"calibre9\">Products<\/code>, so we can compare the subtle differences:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, add a method to group and join, show the group name, and then show all the items within each group, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void GroupJoinCategoriesAndProducts()\n{\n  SectionTitle(\"Group join categories and products\");\n  using NorthwindDb db = new();\n  \/\/ Group all products by their category to return 8 matches.\n  var queryGroup = db.Categories.AsEnumerable().GroupJoin(\n    inner: db.Products,\n    outerKeySelector: category =&gt; category.CategoryId,\n    innerKeySelector: product =&gt; product.CategoryId,\n    resultSelector: (c, matchingProducts) =&gt; new\n    {\n      c.CategoryName,\n      Products = matchingProducts.OrderBy(p =&gt; p.ProductName)\n    });\n  foreach (var c in queryGroup)\n  {\n    WriteLine($\"{c.CategoryName} has {c.Products.Count()} products.\");\n    foreach (var product in c.Products)\n    {\n      WriteLine($\"  {product.ProductName}\");\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If we had not called the <code class=\"calibre9\">AsEnumerable<\/code> method, then a runtime exception would have been thrown, as shown in the following output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Unhandled exception. System.ArgumentException:  Argument type 'System.Linq.IOrderedQueryable`1[Packt.Shared.Product]' does not match the corresponding member type 'System.Linq.IOrderedEnumerable`1[Packt.Shared.Product]' (Parameter 'arguments[1]')<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This is because not all LINQ extension methods can be converted from expression trees into some other query syntax like SQL. In these cases, we can convert from <code class=\"calibre9\">IQueryable&lt;T&gt;<\/code> to <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> by calling the <code class=\"calibre9\">AsEnumerable<\/code> method, which forces query processing to use LINQ to EF Core only to bring the data into the application, and then use LINQ to Objects to execute more complex processing in memory. But, often, this is less efficient.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, call the <code class=\"calibre9\">GroupJoinCategoriesAndProducts<\/code> method.<\/li>\n<li class=\"calibre3\">Run the code, view the results, and note that the products inside each category have been sorted by their name, as defined in the query, and as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Beverages has 12 products.\n  Chai\n  Chang\n  ...\nCondiments has 12 products.\n  Aniseed Syrup\n  Chef Anton's Cajun Seasoning\n  ...<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"12.6.3\" id=\"calibre_link-640\">\n<h3 data-number=\"12.6.3\" class=\"calibre8\">Grouping for lookups<\/h3>\n<p class=\"rights\">Instead of writing a LINQ query expression to join and group and running it once, you might want to use a LINQ extension method to create and then store a reusable in-memory collection that has entities that have been grouped.We have a table named <code class=\"calibre9\">Products<\/code> in the Northwind database that includes a column for the category that they reside in, as shown in <em class=\"calibre10\">Table 11.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">ProductName<\/td>\n<td class=\"calibre21\">CategoryID<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Chai<\/td>\n<td class=\"calibre21\">1<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Chang<\/td>\n<td class=\"calibre21\">1<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Aniseed Syrup<\/td>\n<td class=\"calibre21\">2<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Chef Anton's Cajun Seasoning<\/td>\n<td class=\"calibre21\">2<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Chef Anton's Gumbo Mix<\/td>\n<td class=\"calibre21\">2<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">...<\/td>\n<td class=\"calibre21\">...<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 11.3: Simplified products table<\/p>\n<p class=\"rights\">You might want to create a data structure in memory that can group the <code class=\"calibre9\">Product<\/code> entities by their category, and then provide a quick way to look up all the products in a specific category. You can create this using the <code class=\"calibre9\">ToLookup<\/code> LINQ method, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ILookup&lt;int, Product&gt;? productsByCategoryId = \n  db.Products.ToLookup(keySelector: category =&gt; category.CategoryId);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">When you call the <code class=\"calibre9\">ToLookup<\/code> method, you must specify a <strong class=\"calibre2\">key selector<\/strong> to choose what value you want to group by. This value can then later be used to look up the group and its items.The <code class=\"calibre9\">ToLookup<\/code> method creates a dictionary-like data structure of key-value pairs in memory that has unique category IDs for the key and a collection of <code class=\"calibre9\">Product<\/code> objects for the value, as shown in <em class=\"calibre10\">Table 11.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Key<\/td>\n<td class=\"calibre21\">Value (each one is a collection of Product objects)<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">1<\/td>\n<td class=\"calibre21\">[Chai] [Chang] and so on.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">2<\/td>\n<td class=\"calibre21\">[Aniseed Syrup] [Chef Anton's Cajun Seasoning] [Chef Anton's Gumbo Mix] and so on.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">...<\/td>\n<td class=\"calibre21\">...<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 11.4: Simplified product lookup<\/p>\n<p class=\"rights\">Note the product names in square brackets like [Chai] represent an entire <code class=\"calibre9\">Product<\/code> object.Instead of using the <code class=\"calibre9\">CategoryId<\/code> values as the key to the lookup, we could use the category names from the related categories table.Let's do this in a code example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, add a method to join products to category names, and then convert them into a lookup, enumerate through the whole lookup, using an <code class=\"calibre9\">IGrouping&lt;string, Product&gt;<\/code> to represent each row in the lookup dictionary, and then look up an individual collection of products for a specific category, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void ProductsLookup()\n{\n  SectionTitle(\"Products lookup\");\n  using NorthwindDb db = new();\n  \/\/ Join all products to their category to return 77 matches.\n  var productQuery = db.Categories.Join(\n    inner: db.Products,\n    outerKeySelector: category =&gt; category.CategoryId,\n    innerKeySelector: product =&gt; product.CategoryId,\n    resultSelector: (c, p) =&gt; new { c.CategoryName, Product = p });\n  ILookup&lt;string, Product&gt; productLookup = productQuery.ToLookup(\n    keySelector: cp =&gt; cp.CategoryName, \n    elementSelector: cp =&gt; cp.Product);\n  foreach (IGrouping&lt;string, Product&gt; group in productLookup)\n  {\n    \/\/ Key is Beverages, Condiments, and so on.\n    WriteLine($\"{group.Key} has {group.Count()} products.\");\n    foreach (Product product in group)\n    {\n      WriteLine($\" {product.ProductName}\");\n    }\n  }\n  \/\/ We can look up the products by a category name.\n  Write(\"Enter a category name: \");\n  string categoryName = ReadLine()!;\n  WriteLine();\n  WriteLine($\"Products in {categoryName}:\");\n  IEnumerable&lt;Product&gt; productsInCategory = productLookup[categoryName];\n  foreach (Product product in productsInCategory)\n  {\n    WriteLine($\"  {product.ProductName}\");\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Selector<\/strong> parameters are lambda expressions that select sub-elements for different purposes. For example, <code class=\"calibre9\">ToLookup<\/code> has a <code class=\"calibre9\">keySelector<\/code> to select the part of each item that will be the key and an <code class=\"calibre9\">elementSelector<\/code> to select the part of each item that will be the value. You can learn more at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.linq.enumerable.tolookup\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.linq.enumerable.tolookup<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, call the <code class=\"calibre9\">ProductsLookup<\/code> method.<\/li>\n<li class=\"calibre3\">Run the code, view the results, enter a category name like <code class=\"calibre9\">Seafoods<\/code>, and note that the products are looked up and listed for that category, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Beverages has 12 products.\n  Chai\n  Chang\n  ...\nCondiments has 12 products.\n  Aniseed Syrup\n  Chef Anton's Cajun Seasoning\n  ...\nEnter a category name: Seafood\nProducts in Seafood:\n  Ikura\n  Konbu\n  Carnarvon Tigers\n  Nord-Ost Matjeshering\n  Inlagd Sill\n  Gravad lax\n  Boston Crab Meat\n  Jack's New England Clam Chowder\n  Rogede sild\n  Spegesild\n  Escargots de Bourgogne\n  R\u00f6d Kaviar<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"12.7\" id=\"calibre_link-641\">\n<h2 data-number=\"12.7\" class=\"calibre5\">Aggregating and paging sequences<\/h2>\n<p class=\"rights\">There are LINQ extension methods to perform aggregation functions, such as <code class=\"calibre9\">Average<\/code> and <code class=\"calibre9\">Sum<\/code>. Let's write some code to see some of these methods in action, aggregating information from the <code class=\"calibre9\">Products<\/code> table:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, add a method to show the use of the aggregation extension methods, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void AggregateProducts()\n{\n  SectionTitle(\"Aggregate products\");\n  using NorthwindDb db = new();\n  \/\/ Try to get an efficient count from EF Core DbSet&lt;T&gt;.\n  if (db.Products.TryGetNonEnumeratedCount(out int countDbSet))\n  {\n    WriteLine($\"{\"Product count from DbSet:\",-25} {countDbSet,10}\");\n  }\n  else\n  {\n    WriteLine(\"Products DbSet does not have a Count property.\");\n  }\n  \/\/ Try to get an efficient count from a List&lt;T&gt;.\n  List&lt;Product&gt; products = db.Products.ToList();\n  if (products.TryGetNonEnumeratedCount(out int countList))\n  {\n    WriteLine($\"{\"Product count from list:\",-25} {countList,10}\");\n  }\n  else\n  {\n    WriteLine(\"Products list does not have a Count property.\");\n  }\n  WriteLine($\"{\"Product count:\",-25} {db.Products.Count(),10}\");\n  WriteLine($\"{\"Discontinued product count:\",-27} {db.Products\n    .Count(product =&gt; product.Discontinued),8}\");\n  WriteLine($\"{\"Highest product price:\",-25} {db.Products\n    .Max(p =&gt; p.UnitPrice),10:$#,##0.00}\");\n  WriteLine($\"{\"Sum of units in stock:\",-25} {db.Products\n    .Sum(p =&gt; p.UnitsInStock),10:N0}\");\n  WriteLine($\"{\"Sum of units on order:\",-25} {db.Products\n    .Sum(p =&gt; p.UnitsOnOrder),10:N0}\");\n  WriteLine($\"{\"Average unit price:\",-25} {db.Products\n    .Average(p =&gt; p.UnitPrice),10:$#,##0.00}\");\n  WriteLine($\"{\"Value of units in stock:\",-25} {db.Products\n    .Sum(p =&gt; p.UnitPrice * p.UnitsInStock),10:$#,##0.00}\");\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good practice<\/strong>: Getting a count can seem like a simple operation but counting can be costly. A <code class=\"calibre9\">DbSet&lt;T&gt;<\/code> like <code class=\"calibre9\">Products<\/code> does not have a <code class=\"calibre9\">Count<\/code> property so <code class=\"calibre9\">TryGetNonEnumeratedCount<\/code> returns <code class=\"calibre9\">false<\/code>. A <code class=\"calibre9\">List&lt;T&gt;<\/code> like <code class=\"calibre9\">products<\/code> does have a <code class=\"calibre9\">Count<\/code> property because it implements <code class=\"calibre9\">ICollection<\/code> so <code class=\"calibre9\">TryGetNonEnumeratedCount<\/code> returns <code class=\"calibre9\">true<\/code>. (In this case, we had to instantiate a list, which is itself a costly operation, but if you already have a list and need to know the number of items, then this would be efficient.) You can always call <code class=\"calibre9\">Count()<\/code> on a <code class=\"calibre9\">DbSet&lt;T&gt;<\/code>, but it can be slow because it might have to enumerate the sequence depending on the data provider implementation. For any array, use the <code class=\"calibre9\">Length<\/code> property to get a count. You can pass a lambda expression to <code class=\"calibre9\">Count()<\/code> to filter which items in the sequence should be counted, which you cannot do with either the <code class=\"calibre9\">Count<\/code> or <code class=\"calibre9\">Length<\/code> properties.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, call the <code class=\"calibre9\">AggregateProducts<\/code> method.<\/li>\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Products DbSet does not have a Count property.\nProduct count from list:          77\nProduct count:                    77\nDiscontinued product count:        8\nHighest product price:       $263.50\nSum of units in stock:         3,119\nSum of units on order:           780\nAverage unit price:           $28.87\nValue of units in stock:  $74,050.85<\/code><\/pre>\n<\/div>\n<section data-number=\"12.7.1\" id=\"calibre_link-642\">\n<h3 data-number=\"12.7.1\" class=\"calibre8\">Checking for an empty sequence<\/h3>\n<p class=\"rights\">There are multiple ways to check if a sequence is empty or it contains any items:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Call the LINQ <code class=\"calibre9\">Count()<\/code> method and see if it is greater than zero. This is sometimes the worst if it must enumerate the whole sequence to count the items. You will see more about this in the next section. But as we saw when we used ILSpy to decompile the <code class=\"calibre9\">Count<\/code> method implementation, it is smart enough to check if the sequence implements <code class=\"calibre9\">ICollection<\/code> or <code class=\"calibre9\">ICollection&lt;T&gt;<\/code> and therefore has a more efficient <code class=\"calibre9\">Count<\/code> property.<\/li>\n<li class=\"calibre3\">Call the LINQ <code class=\"calibre9\">Any()<\/code> method and see if it returns <code class=\"calibre9\">true<\/code>. This is better than <code class=\"calibre9\">Count()<\/code> but not as good as either of the next two options.<\/li>\n<li class=\"calibre3\">Get the sequence's <code class=\"calibre9\">Count<\/code> property (if it has one) and see if it is greater than zero. Any sequence that implements <code class=\"calibre9\">ICollection<\/code> or <code class=\"calibre9\">ICollection&lt;T&gt;<\/code> will have a <code class=\"calibre9\">Count<\/code> property.<\/li>\n<li class=\"calibre3\">Get the sequence's <code class=\"calibre9\">Length<\/code> property (if it has one) and see if it is greater than zero. Any array will have a <code class=\"calibre9\">Length<\/code> property.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"12.7.2\" id=\"calibre_link-643\">\n<h3 data-number=\"12.7.2\" class=\"calibre8\">Be careful with Count!<\/h3>\n<p class=\"rights\">Amichai Mantinband is a Software Engineer at Microsoft, and he does a great job of highlighting interesting parts of the C# and .NET developer stack.Recently, he posted a code teaser on Twitter, LinkedIn, and YouTube, with a poll to find out what developers thought the code would do. Here's the code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">IEnumerable&lt;Task&gt; tasks = Enumerable.Range(0, 2)\n  .Select(_ =&gt; Task.Run(() =&gt; Console.WriteLine(\"*\")));\nawait Task.WhenAll(tasks);\nConsole.WriteLine($\"{tasks.Count()} stars!\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">What will the output be?<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">**2 stars!<\/li>\n<li class=\"calibre3\">**2 stars!**<\/li>\n<li class=\"calibre3\">****2 stars!<\/li>\n<li class=\"calibre3\">Something else<\/li>\n<\/ol>\n<p class=\"rights\">Most got it wrong, as shown in <em class=\"calibre10\">Figure 11.6<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 11.6: A tricky LINQ and Task code teaser from Amichai Mantinband\" height=\"607\" src=\"\/images\/cs12\/000001.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 11.6: A tricky LINQ and Task code teaser from Amichai Mantinband<\/figcaption><\/figure>\n<p class=\"rights\">By this point in this chapter, I would hope that you understand the LINQ parts of this tricky question. Don't worry! I would not expect you to understand the subtleties of multi-threading with tasks. It is still worth breaking down the code to make sure you understand the LINQ parts, as shown in <em class=\"calibre10\">Table 11.5<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre19\"><\/col>\n<col class=\"calibre19\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Code<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Enumerable.Range(0, 2)<\/code><\/td>\n<td class=\"calibre21\">Returns a sequence of two integers, <code class=\"calibre9\">0<\/code> and <code class=\"calibre9\">1<\/code> . Personally, I would have added named parameters to make this clearer, as shown in the following code: <code class=\"calibre9\">Enumerable.Range(start: 0, count: 2)<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Select(_ =&gt; Task.Run(...)<\/code><\/td>\n<td class=\"calibre21\">Creates a task with its own thread for each of the two numbers. The <code class=\"calibre9\">_<\/code> parameter discards the number value. Each task outputs a star <code class=\"calibre9\">*<\/code> to the console.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">await Task.WhenAll(tasks);<\/code><\/td>\n<td class=\"calibre21\">Blocks the main thread until both of the two tasks have completed. So, at this point, we know that two stars <code class=\"calibre9\">**<\/code> have been output to the console.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">tasks.Count()<\/code><\/td>\n<td class=\"calibre21\">For the LINQ <code class=\"calibre9\">Count()<\/code> extension method to work in this scenario, it must <em class=\"calibre10\">enumerate the sequence<\/em> . This triggers the two tasks to execute again! But we do not know when those two tasks will execute. The value 2 is returned from the method call.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><code class=\"calibre9\">Console.WriteLine(<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">  $\"... stars!\");<\/code><\/p>\n<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">2 stars!<\/code> is output to the console.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 11.5: Code teaser steps explanation<\/p>\n<p class=\"rights\">So, we know that <code class=\"calibre9\">**<\/code> is output to the console first, then one or both tasks might output their star, then <code class=\"calibre9\">2 stars!<\/code> is output, and finally one or both tasks might output their star if they did not have time to do so before, or the main thread might end, terminating the console app before either task can output their star:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">**[each task could output * here]2 stars![each task could output * here]<\/code><\/pre>\n<\/div>\n<p class=\"rights\">So, the best answer to Amichai's teaser is \"Something else.\"<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good practice<\/strong>: Be careful when calling LINQ extension methods like <code class=\"calibre9\">Count<\/code> that need to enumerate over the sequence to calculate their return value. Even if you are not working with a sequence of executable objects like tasks, re-enumerating the sequence is likely to be inefficient.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"12.7.3\" id=\"calibre_link-644\">\n<h3 data-number=\"12.7.3\" class=\"calibre8\">Paging with LINQ<\/h3>\n<p class=\"rights\">Let's see how we could implement paging using the <code class=\"calibre9\">Skip<\/code> and <code class=\"calibre9\">Take<\/code> extension methods:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, add a method to output to the console a table of products passed as an array, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void OutputTableOfProducts(Product[] products, \n  int currentPage, int totalPages)\n{\n  string line = new('-', count: 73);\n  string lineHalf = new('-', count: 30);\n  WriteLine(line);\n  WriteLine(\"{0,4} {1,-40} {2,12} {3,-15}\",\n    \"ID\", \"Product Name\", \"Unit Price\", \"Discontinued\");\n  WriteLine(line);\n  foreach (Product p in products)\n  {\n    WriteLine(\"{0,4} {1,-40} {2,12:C} {3,-15}\",\n      p.ProductId, p.ProductName, p.UnitPrice, p.Discontinued);\n  }\n  WriteLine(\"{0} Page {1} of {2} {3}\",\n    lineHalf, currentPage + 1, totalPages + 1, lineHalf);\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">As usual in computing, our code will start counting from zero, so we need to add one to both the <code class=\"calibre9\">currentPage<\/code> count and <code class=\"calibre9\">totalPages<\/code> count before showing these values in a user interface.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, add a method to create a LINQ query that creates a page of products, outputs the SQL generated from it, and then passes the results as an array of products to the method that outputs a table of products, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void OutputPageOfProducts(IQueryable&lt;Product&gt; products,\n  int pageSize, int currentPage, int totalPages)\n{\n  \/\/ We must order data before skipping and taking to ensure\n  \/\/ the data is not randomly sorted in each page.\n  var pagingQuery = products.OrderBy(p =&gt; p.ProductId)\n    .Skip(currentPage * pageSize).Take(pageSize);\n  Clear(); \/\/ Clear the console\/screen.\n  SectionTitle(pagingQuery.ToQueryString());\n  OutputTableOfProducts(pagingQuery.ToArray(), \n    currentPage, totalPages);\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Why order when paging? The EF Core team gave a good example at the following link: <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-ef7-preview7-entity-framework\/#linq-expression-tree-interception\">https:\/\/devblogs.microsoft.com\/dotnet\/announcing-ef7-preview7-entity-framework\/#linq-expression-tree-interception<\/a>. I also cover ordering when paging in the companion book <em class=\"calibre10\">Apps and Services with .NET 8<\/em>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.Functions.cs<\/code>, add a method to loop while the user presses either the left or right arrows to page through the products in the database, showing one page at a time, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private static void PagingProducts()\n{\n  SectionTitle(\"Paging products\");\n  using NorthwindDb db = new();\n  int pageSize = 10;\n  int currentPage = 0;\n  int productCount = db.Products.Count();\n  int totalPages = productCount \/ pageSize;\n  while (true) \/\/ Use break to escape this infinite loop.\n  {\n    OutputPageOfProducts(db.Products, pageSize, currentPage, totalPages);\n    Write(\"Press &lt;- to page back, press -&gt; to page forward, any key to exit.\");\n    ConsoleKey key = ReadKey().Key;\n    if (key == ConsoleKey.LeftArrow)\n      currentPage = currentPage == 0 ? totalPages : currentPage - 1;\n    else if (key == ConsoleKey.RightArrow)\n      currentPage = currentPage == totalPages ? 0 : currentPage + 1;\n    else\n      break; \/\/ Break out of the while loop.\n    WriteLine();\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, comment out any other methods and then call the <code class=\"calibre9\">PagingProducts<\/code> method.<\/li>\n<li class=\"calibre3\">Run the code and view the result, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">-------------------------------------------------------------------------\n  ID Product Name                               Unit Price Discontinued\n-------------------------------------------------------------------------\n   1 Chai                                           \u00a318.00 False\n   2 Chang                                          \u00a319.00 False\n   3 Aniseed Syrup                                  \u00a310.00 False\n   4 Chef Anton's Cajun Seasoning                   \u00a322.00 False\n   5 Chef Anton's Gumbo Mix                         \u00a321.35 True\n   6 Grandma's Boysenberry Spread                   \u00a325.00 False\n   7 Uncle Bob's Organic Dried Pears                \u00a330.00 False\n   8 Northwoods Cranberry Sauce                     \u00a340.00 False\n   9 Mishi Kobe Niku                                \u00a397.00 True\n  10 Ikura                                          \u00a331.00 False\n------------------------------ Page 1 of 8 ------------------------------\nPress &lt;- to page back, press -&gt; to page forward.<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The preceding output excludes the SQL statement used to efficiently get the page of products by using <code class=\"calibre9\">ORDER BY<\/code>, <code class=\"calibre9\">LIMIT<\/code>, and <code class=\"calibre9\">OFFSET<\/code>, as shown in the following code:<\/p>\n<\/blockquote>\n<pre class=\"calibre22\"><code class=\"calibre23\">.param set @__p_1 10\n.param set @__p_0 0\nSELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"QuantityPerUnit\", \"p\".\"ReorderLevel\", \"p\".\"SupplierId\", \"p\".\"UnitPrice\", \"p\".\"UnitsInStock\", \"p\".\"UnitsOnOrder\"\nFROM \"Products\" AS \"p\"\nORDER BY \"p\".\"ProductId\"\nLIMIT @__p_1 OFFSET @__p_0<\/code><\/pre>\n<ol class=\"toc\">\n<li class=\"calibre3\">Make sure the command prompt or terminal window has the focus when you press keys.<\/li>\n<li class=\"calibre3\">Press the right arrow and note the second page of results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">-------------------------------------------------------------------------\n  ID Product Name                               Unit Price Discontinued\n-------------------------------------------------------------------------\n  11 Queso Cabrales                                 \u00a321.00 False\n  12 Queso Manchego La Pastora                      \u00a338.00 False\n  13 Konbu                                           \u00a36.00 False\n  14 Tofu                                           \u00a323.25 False\n  15 Genen Shouyu                                   \u00a315.50 False\n  16 Pavlova                                        \u00a317.45 False\n  17 Alice Mutton                                   \u00a339.00 True\n  18 Carnarvon Tigers                               \u00a362.50 False\n  19 Teatime Chocolate Biscuits                      \u00a39.20 False\n  20 Sir Rodney's Marmalade                         \u00a381.00 False\n------------------------------ Page 2 of 8 ------------------------------\nPress &lt;- to page back, press -&gt; to page forward.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Press the left arrow twice and note it loops around to the last page of results, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">-------------------------------------------------------------------------\n  ID Product Name                               Unit Price Discontinued\n-------------------------------------------------------------------------\n  71 Flotemysost                                    \u00a321.50 False\n  72 Mozzarella di Giovanni                         \u00a334.80 False\n  73 R\u00f6d Kaviar                                     \u00a315.00 False\n  74 Longlife Tofu                                  \u00a310.00 False\n  75 Rh\u00f6nbr\u00e4u Klosterbier                            \u00a37.75 False\n  76 Lakkalik\u00f6\u00f6ri                                   \u00a318.00 False\n  77 Original Frankfurter gr\u00fcne So\u00dfe                \u00a313.00 False\n------------------------------ Page 8 of 8 ------------------------------\nPress &lt;- to page back, press -&gt; to page forward.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Press any other key to end the loop.<\/li>\n<li class=\"calibre3\">Optionally, in <code class=\"calibre9\">Program.Functions.cs<\/code>, in the <code class=\"calibre9\">OutputPageOfProducts<\/code> method, comment out the statement to output the SQL used, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ SectionTitle(pagingQuery.ToQueryString());<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">As an optional task, explore how you might use the <code class=\"calibre9\">Chunk<\/code> method to output pages of products. You can read more about partitioning items in a sequence using <code class=\"calibre9\">Skip<\/code>, <code class=\"calibre9\">Take<\/code>, and <code class=\"calibre9\">Chunk<\/code> at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/partitioning-data\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/linq\/partitioning-data<\/a>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good practice<\/strong>: You should always order data before calling <code class=\"calibre9\">Skip<\/code> and <code class=\"calibre9\">Take<\/code> if you want to implement paging. This is because each time you execute a query, the LINQ provider does not have to guarantee to return the data in the same order unless you have specified it. Therefore, if the SQLite provider wanted to, the first time you request a page of products, they might be in <code class=\"calibre9\">ProductId<\/code> order, but the next time you request a page of products, they might be in <code class=\"calibre9\">UnitPrice<\/code> order, or a random order, and that would confuse the users! In practice, at least for relational databases, the default order is usually by its index on the primary key.<\/p>\n<\/blockquote>\n<\/blockquote>\n<\/section>\n<section data-number=\"12.7.4\" id=\"calibre_link-645\">\n<h3 data-number=\"12.7.4\" class=\"calibre8\">Sweetening LINQ syntax with syntactic sugar<\/h3>\n<p class=\"rights\">C# 3 introduced some new language keywords in 2008 to make it easier for programmers with experience with SQL to write LINQ queries. This syntactic sugar is sometimes called the <strong class=\"calibre2\">LINQ query comprehension syntax<\/strong>.Consider the following array of <code class=\"calibre9\">string<\/code> values:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string[] names = new[] { \"Michael\", \"Pam\", \"Jim\", \"Dwight\", \n  \"Angela\", \"Kevin\", \"Toby\", \"Creed\" };<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To filter and sort the names, you could use extension methods and lambda expressions, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var query = names\n  .Where(name =&gt; name.Length &gt; 4)\n  .OrderBy(name =&gt; name.Length)\n  .ThenBy(name =&gt; name);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Or you could achieve the same results by using query comprehension syntax, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var query = from name in names\n  where name.Length &gt; 4\n  orderby name.Length, name \n  select name;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The compiler changes the query comprehension syntax to the equivalent extension methods and lambda expressions for you.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">select<\/code> keyword is always required for LINQ query comprehension syntax. The <code class=\"calibre9\">Select<\/code> extension method is optional when using extension methods and lambda expressions because if you do not call <code class=\"calibre9\">Select<\/code>, then the whole item is implicitly selected.<\/p>\n<\/blockquote>\n<p class=\"rights\">Not all extension methods have a C# keyword equivalent, for example, the <code class=\"calibre9\">Skip<\/code> and <code class=\"calibre9\">Take<\/code> extension methods, which are commonly used to implement paging for lots of data.A query that skips and takes cannot be written using only the query comprehension syntax, so we could write the query using all extension methods, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var query = names\n  .Where(name =&gt; name.Length &gt; 4)\n  .Skip(80)\n  .Take(10);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Or, we could wrap query comprehension syntax in parentheses and then switch to using extension methods, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var query = (from name in names\n  where name.Length &gt; 4\n  select name)\n  .Skip(80)\n  .Take(10);<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good practice<\/strong>: Learn both extension methods with lambda expressions and the query comprehension syntax ways of writing LINQ queries, because you are likely to have to maintain code that uses both.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"12.8\" id=\"calibre_link-646\">\n<h2 data-number=\"12.8\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring with deeper research into the topics covered in this chapter.<\/p>\n<section data-number=\"12.8.1\" id=\"calibre_link-647\">\n<h3 data-number=\"12.8.1\" class=\"calibre8\">Exercise 11.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the two required parts of LINQ?<\/li>\n<li class=\"calibre3\">Which LINQ extension method would you use to return a subset of properties from a type?<\/li>\n<li class=\"calibre3\">Which LINQ extension method would you use to filter a sequence?<\/li>\n<li class=\"calibre3\">List five LINQ extension methods that perform aggregation.<\/li>\n<li class=\"calibre3\">What is the difference between the <code class=\"calibre9\">Select<\/code> and <code class=\"calibre9\">SelectMany<\/code> extension methods?<\/li>\n<li class=\"calibre3\">What is the difference between <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> and <code class=\"calibre9\">IQueryable&lt;T&gt;<\/code>? How do you switch between them?<\/li>\n<li class=\"calibre3\">What does the last type parameter <code class=\"calibre9\">T<\/code> in generic <code class=\"calibre9\">Func<\/code> delegates like <code class=\"calibre9\">Func&lt;T1, T2, T&gt;<\/code> represent?<\/li>\n<li class=\"calibre3\">What is the benefit of a LINQ extension method that ends with <code class=\"calibre9\">OrDefault<\/code>?<\/li>\n<li class=\"calibre3\">Why is query comprehension syntax optional?<\/li>\n<li class=\"calibre3\">How can you create your own LINQ extension methods?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"12.8.2\" id=\"calibre_link-648\">\n<h3 data-number=\"12.8.2\" class=\"calibre8\">Exercise 11.2 &ndash; Practice querying with LINQ<\/h3>\n<p class=\"rights\">In the <code class=\"calibre9\">Chapter11<\/code> solution, create a console application, named <code class=\"calibre9\">Ch11Ex02LinqQueries<\/code>, that prompts the user for a city and then lists the company names for Northwind customers in that city, as shown in the following output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Enter the name of a city: London \nThere are 6 customers in London: \n  Around the Horn\n  B's Beverages \n  Consolidated Holdings \n  Eastern Connection \n  North\/South\n  Seven Seas Imports<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Then, enhance the application by displaying a list of all unique cities that customers already reside in as a prompt to the user before they enter their preferred city, as shown in the following output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Aachen, Albuquerque, Anchorage, \u00c5rhus, Barcelona, Barquisimeto, Bergamo, Berlin, Bern, Boise, Br\u00e4cke, Brandenburg, Bruxelles, Buenos Aires, Butte, Campinas, Caracas, Charleroi, Cork, Cowes, Cunewalde, Elgin, Eugene, Frankfurt a.M., Gen\u00e8ve, Graz, Helsinki, I. de Margarita, Kirkland, Kobenhavn, K\u00f6ln, Lander, Leipzig, Lille, Lisboa, London, Lule\u00e5, Lyon, Madrid, Mannheim, Marseille, M\u00e9xico D.F., Montr\u00e9al, M\u00fcnchen, M\u00fcnster, Nantes, Oulu, Paris, Portland, Reggio Emilia, Reims, Resende, Rio de Janeiro, Salzburg, San Crist\u00f3bal, San Francisco, Sao Paulo, Seattle, Sevilla, Stavern, Strasbourg, Stuttgart, Torino, Toulouse, Tsawassen, Vancouver, Versailles, Walla Walla, Warszawa<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"12.8.3\" id=\"calibre_link-649\">\n<h3 data-number=\"12.8.3\" class=\"calibre8\">Exercise 11.3 &ndash; Using multiple threads with parallel LINQ<\/h3>\n<p class=\"rights\">You can improve performance and scalability by using multiple threads to run LINQ queries. Learn how by completing the online-only section found at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch11-plinq.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch11-plinq.md<\/a><\/p>\n<\/section>\n<section data-number=\"12.8.4\" id=\"calibre_link-650\">\n<h3 data-number=\"12.8.4\" class=\"calibre8\">Exercise 11.4 &ndash; Working with LINQ to XML<\/h3>\n<p class=\"rights\">If you want to process or generate XML using LINQ, then you can learn the basics of how by completing the online-only section found at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch11-linq-to-xml.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch11-linq-to-xml.md<\/a><\/p>\n<\/section>\n<section data-number=\"12.8.5\" id=\"calibre_link-651\">\n<h3 data-number=\"12.8.5\" class=\"calibre8\">Exercise 11.5 &ndash; Creating your own LINQ extension methods<\/h3>\n<p class=\"rights\">If you want to create your own LINQ extension methods, then you can learn the basics of how by completing the online-only section found at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch11-custom-linq-methods.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch11-custom-linq-methods.md<\/a><\/p>\n<\/section>\n<section data-number=\"12.8.6\" id=\"calibre_link-652\">\n<h3 data-number=\"12.8.6\" class=\"calibre8\">Exercise 11.6 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more details about the topics covered in this chapter:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-11---querying-and-manipulating-data-using-linq\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-11---querying-and-manipulating-data-using-linq<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"12.9\" id=\"calibre_link-653\">\n<h2 data-number=\"12.9\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned how to write LINQ queries to perform common tasks like:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Selecting just the properties of an item that you need.<\/li>\n<li class=\"calibre3\">Filtering items based on conditions.<\/li>\n<li class=\"calibre3\">Sorting items.<\/li>\n<li class=\"calibre3\">Projecting items into different types.<\/li>\n<li class=\"calibre3\">Joining and grouping items.<\/li>\n<li class=\"calibre3\">Aggregating items.<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will be introduced to web development using ASP.NET Core. In the remaining chapters, you will learn how to implement major components of ASP.NET Core like Razor Pages, MVC, Web API, and Blazor.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-941\">\n<div id=\"calibre_link-1938\" class=\"calibre1\">\n<section data-number=\"13\" id=\"calibre_link-654\">\n<h1 data-number=\"13\" class=\"title\">12 Introducing Web Development Using ASP.NET Core<\/h1>\n<section data-number=\"13.1\" id=\"calibre_link-655\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"13.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000015.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">The third and final part of this book is about web development using ASP.NET Core. You will learn how to build cross-platform projects such as websites, web services, and web browser apps.Microsoft calls platforms for building applications <strong class=\"calibre2\">app models<\/strong> or <strong class=\"calibre2\">workloads<\/strong>. I recommend that you work through this and subsequent chapters sequentially because later chapters will reference projects in earlier chapters, and you will build up sufficient knowledge and skills to tackle the trickier problems in later chapters.In this chapter, we will cover the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Understanding ASP.NET Core<\/li>\n<li class=\"calibre3\">New features in ASP.NET Core<\/li>\n<li class=\"calibre3\">Structuring projects<\/li>\n<li class=\"calibre3\">Building an entity model for use in the rest of the book<\/li>\n<li class=\"calibre3\">Understanding web development<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"13.2\" id=\"calibre_link-656\">\n<h2 data-number=\"13.2\" class=\"calibre5\">Understanding ASP.NET Core<\/h2>\n<p class=\"rights\">Since this book is about C# and .NET, we will learn about app models that use them to build the practical applications that we will encounter in the remaining chapters of this book.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: Microsoft has extensive guidance for implementing app models in its <em class=\"calibre10\">.NET Architecture Guides<\/em> documentation, which you can read at the following link: <a href=\"https:\/\/dotnet.microsoft.com\/en-us\/learn\/dotnet\/architecture-guides\">https:\/\/dotnet.microsoft.com\/en-us\/learn\/dotnet\/architecture-guides<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Microsoft ASP.NET Core is part of a history of Microsoft technologies used to build websites and services that have evolved over the years:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Active Server Pages<\/strong> (<strong class=\"calibre2\">ASP<\/strong>) was released in 1996 and was Microsoft's first attempt at a platform for dynamic server-side execution of website code. ASP files contain a mix of HTML and code that execute on the server written in the VBScript language.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">ASP.NET Web Forms<\/strong> was released in 2002 with the .NET Framework and was designed to enable non-web developers, such as those familiar with Visual Basic, to quickly create websites by dragging and dropping visual components and writing event-driven code in Visual Basic or C#. Web Forms should be avoided for new .NET Framework web projects in favor of ASP.NET MVC.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Windows Communication Foundation<\/strong> (<strong class=\"calibre2\">WCF<\/strong>) was released in 2006 and enables developers to build SOAP and REST services. SOAP is powerful but complex, so it should be avoided unless you need advanced features, such as distributed transactions and complex messaging topologies.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">ASP.NET MVC<\/strong> was released in 2009 to cleanly separate the concerns of web developers between the <strong class=\"calibre2\">models<\/strong>, which temporarily store the data; the <strong class=\"calibre2\">views<\/strong>, which present the data using various formats in the UI; and the <strong class=\"calibre2\">controllers<\/strong>, which fetch the model and pass it to a view. This separation enables improved reuse and unit testing.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">ASP.NET Web API<\/strong> was released in 2012 and enables developers to create HTTP services (aka REST services) that are simpler and more scalable than SOAP services.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">ASP.NET SignalR<\/strong> was released in 2013 and enables real-time communication for websites by abstracting underlying technologies and techniques, such as WebSockets and long polling. This enables website features such as live chat or updates to time-sensitive data such as stock prices across a wide variety of web browsers, even when they do not support an underlying technology such as WebSockets.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">ASP.NET Core<\/strong> was released in 2016 and combines modern implementations of .NET Framework technologies such as MVC, Web API, and SignalR, with newer technologies such as Razor Pages, gRPC, and Blazor, all running on modern .NET. Therefore, it can execute cross-platform. ASP.NET Core has many project templates to get you started with its supported technologies.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Choose ASP.NET Core to develop websites and web services because it includes web-related technologies that are modern and cross-platform.<\/p>\n<\/blockquote>\n<section data-number=\"13.2.1\" id=\"calibre_link-657\">\n<h3 data-number=\"13.2.1\" class=\"calibre8\">Classic ASP.NET versus modern ASP.NET Core<\/h3>\n<p class=\"rights\">Until modern .NET, ASP.NET was built on top of a large assembly in .NET Framework named <code class=\"calibre9\">System.Web.dll<\/code> and it was tightly coupled to Microsoft's Windows-only web server named <strong class=\"calibre2\">Internet Information Services<\/strong> (<strong class=\"calibre2\">IIS<\/strong>). Over the years, this assembly has accumulated a lot of features, many of which are not suitable for modern cross-platform development.ASP.NET Core is a major redesign of ASP.NET. It removes the dependency on the <code class=\"calibre9\">System.Web.dll<\/code> assembly and IIS and is composed of modular lightweight packages, just like the rest of modern .NET. Using IIS as the web server is still supported by ASP.NET Core, but there is a better option.You can develop and run ASP.NET Core applications cross-platform on Windows, macOS, and Linux. Microsoft has even created a cross-platform, super-performant web server named <strong class=\"calibre2\">Kestrel<\/strong>, and the entire stack is open source.ASP.NET Core 2.2 or later projects default to the new in-process hosting model. This gives a 400% performance improvement when hosting in Microsoft IIS, but Microsoft still recommends using Kestrel for even better performance.<\/p>\n<\/section>\n<section data-number=\"13.2.2\" id=\"calibre_link-658\">\n<h3 data-number=\"13.2.2\" class=\"calibre8\">Building websites using ASP.NET Core<\/h3>\n<p class=\"rights\">Websites are made up of multiple web pages loaded statically from the filesystem or generated dynamically by a server-side technology such as ASP.NET Core. A web browser makes <code class=\"calibre9\">GET<\/code> requests using <strong class=\"calibre2\">Unique Resource Locators<\/strong> (<strong class=\"calibre2\">URLs<\/strong>) that identify each page and can manipulate data stored on the server using <code class=\"calibre9\">POST<\/code>, <code class=\"calibre9\">PUT<\/code>, and <code class=\"calibre9\">DELETE<\/code> requests.With many websites, the web browser is treated as a presentation layer, with almost all the processing performed on the server side. Some JavaScript might be used on the client side to implement form validation warnings and some presentation features, such as carousels.ASP.NET Core provides multiple technologies for building the user interface for websites:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">ASP.NET Core Razor Pages<\/strong> is a simple way to dynamically generate HTML for simple websites. You will learn about them in detail in <em class=\"calibre10\">Chapter 13<\/em>, <em class=\"calibre10\">Building Websites Using ASP.NET Core Razor Pages<\/em>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">ASP.NET Core MVC<\/strong> is an implementation of the <strong class=\"calibre2\">Model-View-Controller<\/strong> (<strong class=\"calibre2\">MVC<\/strong>) design pattern that is popular for developing complex websites. You will learn about it in detail in <em class=\"calibre10\">Chapter 14<\/em>, <em class=\"calibre10\">Building Websites Using the Model-View-Controller Pattern<\/em>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Blazor<\/strong> lets you build user interface components using C# and .NET instead of a JavaScript-based UI framework like Angular, React, and Vue. Early versions of Blazor required a developer to choose a <strong class=\"calibre2\">hosting model<\/strong>. The <strong class=\"calibre2\">Blazor WebAssembly<\/strong> hosting model runs your code in the browser like a JavaScript-based framework would. The <strong class=\"calibre2\">Blazor Server<\/strong> hosting model runs your code on the server and updates the web page dynamically. Introduced with .NET 8 is a unified, full-stack hosting model that allows individual components to execute either on the server- or client-side, or even adapt dynamically at runtime. You will learn about Blazor in detail in <em class=\"calibre10\">Chapter 16<\/em>, <em class=\"calibre10\">Building User Interfaces Using Blazor<\/em>.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"13.2.3\" id=\"calibre_link-659\">\n<h3 data-number=\"13.2.3\" class=\"calibre8\">Comparison of file types used in ASP.NET Core<\/h3>\n<p class=\"rights\">It is useful to summarize the file types used by these technologies because they are similar but different. If the reader does not understand some subtle but important differences, it can cause much confusion when trying to implement their own projects. Please note the differences in <em class=\"calibre10\">Table 12.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Technology<\/td>\n<td class=\"calibre21\">Special filename<\/td>\n<td class=\"calibre21\">File extension<\/td>\n<td class=\"calibre21\">Directive<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Razor Component (Blazor)<\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">.razor<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Razor Component (Blazor with page routing)<\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">.razor<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">@page<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Razor Page<\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">.cshtml<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">@page<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Razor View (MVC)<\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">.cshtml<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Razor Layout<\/td>\n<td class=\"calibre21\"><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">.cshtml<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Razor View Start<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">_ViewStart<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">.cshtml<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Razor View Imports<\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">_ViewImports<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">.cshtml<\/code><\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 12.1: Comparison of file types used in ASP.NET Core<\/p>\n<p class=\"rights\">Directives like <code class=\"calibre9\">@page<\/code> are added to the top of a file's contents.If a file does not have a special filename, then it can be named anything. For example, you might create a Razor Component for use in a Blazor project named <code class=\"calibre9\">Customer.razor<\/code>, or you might create a Razor Layout for use in an MVC or Razor Pages project named <code class=\"calibre9\">_MobileLayout.cshtml<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The naming convention for shared Razor files like layouts and partial views is to prefix with an underscore <code class=\"calibre9\">_<\/code>. For example, <code class=\"calibre9\">_ViewStart.cshtml<\/code>, <code class=\"calibre9\">_Layout.cshtml<\/code>, or <code class=\"calibre9\">_Product.cshtml<\/code> (this might be a partial view for rendering a product).<\/p>\n<\/blockquote>\n<p class=\"rights\">A Razor Layout file like <code class=\"calibre9\">_MyCustomLayout.cshtml<\/code> is identical to a Razor View. What makes the file a layout is being set as the <code class=\"calibre9\">Layout<\/code> property of another Razor file, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@{\n  Layout = \"_MyCustomLayout\"; \/\/ File extension is not needed.\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Be careful to use the correct file extension and directive at the top of the file or you will get unexpected behavior.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"13.2.4\" id=\"calibre_link-660\">\n<h3 data-number=\"13.2.4\" class=\"calibre8\">Building websites using a content management system<\/h3>\n<p class=\"rights\">Most websites have a lot of content, and if developers had to be involved every time some content needed to be changed, that would not scale well. A <strong class=\"calibre2\">Content Management System<\/strong> (<strong class=\"calibre2\">CMS<\/strong>) enables developers to define content structure and templates to provide consistency and good design while making it easy for a non-technical content owner to manage the actual content. They can create new pages or blocks of content, and update existing content, knowing it will look great for visitors with minimal effort.There are a multitude of CMSs available for all web platforms, like WordPress for PHP or Django CMS for Python. CMSs that support modern .NET include Optimizely Content Cloud, Umbraco, Piranha CMS, and Orchard Core.The key benefit of using a CMS is that it provides a friendly content management user interface. Content owners log in to the website and manage the content themselves. The content is then rendered and returned to visitors using ASP.NET Core MVC controllers and views, or via web service endpoints, known as a <strong class=\"calibre2\">headless CMS<\/strong>, to provide that content to \"heads\" implemented as mobile or desktop apps, in-store touchpoints, or clients built with JavaScript frameworks or Blazor.This book does not cover .NET CMSs, so I have included links where you can learn more about them in the GitHub repository: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#net-content-management-systems\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#net-content-management-systems<\/a>.<\/p>\n<\/section>\n<section data-number=\"13.2.5\" id=\"calibre_link-661\">\n<h3 data-number=\"13.2.5\" class=\"calibre8\">Building web applications using SPA frameworks<\/h3>\n<p class=\"rights\">Web applications are often built using technologies known as <strong class=\"calibre2\">Single-Page Application<\/strong> (<strong class=\"calibre2\">SPA<\/strong>) frameworks, such as Blazor, Angular, React, Vue, or a proprietary JavaScript library. They can make requests to a backend web service to get more data when needed and post updated data using common serialization formats such as XML and JSON. The canonical examples are Google web apps like Gmail, Maps, and Docs.With a web application, the client side uses JavaScript frameworks or Blazor to implement sophisticated user interactions, but most of the important processing and data access still happens on the server side, because the web browser has limited access to local system resources.JavaScript is loosely typed and is not designed for complex projects, so most JavaScript libraries these days use TypeScript, which adds strong typing to JavaScript and is designed with many modern language features for handling complex implementations..NET SDK has project templates for JavaScript and TypeScript-based SPAs, but we will not spend any time learning how to build JavaScript and TypeScript-based SPAs in this book. Even though these SPAs are commonly used with ASP.NET Core as the backend, the focus of this book is on C# and not on other languages.In summary, C# and .NET can be used on both the server side and the client side to build websites, as shown in <em class=\"calibre10\">Figure 12.1<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 12.1: The use of C# and .NET to build websites on both the server and client side\" height=\"325\" src=\"\/images\/cs12\/000109.png\" width=\"927\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 12.1: The use of C# and .NET to build websites on both the server and client side<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"13.2.6\" id=\"calibre_link-662\">\n<h3 data-number=\"13.2.6\" class=\"calibre8\">Building web and other services<\/h3>\n<p class=\"rights\">Although we will not learn about JavaScript and TypeScript-based SPAs, we will learn how to build a web service using the <strong class=\"calibre2\">ASP.NET Core Web API<\/strong>, and then call that web service from the server-side code in our ASP.NET Core websites. Later, we will call that web service from Blazor components and cross-platform mobile and desktop apps.There are no formal definitions, but services are sometimes described based on their complexity:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Service<\/strong>: All functionality needed by a client app in one monolithic service.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Microservice<\/strong>: Multiple services that each focus on a smaller set of functionalities.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Nanoservice<\/strong>: A single function provided as a service. Unlike services and microservices that are hosted 24\/7\/365, nanoservices are often inactive until called upon to reduce resources and costs.<\/li>\n<\/ul>\n<p class=\"rights\">At the start of the first part of this book, we briefly reviewed C# language features and in which versions they were introduced. At the start of the second part of this book, we briefly reviewed .NET library features and in which versions they were introduced. Now, in the third and final part of this book, we will briefly review ASP.NET Core features and in which versions they were introduced.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"13.3\" id=\"calibre_link-663\">\n<h2 data-number=\"13.3\" class=\"calibre5\">New features in ASP.NET Core<\/h2>\n<p class=\"rights\">Over the past few years, Microsoft has rapidly expanded the capabilities of ASP.NET Core. You should note which .NET platforms are supported, as shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">ASP.NET Core 1.0 to 2.2 runs on either .NET Core or .NET Framework.<\/li>\n<li class=\"calibre3\">ASP.NET Core 3.0 or later only runs on .NET Core 3.0 or later.<\/li>\n<\/ul>\n<section data-number=\"13.3.1\" id=\"calibre_link-664\">\n<h3 data-number=\"13.3.1\" class=\"calibre8\">ASP.NET Core 1.0, June 2016<\/h3>\n<p class=\"rights\">Implemented a minimum API suitable for building modern cross-platform web apps and services for Windows, macOS, and Linux.<\/p>\n<\/section>\n<section data-number=\"13.3.2\" id=\"calibre_link-665\">\n<h3 data-number=\"13.3.2\" class=\"calibre8\">ASP.NET Core 1.1, November 2016<\/h3>\n<p class=\"rights\">Focused on bug fixes and general improvements to features and performance.<\/p>\n<\/section>\n<section data-number=\"13.3.3\" id=\"calibre_link-666\">\n<h3 data-number=\"13.3.3\" class=\"calibre8\">ASP.NET Core 2.0, August 2017<\/h3>\n<p class=\"rights\">Added new features such as Razor Pages, bunded assemblies into a <code class=\"calibre9\">Microsoft.AspNetCore.All<\/code> metapackage, targeted .NET Standard 2.0, provided a new authentication model, and added many performance improvements. The biggest new features introduced with ASP.NET Core 2.0 are ASP.NET Core Razor Pages, which is covered in <em class=\"calibre10\">Chapter 13<\/em>, <em class=\"calibre10\">Building Websites Using ASP.NET Core Razor Pages<\/em>, and ASP.NET Core OData support. OData is covered in an online-only chapter of the companion book, <em class=\"calibre10\">Apps and Services with .NET 8<\/em>, and is available at the following link: <a href=\"https:\/\/github.com\/markjprice\/apps-services-net8\/blob\/main\/docs\/ch08-odata.md\">https:\/\/github.com\/markjprice\/apps-services-net8\/blob\/main\/docs\/ch08-odata.md<\/a>.<\/p>\n<\/section>\n<section data-number=\"13.3.4\" id=\"calibre_link-667\">\n<h3 data-number=\"13.3.4\" class=\"calibre8\">ASP.NET Core 2.1, May 2018<\/h3>\n<p class=\"rights\">Added new features such as <strong class=\"calibre2\">SignalR<\/strong> for real-time communication, <strong class=\"calibre2\">Razor class libraries<\/strong> for reusing web components, <strong class=\"calibre2\">ASP.NET Core Identity<\/strong> for authentication, and better support for HTTPS and the European Union's <strong class=\"calibre2\">General Data Protection Regulation<\/strong> (<strong class=\"calibre2\">GDPR<\/strong>), including the topics listed in <em class=\"calibre10\">Table 12.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Razor class libraries<\/td>\n<td class=\"calibre21\">13<\/td>\n<td class=\"calibre21\">Using Razor class libraries<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">GDPR support<\/td>\n<td class=\"calibre21\">14<\/td>\n<td class=\"calibre21\">Creating and exploring an ASP.NET Core MVC website<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Identity UI library and scaffolding<\/td>\n<td class=\"calibre21\">14<\/td>\n<td class=\"calibre21\">Exploring an ASP.NET Core MVC website<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Integration tests<\/td>\n<td class=\"calibre21\">14<\/td>\n<td class=\"calibre21\">Testing an ASP.NET Core MVC website<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">[ApiController]<\/code> , <code class=\"calibre9\">ActionResult&lt;T&gt;<\/code><\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Creating an ASP.NET Core Web API project<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Problem details<\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Implementing a Web API controller<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">IHttpClientFactory<\/code><\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Configuring HTTP clients using <code class=\"calibre9\">HttpClientFactory<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 12.2: Features of ASP.NET Core 2.1 covered in this book<br \/>\n<\/section>\n<section data-number=\"13.3.5\" id=\"calibre_link-668\">\n<h3 data-number=\"13.3.5\" class=\"calibre8\">ASP.NET Core 2.2, December 2018<\/h3>\n<p class=\"rights\">Improved the building of RESTful HTTP APIs, updated the project templates to Bootstrap 4 and Angular 6, an optimized configuration for hosting in Azure, including the topics listed in <em class=\"calibre10\">Table 12.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">HTTP\/2 in Kestrel<\/td>\n<td class=\"calibre21\">13<\/td>\n<td class=\"calibre21\">Classic ASP.NET versus modern ASP.NET Core<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">In-process hosting model<\/td>\n<td class=\"calibre21\">13<\/td>\n<td class=\"calibre21\">Creating an ASP.NET Core project<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Endpoint routing<\/td>\n<td class=\"calibre21\">13<\/td>\n<td class=\"calibre21\">Understanding endpoint routing<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Health Checks Middleware<\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Implementing health checks<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Open API analyzers<\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Implementing Open API analyzers and conventions<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 12.3: Features of ASP.NET Core 2.2 covered in this book<br \/>\n<\/section>\n<section data-number=\"13.3.6\" id=\"calibre_link-669\">\n<h3 data-number=\"13.3.6\" class=\"calibre8\">ASP.NET Core 3.0, September 2019<\/h3>\n<p class=\"rights\">Focused on fully leveraging .NET Core 3.0 and .NET Standard 2.1, which meant it could not support .NET Framework, and it added useful refinements, including the topics listed in <em class=\"calibre10\">Table 12.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Static assets in Razor class libraries<\/td>\n<td class=\"calibre21\">13<\/td>\n<td class=\"calibre21\">Using Razor class libraries<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">New options for MVC service registration<\/td>\n<td class=\"calibre21\">14<\/td>\n<td class=\"calibre21\">Understanding ASP.NET Core MVC startup<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Blazor Server<\/td>\n<td class=\"calibre21\">16<\/td>\n<td class=\"calibre21\">Building components using Blazor Server<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 12.4: Features of ASP.NET Core 3.0 covered in this book<br \/>\n<\/section>\n<section data-number=\"13.3.7\" id=\"calibre_link-670\">\n<h3 data-number=\"13.3.7\" class=\"calibre8\">ASP.NET Core 3.1, December 2019<\/h3>\n<p class=\"rights\">Added refinements like partial class support for Razor components and a new <code class=\"calibre9\">&lt;component&gt;<\/code> tag helper.<\/p>\n<\/section>\n<section data-number=\"13.3.8\" id=\"calibre_link-671\">\n<h3 data-number=\"13.3.8\" class=\"calibre8\">Blazor WebAssembly 3.2, May 2020<\/h3>\n<p class=\"rights\">It was a Current (now known as STS) release, meaning that projects had to be upgraded to the .NET 5 version within three months of the .NET 5 release. Microsoft finally delivered on the promise of full-stack web development with .NET.<\/p>\n<\/section>\n<section data-number=\"13.3.9\" id=\"calibre_link-672\">\n<h3 data-number=\"13.3.9\" class=\"calibre8\">ASP.NET Core 5, November 2020<\/h3>\n<p class=\"rights\">Focused on bug fixes, performance improvements, using caching for certificate authentication, HPACK dynamic compression of HTTP\/2 response headers in Kestrel, nullable annotations for ASP.NET Core assemblies, and a reduction in container image sizes, including the topics listed in <em class=\"calibre10\">Table 12.5<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Extension method to allow anonymous access to an endpoint<\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Securing web services<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">JSON extension methods for <code class=\"calibre9\">HttpRequest<\/code> and <code class=\"calibre9\">HttpResponse<\/code><\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Getting customers as JSON in the controller<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 12.5: Features of ASP.NET Core 5 covered in this book<br \/>\n<\/section>\n<section data-number=\"13.3.10\" id=\"calibre_link-673\">\n<h3 data-number=\"13.3.10\" class=\"calibre8\">ASP.NET Core 6, November 2021<\/h3>\n<p class=\"rights\">Added productivity improvements like minimizing code to implement basic websites and services, support for .NET Hot Reload, and new hosting options for Blazor, like hybrid apps using .NET MAUI, including the topics listed in <em class=\"calibre10\">Table 12.6<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">New empty web project template<\/td>\n<td class=\"calibre21\">13<\/td>\n<td class=\"calibre21\">Understanding the empty web template<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Minimal APIs<\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Implementing minimal Web APIs<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Blazor WebAssembly AOT<\/td>\n<td class=\"calibre21\">16<\/td>\n<td class=\"calibre21\">Enabling Blazor WebAssembly ahead-of-time compilation<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 12.6: Features of ASP.NET Core 6 covered in this book<br \/>\n<\/section>\n<section data-number=\"13.3.11\" id=\"calibre_link-674\">\n<h3 data-number=\"13.3.11\" class=\"calibre8\">ASP.NET Core 7, November 2022<\/h3>\n<p class=\"rights\">Filled well-known gaps in functionality like HTTP\/3 support, output caching, and many quality-of-life improvements to Blazor, including the topics listed in <em class=\"calibre10\">Table 12.7<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">HTTP request decompression<\/td>\n<td class=\"calibre21\">13<\/td>\n<td class=\"calibre21\">Enabling request decompression support<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">HTTP\/3 support<\/td>\n<td class=\"calibre21\">13<\/td>\n<td class=\"calibre21\">Enabling HTTP\/3 support<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Output caching<\/td>\n<td class=\"calibre21\">14<\/td>\n<td class=\"calibre21\">Using a filter to cache output<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">W3C log additional headers<\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Support for logging additional request headers in W3CLogger<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">HTTP\/3 client support<\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Enabling HTTP\/3 support for <code class=\"calibre9\">HttpClient<\/code><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Blazor Empty templates<\/td>\n<td class=\"calibre21\">16<\/td>\n<td class=\"calibre21\">Comparing Blazor project templates<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Location change support<\/td>\n<td class=\"calibre21\">16<\/td>\n<td class=\"calibre21\">Enabling location change event handling<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 12.7: Features of ASP.NET Core 7 covered in this book<br \/>\n<\/section>\n<section data-number=\"13.3.12\" id=\"calibre_link-675\">\n<h3 data-number=\"13.3.12\" class=\"calibre8\">ASP.NET Core 8, November 2023<\/h3>\n<p class=\"rights\">Focused on unifying the Blazor hosting models, including the topics listed in <em class=\"calibre10\">Table 12.8<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Feature<\/td>\n<td class=\"calibre21\">Chapter<\/td>\n<td class=\"calibre21\">Topic<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Route short-circuiting<\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Short-circuit routes in ASP.NET Core 8<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Route tooling enhancements<\/td>\n<td class=\"calibre21\">15<\/td>\n<td class=\"calibre21\">Improved route tooling in ASP.NET Core 8<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">Unification of Blazor hosting<\/td>\n<td class=\"calibre21\">16<\/td>\n<td class=\"calibre21\">All of <em class=\"calibre10\">Chapter 16<\/em> , <em class=\"calibre10\">Building User Interfaces Using Blazor<\/em> .<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 12.8: Features of ASP.NET Core 8 covered in this book<br \/>\n<\/section>\n<\/section>\n<section data-number=\"13.4\" id=\"calibre_link-676\">\n<h2 data-number=\"13.4\" class=\"calibre5\">Structuring projects<\/h2>\n<p class=\"rights\">How should you structure your projects? So far, we have mostly built small individual console apps to illustrate language or library features, with the occasional class library and unit test project to support them. In the rest of this book, we will build multiple projects using different technologies that work together to provide a single solution.With large, complex solutions, it can be difficult to navigate through all the code. So, the primary reason to structure your projects is to make it easier to find components. It is good to have an overall name for your solution that reflects the application or solution.We will build multiple projects for a fictional company named <strong class=\"calibre2\">Northwind<\/strong>. We will name the solution <code class=\"calibre9\">PracticalApps<\/code> and use the name <code class=\"calibre9\">Northwind<\/code> as a prefix for all the project names.There are many ways to structure and name projects and solutions, for example, using a folder hierarchy as well as a naming convention. If you work in a team, make sure you know how your team does it.<\/p>\n<section data-number=\"13.4.1\" id=\"calibre_link-677\">\n<h3 data-number=\"13.4.1\" class=\"calibre8\">Structuring projects in a solution<\/h3>\n<p class=\"rights\">It is good to have a naming convention for your projects in a solution so that any developer can tell what each one does instantly. A common choice is to use the type of project, for example, class library, console app, website, and so on.Since you might want to run multiple web projects at the same time, and they will be hosted on a local web server, we need to differentiate each project by assigning different port numbers for their endpoints for both HTTP and HTTPS. Commonly assigned local port numbers are <code class=\"calibre9\">5000<\/code> for HTTP and <code class=\"calibre9\">5001<\/code> for HTTPS. We will use a numbering convention of <code class=\"calibre9\">5&lt;chapter&gt;0<\/code> for HTTP and <code class=\"calibre9\">5&lt;chapter&gt;1<\/code> for HTTPS. For example, for an MVC website project we will create in <em class=\"calibre10\">Chapter 14<\/em>, we will assign <code class=\"calibre9\">5140<\/code> for HTTP and <code class=\"calibre9\">5141<\/code> for HTTPS.We will therefore use the following project names and port numbers, as shown in <em class=\"calibre10\">Table 12.9<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre25\"><\/col>\n<col class=\"calibre25\"><\/col>\n<col class=\"calibre25\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Name<\/td>\n<td class=\"calibre21\">Ports<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Northwind.Common<\/code><\/td>\n<td class=\"calibre21\">n\/a<\/td>\n<td class=\"calibre21\">A class library project for common types like interfaces, enums, classes, records, and structs, used across multiple projects.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Northwind.EntityModels<\/code><\/td>\n<td class=\"calibre21\">n\/a<\/td>\n<td class=\"calibre21\">A class library project for common EF Core entity models. Entity models are often used on both the server and client side, so it is best to separate dependencies on specific database providers.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Northwind.DataContext<\/code><\/td>\n<td class=\"calibre21\">n\/a<\/td>\n<td class=\"calibre21\">A class library project for the EF Core database context with dependencies on specific database providers.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Northwind.UnitTests<\/code><\/td>\n<td class=\"calibre21\">n\/a<\/td>\n<td class=\"calibre21\">An xUnit test project for the solution.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Northwind.Web<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\"><code class=\"calibre9\">http<\/code> <code class=\"calibre9\">5130<\/code>,<\/p>\n<p class=\"rights\"><code class=\"calibre9\">https<\/code> <code class=\"calibre9\">5131<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">An ASP.NET Core project for a simple website that uses a mixture of static HTML files and dynamic Razor Pages.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Northwind.Mvc<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\"><code class=\"calibre9\">http<\/code> <code class=\"calibre9\">5140<\/code>,<\/p>\n<p class=\"rights\"><code class=\"calibre9\">https<\/code> <code class=\"calibre9\">5141<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">An ASP.NET Core project for a complex website that uses the MVC pattern and can be more easily unit tested.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Northwind.WebApi<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\"><code class=\"calibre9\">http<\/code> <code class=\"calibre9\">5150<\/code>,<\/p>\n<p class=\"rights\"><code class=\"calibre9\">https<\/code> <code class=\"calibre9\">5151<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">An ASP.NET Core project for a Web API aka HTTP service. A good choice for integrating with websites because it can use any JavaScript library or Blazor to interact with the service.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Northwind.MinimalApi<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">http<\/code> <code class=\"calibre9\">5152<\/code><\/td>\n<td class=\"calibre21\">An ASP.NET Core project for a Minimal API aka HTTP service. Unlike Web API projects, these can be compiled using native AOT for improved startup time and reduced memory footprint.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Northwind.Blazor<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\"><code class=\"calibre9\">http<\/code> <code class=\"calibre9\">5160<\/code>,<\/p>\n<p class=\"rights\"><code class=\"calibre9\">https<\/code> <code class=\"calibre9\">5161<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">An ASP.NET Core Blazor project.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 12.9: Example project names for various project types<br \/>\n<\/section>\n<\/section>\n<section data-number=\"13.5\" id=\"calibre_link-678\">\n<h2 data-number=\"13.5\" class=\"calibre5\">Building an entity model for use in the rest of the book<\/h2>\n<p class=\"rights\">Practical applications usually need to work with data in a relational database or another data store. In this section, we will define an entity data model for the Northwind database stored in SQL Server or SQLite. It will be used in most of the apps that we create in subsequent chapters.<\/p>\n<section data-number=\"13.5.1\" id=\"calibre_link-679\">\n<h3 data-number=\"13.5.1\" class=\"calibre8\">Creating the Northwind database<\/h3>\n<p class=\"rights\">The script files for creating the Northwind database for SQLite and SQL Server are different. The script for SQL Server creates 13 tables as well as related views and stored procedures. The script for SQLite is a simplified version that only creates 10 tables because SQLite does not support as many features. The main projects in this book only need those 10 tables so you can complete every task in this book with either database.The SQL scripts are found at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/scripts\/sql-scripts\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/scripts\/sql-scripts<\/a>.There are multiple SQL scripts to choose from, as described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Northwind4Sqlite.sql<\/code> script: To use SQLite on a local Windows, macOS, or Linux computer. This script could probably also be used for other SQL systems like PostgreSQL or MySQL but has not been tested for use with those!<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Northwind4SqlServer.sql<\/code> script: To use SQL Server on a local Windows computer. The script checks if the Northwind database already exists and drops it before creating it.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Northwind4AzureSqlDatabaseCloud.sql<\/code> script: To use SQL Server with an Azure SQL Database resource created in the Azure cloud. These resources cost money as long as they exist! The script does not drop or create the Northwind database because you should manually create the Northwind database using the Azure portal user interface.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Northwind4AzureSqlEdgeDocker.sql<\/code> script: To use SQL Server on a local computer in Docker. The script creates the Northwind database. It does not drop it if it already exists because the Docker container should be empty anyway as a fresh one will be spun up each time.<\/li>\n<\/ul>\n<p class=\"rights\">Instructions to install SQLite can be found in <em class=\"calibre10\">Chapter 10<\/em>, <em class=\"calibre10\">Working with Data Using Entity Framework Core<\/em>. In that chapter, you will also find instructions for installing the <code class=\"calibre9\">dotnet-ef<\/code> tool, which you will use to scaffold an entity model from an existing database.Instructions to install SQL Server Developer Edition (free) on your local Windows computer can be found in the GitHub repository for this book at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/sql-server\/README.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/sql-server\/README.md<\/a>.Instructions to setup Azure SQL Edge in Docker for Windows, macOS, or Linux can be found in the GitHub repository for the companion book at the following link: <a href=\"https:\/\/github.com\/markjprice\/apps-services-net8\/blob\/main\/docs\/ch02-sql-edge.md\">https:\/\/github.com\/markjprice\/apps-services-net8\/blob\/main\/docs\/ch02-sql-edge.md<\/a>.<\/p>\n<\/section>\n<section data-number=\"13.5.2\" id=\"calibre_link-680\">\n<h3 data-number=\"13.5.2\" class=\"calibre8\">Creating a class library for entity models using SQLite<\/h3>\n<p class=\"rights\">You will now define entity data models in a class library so that they can be reused in other types of projects including client-side app models.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You should create a separate class library project for your entity data models. This allows easier sharing between backend web servers and frontend desktop, mobile, and Blazor clients.<\/p>\n<\/blockquote>\n<p class=\"rights\">We will automatically generate some entity models using the EF Core command-line tool:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to create a new project and solution, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Class Library<\/strong> \/ <code class=\"calibre9\">classlib<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">Northwind.EntityModels.Sqlite<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">PracticalApps<\/code><\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.EntityModels.Sqlite<\/code> project, add package references for the SQLite database provider and EF Core design-time support, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;PackageReference Version=\"8.0.0\"\n    Include=\"Microsoft.EntityFrameworkCore.Sqlite\" \/&gt;\n  &lt;PackageReference Version=\"8.0.0\"\n    Include=\"Microsoft.EntityFrameworkCore.Design\"&gt;\n    &lt;PrivateAssets&gt;all&lt;\/PrivateAssets&gt;\n    &lt;IncludeAssets&gt;runtime; build; native; contentfiles; analyzers; buildtransitive&lt;\/IncludeAssets&gt;\n  &lt;\/PackageReference&gt;  \n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Delete the <code class=\"calibre9\">Class1.cs<\/code> file.<\/li>\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.EntityModels.Sqlite<\/code> project to restore packages.<\/li>\n<li class=\"calibre3\">Copy the <code class=\"calibre9\">Northwind4Sqlite.sql<\/code> file into the <code class=\"calibre9\">PracticalApps<\/code> solution folder (not the project folder!).<\/li>\n<li class=\"calibre3\">At a command prompt or terminal in the <code class=\"calibre9\">PracticalApps<\/code> folder, enter a command to create the <code class=\"calibre9\">Northwind.db<\/code> file for SQLite, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">sqlite3 Northwind.db -init Northwind4SQLite.sql<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Be patient because this command might take a while to create the database structure.<\/li>\n<li class=\"calibre3\">To exit SQLite command mode, press <span>Ctrl<\/span> + <span>C<\/span> twice on Windows or <span>Cmd<\/span> + <span>D<\/span> on macOS or Linux.<\/li>\n<li class=\"calibre3\">At a command prompt or terminal in the <code class=\"calibre9\">Northwind.EntityModels.Sqlite<\/code> project folder (the folder that contains the <code class=\"calibre9\">.csproj<\/code> project file), generate entity class models for all tables, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet ef dbcontext scaffold \"Data Source=..\/Northwind.db\" Microsoft.EntityFrameworkCore.Sqlite --namespace Northwind.EntityModels --data-annotations<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The command to perform: <code class=\"calibre9\">dbcontext scaffold<\/code><\/li>\n<li class=\"calibre3\">The connection string refers to the database file in the solution folder, which is one folder up from the current project folder: <code class=\"calibre9\">\"Data Source=..\/Northwind.db\"<\/code><\/li>\n<li class=\"calibre3\">The database provider: <code class=\"calibre9\">Microsoft.EntityFrameworkCore.Sqlite<\/code><\/li>\n<li class=\"calibre3\">The namespace: <code class=\"calibre9\">--namespace Northwind.EntityModels<\/code><\/li>\n<li class=\"calibre3\">To use data annotations as well as the Fluent API: <code class=\"calibre9\">--data-annotations<\/code><\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> <code class=\"calibre9\">dotnet-ef<\/code> commands must be entered all on one line and in a folder that contains a project, or you will see the following error: <code class=\"calibre9\">No project was found. Change the current working directory or use the --project option.<\/code> Remember that all command lines can be found at and copied from the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/command-lines.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/command-lines.md<\/a>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you use SQLite, then you will see warnings about incompatible type mappings between the table columns and properties in the entity class models. For example, <code class=\"calibre9\">The column 'BirthDate' on table 'Employees' should map to a property of type 'DateOnly', but its values are in an incompatible format. Using a different type<\/code>. This is due to SQLite using dynamic types. We will fix those issues in the next section.<\/p>\n<\/blockquote>\n<\/blockquote>\n<\/section>\n<section data-number=\"13.5.3\" id=\"calibre_link-681\">\n<h3 data-number=\"13.5.3\" class=\"calibre8\">Creating a class library for a database context using SQLite<\/h3>\n<p class=\"rights\">You will now define a database context class library:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a new project to the solution, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Class Library<\/strong> \/ <code class=\"calibre9\">classlib<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">Northwind.DataContext.Sqlite<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">PracticalApps<\/code><\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.DataContext.Sqlite<\/code> project, statically and globally import the <code class=\"calibre9\">Console<\/code> class, add a package reference to the EF Core data provider for SQLite, and add a project reference to the <code class=\"calibre9\">Northwind.EntityModels.Sqlite<\/code> project, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Using Include=\"System.Console\" Static=\"true\" \/&gt;\n&lt;\/ItemGroup&gt;\n&lt;ItemGroup&gt;\n  &lt;PackageReference Version=\"8.0.0\"\n    Include=\"Microsoft.EntityFrameworkCore.Sqlite\" \/&gt;\n&lt;\/ItemGroup&gt;\n&lt;ItemGroup&gt;\n  &lt;ProjectReference Include=\"..\\Northwind.EntityModels.Sqlite\n\\Northwind.EntityModels.Sqlite.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> The path to the project reference should not have a line break in your project file.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.DataContext.Sqlite<\/code> project, delete the <code class=\"calibre9\">Class1.cs<\/code> file.<\/li>\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.DataContext.Sqlite<\/code> project to restore packages.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.DataContext.Sqlite<\/code> project, add a class named <code class=\"calibre9\">NorthwindContextLogger.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify its contents to define a static method named <code class=\"calibre9\">WriteLine<\/code> that appends a string to the end of a text file named <code class=\"calibre9\">northwindlog.txt<\/code> on the desktop, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using static System.Environment;\nnamespace Northwind.EntityModels;\npublic class NorthwindContextLogger\n{\n  public static void WriteLine(string message)\n  {\n    string path = Path.Combine(GetFolderPath(\n      SpecialFolder.DesktopDirectory), \"northwindlog.txt\");\n    StreamWriter textFile = File.AppendText(path);\n    textFile.WriteLine(message);\n    textFile.Close();\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Move the <code class=\"calibre9\">NorthwindContext.cs<\/code> file from the <code class=\"calibre9\">Northwind.EntityModels.Sqlite<\/code> project\/folder to the <code class=\"calibre9\">Northwind.DataContext.Sqlite<\/code> project\/folder.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In Visual Studio 2022 <strong class=\"calibre2\">Solution Explorer<\/strong>, if you drag and drop a file between projects, it will be copied. If you hold down <span>Shift<\/span> while dragging and dropping, it will be moved. In Visual Studio Code <strong class=\"calibre2\">EXPLORER<\/strong>, if you drag and drop a file between projects, it will be moved. If you hold down <span>Ctrl<\/span> while dragging and dropping, it will be copied.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">NorthwindContext.cs<\/code>, note the second constructor can have <code class=\"calibre9\">options<\/code> passed as a parameter, which allows us to override the default database connection string in any projects such as websites that need to work with the Northwind database, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public NorthwindContext(DbContextOptions&lt;NorthwindContext&gt; options)\n  : base(options)\n{\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">NorthwindContext.cs<\/code>, in the <code class=\"calibre9\">OnConfiguring<\/code> method, remove the compiler <code class=\"calibre9\">#warning<\/code> about the connection string and then add statements to check the end of the current directory to adjust for when running in Visual Studio 2022 compared to the command prompt with Visual Studio Code, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)\n{\n  if (!optionsBuilder.IsConfigured)\n  {\n    string database = \"Northwind.db\";\n    string dir = Environment.CurrentDirectory;\n    string path = string.Empty;\n    if (dir.EndsWith(\"net8.0\"))\n    {\n      \/\/ In the &lt;project&gt;\\bin\\&lt;Debug|Release&gt;\\net8.0 directory.\n      path = Path.Combine(\"..\", \"..\", \"..\", \"..\", database);\n    }\n    else\n    {\n      \/\/ In the &lt;project&gt; directory.\n      path = Path.Combine(\"..\", database);\n    }\n    path = Path.GetFullPath(path); \/\/ Convert to absolute path.\n    NorthwindContextLogger.WriteLine($\"Database path: {path}\");\n    if (!File.Exists(path))\n    {\n      throw new FileNotFoundException(\n        message: $\"{path} not found.\", fileName: path);\n    }\n    optionsBuilder.UseSqlite($\"Data Source={path}\");\n    optionsBuilder.LogTo(NorthwindContextLogger.WriteLine,\n      new[] { Microsoft.EntityFrameworkCore\n        .Diagnostics.RelationalEventId.CommandExecuting });\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The throwing of the exception is important because if the database file is missing, then the SQLite database provider will create an empty database file, and so if you test connecting to it, it works. But if you query it, then you will see an exception related to missing tables because it does not have any tables! After converting the relative path to an absolute path, you can set a breakpoint while debugging to more easily see where the database file is expected to be or add a statement to log that path.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"13.5.4\" id=\"calibre_link-682\">\n<h3 data-number=\"13.5.4\" class=\"calibre8\">Customizing the model and defining an extension method<\/h3>\n<p class=\"rights\">Now, we will simplify the <code class=\"calibre9\">OnModelCreating<\/code> method. I will briefly explain the individual steps and then show the complete final method. You can either try to perform the individual steps or just use the final method code:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">OnModelCreating<\/code> method, remove all Fluent API statements that call the <code class=\"calibre9\">ValueGeneratedNever<\/code> method, like the one shown in the following code. This will configure primary key properties like <code class=\"calibre9\">CategoryId<\/code> to never generate a value automatically or call the <code class=\"calibre9\">HasDefaultValueSql<\/code> method:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">modelBuilder.Entity&lt;Category&gt;(entity =&gt;\n{\n  entity.Property(e =&gt; e. CategoryId).ValueGeneratedNever();\n});<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If we do not remove the configuration like the statements above, then when we add new suppliers, the <code class=\"calibre9\">CategoryId<\/code> value will always be <code class=\"calibre9\">0<\/code> and we will only be able to add one supplier with that value; all other attempts will throw an exception. You can compare your <code class=\"calibre9\">NorthwindContext.cs<\/code> to the one in the GitHub repository at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.DataContext.Sqlite\/NorthwindContext.cs\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.DataContext.Sqlite\/NorthwindContext.cs<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">OnModelCreating<\/code> method, for the <code class=\"calibre9\">Product<\/code> entity, tell SQLite that the <code class=\"calibre9\">UnitPrice<\/code> can be converted from <code class=\"calibre9\">decimal<\/code> to <code class=\"calibre9\">double<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">entity.Property(product =&gt; product.UnitPrice)\n  .HasConversion&lt;double&gt;();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">The <code class=\"calibre9\">OnModelCreating<\/code> method should now be simpler, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">protected override void OnModelCreating(ModelBuilder modelBuilder)\n{\n  modelBuilder.Entity&lt;Order&gt;(entity =&gt;\n  {\n    entity.Property(e =&gt; e.Freight).HasDefaultValueSql(\"0\");\n  });\n  modelBuilder.Entity&lt;OrderDetail&gt;(entity =&gt;\n  {\n    entity.Property(e =&gt; e.Quantity).HasDefaultValueSql(\"1\");\n    entity.Property(e =&gt; e.UnitPrice).HasDefaultValueSql(\"0\");\n    entity.HasOne(d =&gt; d.Order).WithMany(p =&gt; \n      p.OrderDetails).OnDelete(DeleteBehavior.ClientSetNull);\n    entity.HasOne(d =&gt; d.Product).WithMany(p =&gt; \n      p.OrderDetails).OnDelete(DeleteBehavior.ClientSetNull);\n  });\n  modelBuilder.Entity&lt;Product&gt;(entity =&gt;\n  {\n    entity.Property(e =&gt; e.Discontinued).HasDefaultValueSql(\"0\");\n    entity.Property(e =&gt; e.ReorderLevel).HasDefaultValueSql(\"0\");\n    entity.Property(e =&gt; e.UnitPrice).HasDefaultValueSql(\"0\");\n    entity.Property(e =&gt; e.UnitsInStock).HasDefaultValueSql(\"0\");\n    entity.Property(e =&gt; e.UnitsOnOrder).HasDefaultValueSql(\"0\");\n    entity.Property(product =&gt; product.UnitPrice)\n      .HasConversion&lt;double&gt;();\n  });\n  OnModelCreatingPartial(modelBuilder);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.DataContext.Sqlite<\/code> project, add a class named <code class=\"calibre9\">NorthwindContextExtensions.cs<\/code>. Modify its contents to define an extension method that adds the Northwind database context to a collection of dependency services, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.EntityFrameworkCore; \/\/ To use UseSqlite.\nusing Microsoft.Extensions.DependencyInjection; \/\/ To use IServiceCollection.\nnamespace Northwind.EntityModels;\npublic static class NorthwindContextExtensions\n{\n  \/\/\/ &lt;summary&gt;\n  \/\/\/ Adds NorthwindContext to the specified IServiceCollection. Uses the Sqlite database provider.\n  \/\/\/ &lt;\/summary&gt;\n  \/\/\/ &lt;param name=\"services\"&gt;The service collection.&lt;\/param&gt;\n  \/\/\/ &lt;param name=\"relativePath\"&gt;Default is \"..\"&lt;\/param&gt;\n  \/\/\/ &lt;param name=\"databaseName\"&gt;Default is \"Northwind.db\"&lt;\/param&gt;\n  \/\/\/ &lt;returns&gt;An IServiceCollection that can be used to add more services.&lt;\/returns&gt;\n  public static IServiceCollection AddNorthwindContext(\n    this IServiceCollection services, \/\/ The type to extend.\n    string relativePath = \"..\",\n    string databaseName = \"Northwind.db\")\n  {\n    string path = Path.Combine(relativePath, databaseName);\n    path = Path.GetFullPath(path);\n    NorthwindContextLogger.WriteLine($\"Database path: {path}\");\n    if (!File.Exists(path))\n    {\n      throw new FileNotFoundException(\n        message: $\"{path} not found.\", fileName: path);\n    }\n    services.AddDbContext&lt;NorthwindContext&gt;(options =&gt;\n    {\n      \/\/ Data Source is the modern equivalent of Filename.\n      Options.UseSqlite($\"Data Source={path}\");\n      options.LogTo(NorthwindContextLogger.WriteLine,\n        new[] { Microsoft.EntityFrameworkCore\n          .Diagnostics.RelationalEventId.CommandExecuting });\n    },\n    \/\/ Register with a transient lifetime to avoid concurrency \n    \/\/ issues in Blazor server-side projects.\n    contextLifetime: ServiceLifetime.Transient, \n    optionsLifetime: ServiceLifetime.Transient);\n    return services;\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the two class libraries and fix any compiler errors.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"13.5.5\" id=\"calibre_link-683\">\n<h3 data-number=\"13.5.5\" class=\"calibre8\">Registering the scope of a dependency service<\/h3>\n<p class=\"rights\">By default, a <code class=\"calibre9\">DbContext<\/code> class is registered using <code class=\"calibre9\">Scope<\/code> lifetime, meaning that multiple threads can share the same instance. But <code class=\"calibre9\">DbContext<\/code> does not support multiple threads. If more than one thread attempts to use the same <code class=\"calibre9\">NorthwindContext<\/code> class instance at the same time, then you will see the following runtime exception thrown: <code class=\"calibre9\">A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of a DbContext, however instance members are not guaranteed to be thread safe<\/code>.This happens in Blazor projects with components set to run on the server side because, whenever interactions on the client side happen, a SignalR call is made back to the server where a single instance of the database context is shared between multiple clients. This issue does not occur if a component is set to run on the client side.<\/p>\n<\/section>\n<section data-number=\"13.5.6\" id=\"calibre_link-684\">\n<h3 data-number=\"13.5.6\" class=\"calibre8\">Creating class libraries for entity models using SQL Server<\/h3>\n<p class=\"rights\">If you would like to use SQL Server instead of SQLite, then there are instructions at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/sql-server\/README.md#chapter-12---introducing-web-development-using-aspnet-core\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/sql-server\/README.md#chapter-12---introducing-web-development-using-aspnet-core<\/a><\/p>\n<\/section>\n<section data-number=\"13.5.7\" id=\"calibre_link-685\">\n<h3 data-number=\"13.5.7\" class=\"calibre8\">Improving the class-to-table mapping<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">dotnet-ef<\/code> command-line tool generates different code for SQL Server and SQLite because they support different levels of functionality, and SQLite uses dynamic typing. For example, with EF Core 7, all integer columns in SQLite were mapped to nullable <code class=\"calibre9\">long<\/code> properties for maximum flexibility.With EF Core 8 and later, the actual stored values are checked and if they are all storable in an <code class=\"calibre9\">int<\/code>, it will declare the mapped property as an <code class=\"calibre9\">int<\/code>. If they are all column values storable in a <code class=\"calibre9\">short<\/code>, it will declare the mapped property as a <code class=\"calibre9\">short<\/code>.In this edition, we need to do less work to improve the mapping. Hooray!As another example, SQL Server text columns can have limits on the number of characters. SQLite does not support this. So, <code class=\"calibre9\">dotnet-ef<\/code> will generate validation attributes to ensure <code class=\"calibre9\">string<\/code> properties are limited to a specified number of characters for SQL Server but not for SQLite, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ SQLite database provider-generated code.\n[Column(TypeName = \"nvarchar (15)\")] \npublic string CategoryName { get; set; } = null!;\n\/\/ SQL Server database provider-generated code.\n[StringLength(15)]\npublic string CategoryName { get; set; } = null!;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">We will make some small changes to improve the entity model mapping and validation rules for SQLite. Similar ones for SQL Server are in the online-only instructions.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Remember that all code is available in the GitHub repository for the book. Although you will learn more by typing the code yourself, you never have to. Go to the following link and press <span>.<\/span> to get a live code editor in your browser: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\">https:\/\/github.com\/markjprice\/cs12dotnet8<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">First, we will add a regular expression to validate that a <code class=\"calibre9\">CustomerId<\/code> value is exactly five uppercase letters. Second, we will add string length requirements to validate that multiple properties throughout the entity models know the maximum length allowed for their text values:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Activate your code editor's <strong class=\"calibre2\">Find and Replace<\/strong> feature:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">In Visual Studio 2022, navigate to <strong class=\"calibre2\">Edit<\/strong> | <strong class=\"calibre2\">Find and Replace<\/strong> | <strong class=\"calibre2\">Quick Replace<\/strong>, and then toggle on <strong class=\"calibre2\">Use Regular Expressions<\/strong>.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Type a regular expression in the <strong class=\"calibre2\">Find<\/strong> box, as shown in <em class=\"calibre10\">Figure 12.2<\/em> and in the following expression:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\\[Column\\(TypeName = \"(nchar|nvarchar) \\((.*)\\)\"\\)\\]<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Replace<\/strong> box, type a replacement regular expression, as shown in the following expression:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">$0\\n    [StringLength($2)]<\/code><\/pre>\n<\/div>\n<p class=\"rights\">After the newline character, <code class=\"calibre9\">\\n<\/code>, I have included four space characters to indent correctly on my system, which uses two space characters per indentation level. You can insert as many as you wish.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Set the <strong class=\"calibre2\">Find and Replace<\/strong> to search files in the <strong class=\"calibre2\">Current project<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Execute the <strong class=\"calibre2\">Find and Replace<\/strong> to replace all, as shown in <em class=\"calibre10\">Figure 12.2<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 12.2: Find and replace all matches using regular expressions in Visual Studio 2022\" height=\"959\" src=\"\/images\/cs12\/000127.png\" width=\"2161\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 12.2: Find and replace all matches using regular expressions in Visual Studio 2022<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Change any date\/time columns, for example, in <code class=\"calibre9\">Employee.cs<\/code>, to use a nullable <code class=\"calibre9\">DateTime<\/code> instead of a string, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Before:\n[Column(TypeName = \"datetime\")] \npublic string? BirthDate { get; set; }\n\/\/ After:\n[Column(TypeName = \"datetime\")]\npublic DateTime? BirthDate { get; set; }<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Use your code editor's <strong class=\"calibre2\">Find<\/strong> feature to search for <code class=\"calibre9\">\"datetime\"<\/code> to find all the properties that need changing. There should be two in <code class=\"calibre9\">Employee.cs<\/code> and three in <code class=\"calibre9\">Order.cs<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Change any <code class=\"calibre9\">money<\/code> columns, for example, in <code class=\"calibre9\">Order.cs<\/code>, to use a nullable <code class=\"calibre9\">decimal<\/code> instead of a <code class=\"calibre9\">double<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Before:\n[Column(TypeName =  \"money\")] \npublic double? Freight { get; set; }\n\/\/ After:\n[Column(TypeName = \"money\")]\npublic decimal? Freight { get; set; }<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Use your code editor's <strong class=\"calibre2\">Find<\/strong> feature to search for <code class=\"calibre9\">\"money\"<\/code> to find all the properties that need changing. There should be one in <code class=\"calibre9\">Order.cs<\/code>, one in <code class=\"calibre9\">Orderdetail.cs<\/code>, and one in <code class=\"calibre9\">Product.cs<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Category.cs<\/code>, make the <code class=\"calibre9\">CategoryName<\/code> property required, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[Required]\n[Column(TypeName = \"nvarchar (15)\")]\n[StringLength(15)]\npublic string CategoryName { get; set; }<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Customer.cs<\/code>, add a regular expression to validate its primary key <code class=\"calibre9\">CustomerId<\/code> to only allow uppercase Western characters and make the <code class=\"calibre9\">CompanyName<\/code> property required, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[Key]\n[Column(TypeName = \"nchar (5)\")]\n[StringLength(5)]\n[RegularExpression(\"[A-Z]{5}\")]\npublic string CustomerId { get; set; } = null!;\n[Required]\n[Column(TypeName = \"nvarchar (40)\")]\n[StringLength(40)]\npublic string CompanyName { get; set; }<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Employee.cs<\/code>, make the <code class=\"calibre9\">FirstName<\/code> and <code class=\"calibre9\">LastName<\/code> properties required.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">EmployeeTerritory.cs<\/code>, make the <code class=\"calibre9\">TerritoryId<\/code> property required.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Order.cs<\/code>, decorate the <code class=\"calibre9\">CustomerId<\/code> property with a regular expression to enforce five uppercase characters.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Product.cs<\/code>, make the <code class=\"calibre9\">ProductName<\/code> property required.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Shipper.cs<\/code>, make the <code class=\"calibre9\">CompanyName<\/code> property required.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Supplier.cs<\/code>, make the <code class=\"calibre9\">CompanyName<\/code> property required.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Territory.cs<\/code>, make the <code class=\"calibre9\">TerritoryId<\/code> and <code class=\"calibre9\">TerritoryDescription<\/code> properties required.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"13.5.8\" id=\"calibre_link-686\">\n<h3 data-number=\"13.5.8\" class=\"calibre8\">Testing the class libraries<\/h3>\n<p class=\"rights\">Now let's build some unit tests to ensure the class libraries are working correctly.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> If you are using the SQLite database provider, then when you call the <code class=\"calibre9\">CanConnect<\/code> method with a wrong or missing database file, the provider creates a <code class=\"calibre9\">Northwind.db<\/code> with 0 bytes! This is why it is so important that, in our <code class=\"calibre9\">NorthwindContext<\/code> class, we explicitly check if the database file exists and throw an exception when it is instantiated if it does not exist to prevent this behavior.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's write the tests:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new <strong class=\"calibre2\">xUnit Test Project [C#]<\/strong> \/ <code class=\"calibre9\">xunit<\/code> project named <code class=\"calibre9\">Northwind.UnitTests<\/code> to the <code class=\"calibre9\">PracticalApps<\/code> solution.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.UnitTests<\/code> project, add a project reference to the <code class=\"calibre9\">Northwind.DataContext<\/code> project for either SQLite or SQL Server, as shown highlighted in the following configuration:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;!-- change Sqlite to SqlServer if you prefer --&gt;\n  &lt;ProjectReference Include=\"..\\Northwind.DataContext\n.Sqlite\\Northwind.DataContext.Sqlite.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> The project reference must go all on one line with no line break.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.UnitTests<\/code> project to build referenced projects.<\/li>\n<li class=\"calibre3\">Rename <code class=\"calibre9\">UnitTest1.cs<\/code> to <code class=\"calibre9\">EntityModelTests.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify the contents of the file to define two tests, the first to connect to the database and the second to confirm there are eight categories in the database, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.EntityModels; \/\/ To use NorthwindContext.\nnamespace Northwind.UnitTests\n{\n  public class EntityModelTests\n  {\n    [Fact]\n    public void DatabaseConnectTest()\n    {\n      using NorthwindContext db = new();\n      Assert.True(db.Database.CanConnect());\n    }\n    [Fact]\n    public void CategoryCountTest()\n    {\n      using NorthwindContext db = new();\n      int expected = 8;\n      int actual = db.Categories.Count();\n      Assert.Equal(expected, actual);\n    }\n    [Fact]\n    public void ProductId1IsChaiTest()\n    {\n      using NorthwindContext db = new();\n      string expected = \"Chai\";\n      Product? product = db.Products.Find(keyValues: 1);\n      string actual = product?.ProductName ?? string.Empty;\n      Assert.Equal(expected, actual);\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Run the unit tests:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">If you are using Visual Studio 2022, then navigate to <strong class=\"calibre2\">Test<\/strong> | <strong class=\"calibre2\">Run All Tests<\/strong>, and then view the results in <strong class=\"calibre2\">Test Explorer<\/strong>.<\/li>\n<li class=\"calibre3\">If you are using Visual Studio Code, then in the <code class=\"calibre9\">Northwind.UnitTests<\/code> project's <strong class=\"calibre2\">TERMINAL<\/strong> window, run the tests, as shown in the following command: <code class=\"calibre9\">dotnet test<\/code>, or use the <strong class=\"calibre2\">TESTING<\/strong> window if you have installed C# Dev Kit.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Note that the results should indicate that three tests ran, and all passed. If any of the tests fail, then fix the issue. For example, if you are using SQLite, then check that the <code class=\"calibre9\">Northwind.db<\/code> file is in the solution directory (one up from the project directories). Check the database path in the <code class=\"calibre9\">northwindlog.txt<\/code> file on your desktop which should output the database path it used three times for the three tests, as shown in the following log:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Database path: C:\\cs12dotnet8\\PracticalApps\\Northwind.db\nDatabase path: C:\\cs12dotnet8\\PracticalApps\\Northwind.db\ndbug: 18\/09\/2023 14:20:16.712 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command) \n      Executing DbCommand [Parameters=[@__p_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"QuantityPerUnit\", \"p\".\"ReorderLevel\", \"p\".\"SupplierId\", \"p\".\"UnitPrice\", \"p\".\"UnitsInStock\", \"p\".\"UnitsOnOrder\"\n      FROM \"Products\" AS \"p\"\n      WHERE \"p\".\"ProductId\" = @__p_0\n      LIMIT 1\nDatabase path: C:\\cs12dotnet8\\PracticalApps\\Northwind.db\ndbug: 18\/09\/2023 14:20:16.832 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command) \n      Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']\n      SELECT COUNT(*)\n      FROM \"Categories\" AS \"c\"<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Finally in this chapter, let's review some key concepts about web development so we will be better prepared to dive into ASP.NET Core Razor Pages in the next chapter.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"13.6\" id=\"calibre_link-687\">\n<h2 data-number=\"13.6\" class=\"calibre5\">Understanding web development<\/h2>\n<p class=\"rights\">Developing for the web means developing with <strong class=\"calibre2\">Hypertext Transfer Protocol<\/strong> (<strong class=\"calibre2\">HTTP<\/strong>), so we will start by reviewing this important foundational technology.<\/p>\n<section data-number=\"13.6.1\" id=\"calibre_link-688\">\n<h3 data-number=\"13.6.1\" class=\"calibre8\">Understanding Hypertext Transfer Protocol<\/h3>\n<p class=\"rights\">To communicate with a web server, the client, also known as the <strong class=\"calibre2\">user agent<\/strong>, makes calls over the network using HTTP. As such, HTTP is the technical underpinning of the web. So, when we talk about websites and web services, we mean that they use HTTP to communicate between a client (often a web browser) and a server.A client makes an HTTP request for a resource, such as a page, uniquely identified by a <strong class=\"calibre2\">Uniform Resource Locator<\/strong> (<strong class=\"calibre2\">URL<\/strong>), and the server sends back an HTTP response, as shown in <em class=\"calibre10\">Figure 12.3<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 12.3: An HTTP request and response\" height=\"405\" src=\"\/images\/cs12\/000144.png\" width=\"927\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 12.3: An HTTP request and response<\/figcaption><\/figure>\n<p class=\"rights\">You can use Google Chrome and other browsers to record requests and responses.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Google Chrome is currently used by about two-thirds of website visitors worldwide, and it has powerful, built-in developer tools, so it is a good first choice for testing your websites. Test your websites with Chrome and at least two other browsers, for example, Firefox and Safari for macOS and iPhone. Microsoft Edge switched from using Microsoft's own rendering engine to using Chromium in 2019, so it is less important to test with it, although some say Edge has the best developer tools. If Microsoft's Internet Explorer is used at all, it tends to mostly be inside organizations for intranets.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"13.6.2\" id=\"calibre_link-689\">\n<h3 data-number=\"13.6.2\" class=\"calibre8\">Understanding the components of a URL<\/h3>\n<p class=\"rights\">A <strong class=\"calibre2\">Uniform Resource Locator<\/strong> (<strong class=\"calibre2\">URL<\/strong>) is made up of several components:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Scheme<\/strong>: <code class=\"calibre9\">http<\/code> (clear text) or <code class=\"calibre9\">https<\/code> (encrypted).<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Domain<\/strong>: For a production website or service, the <strong class=\"calibre2\">top-level domain<\/strong> (<strong class=\"calibre2\">TLD<\/strong>) might be <code class=\"calibre9\">example.com<\/code>. You might have subdomains such as <code class=\"calibre9\">www<\/code>, <code class=\"calibre9\">jobs<\/code>, or <code class=\"calibre9\">extranet<\/code>. During development, you typically use <code class=\"calibre9\">localhost<\/code> for all websites and services.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Port number<\/strong>: For a production website or service, <code class=\"calibre9\">80<\/code> for <code class=\"calibre9\">http<\/code>, <code class=\"calibre9\">443<\/code> for <code class=\"calibre9\">https<\/code>. These port numbers are usually inferred from the scheme. During development, other port numbers are commonly used, such as <code class=\"calibre9\">5000<\/code>, <code class=\"calibre9\">5001<\/code>, and so on, to differentiate between websites and services that all use the shared domain <code class=\"calibre9\">localhost<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Path<\/strong>: A relative path to a resource, for example, <code class=\"calibre9\">\/customers\/germany<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Query string<\/strong>: A way to pass parameter values, for example, <code class=\"calibre9\">?country=Germany&amp;searchtext=shoes<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Fragment<\/strong>: A reference to an element on a web page using its <code class=\"calibre9\">id<\/code>, for example, <code class=\"calibre9\">#toc<\/code>.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">URL is a subset of <strong class=\"calibre2\">Uniform Resource Identifier<\/strong> (<strong class=\"calibre2\">URI<\/strong>). A URL specifies where a resource is located and how to get it. A URI identifies a resource either by URL or <strong class=\"calibre2\">URN<\/strong> (<strong class=\"calibre2\">Uniform Resource Name<\/strong>).<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"13.6.3\" id=\"calibre_link-690\">\n<h3 data-number=\"13.6.3\" class=\"calibre8\">Using Google Chrome to make HTTP requests<\/h3>\n<p class=\"rights\">Let's explore how to use Google Chrome to make HTTP requests:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start Google Chrome.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">More tools<\/strong> | <strong class=\"calibre2\">Developer tools<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Click the <strong class=\"calibre2\">Network<\/strong> tab, and Chrome should immediately start recording the network traffic between your browser and any web servers (note the red circle), as shown in <em class=\"calibre10\">Figure 12.4<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 12.4: Chrome Developer tools recording network traffic\" height=\"440\" src=\"\/images\/cs12\/000060.png\" width=\"852\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 12.4: Chrome Developer tools recording network traffic<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">In Chrome's address box, enter the address of Microsoft's website for learning ASP.NET, as shown in the following URL:<\/li>\n<\/ol>\n<p class=\"rights\"><a href=\"https:\/\/dotnet.microsoft.com\/en-us\/learn\/aspnet\">https:\/\/dotnet.microsoft.com\/en-us\/learn\/aspnet<\/a><\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">In <strong class=\"calibre2\">Developer Tools<\/strong>, in the list of recorded requests, scroll to the top and click on the first entry, the row where the <strong class=\"calibre2\">Type<\/strong> is <strong class=\"calibre2\">document<\/strong>, as shown in <em class=\"calibre10\">Figure 12.5<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 12.5: Recorded requests in Developer Tools\" height=\"323\" src=\"\/images\/cs12\/000076.png\" width=\"855\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 12.5: Recorded requests in Developer Tools<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">On the right-hand side, click on the <strong class=\"calibre2\">Headers<\/strong> tab, and you will see details about <strong class=\"calibre2\">Request Headers<\/strong> and <strong class=\"calibre2\">Response Headers<\/strong>, as shown in <em class=\"calibre10\">Figure 12.6<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 12.6: Request and response headers\" height=\"580\" src=\"\/images\/cs12\/000092.png\" width=\"850\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 12.6: Request and response headers<\/figcaption><\/figure>\n<p class=\"rights\">Note the following aspects:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Request Method<\/strong> is <code class=\"calibre9\">GET<\/code>. Other HTTP methods that you could see here include <code class=\"calibre9\">POST<\/code>, <code class=\"calibre9\">PUT<\/code>, <code class=\"calibre9\">DELETE<\/code>, <code class=\"calibre9\">HEAD<\/code>, and <code class=\"calibre9\">PATCH<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Status Code<\/strong> is <code class=\"calibre9\">200 <\/code>OK. This means that the server found the resource that the browser requested and has returned it in the body of the response. Other status codes that you might see in response to a <code class=\"calibre9\">GET<\/code> request include <code class=\"calibre9\">301 Moved Permanently<\/code>, <code class=\"calibre9\">400 Bad Request<\/code>, <code class=\"calibre9\">401 Unauthorized<\/code>, and <code class=\"calibre9\">404 Not Found<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Request Headers<\/strong> sent by the browser to the web server include:<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">accept<\/strong>, which lists what formats the browser accepts. In this case, the browser is saying it understands <code class=\"calibre9\">HTML<\/code>, <code class=\"calibre9\">XHTML<\/code>, <code class=\"calibre9\">XML<\/code>, and some image formats, but it will accept all other files (<code class=\"calibre9\">*\/*<\/code>). Default weightings, also known as quality values, are <code class=\"calibre9\">1.0<\/code>. XML is specified with a quality value of <code class=\"calibre9\">0.9<\/code> so it is preferred less than HTML or XHTML. All other file types are given a quality value of <code class=\"calibre9\">0.8<\/code> so are least preferred.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">accept-encoding<\/strong>, which lists what compression algorithms the browser understands, in this case, <code class=\"calibre9\">GZIP<\/code>, <code class=\"calibre9\">DEFLATE<\/code>, and <code class=\"calibre9\">Brotli<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">accept-language<\/strong>, which lists the human languages it would prefer the content to use. In this case, US English, which has a default quality value of <code class=\"calibre9\">1.0<\/code>, then any dialect of English that has an explicitly specified quality value of <code class=\"calibre9\">0.9<\/code>, and then any dialect of Swedish that has an explicitly specified quality value of <code class=\"calibre9\">0.8<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Response Headers<\/strong>, <code class=\"calibre9\">content-encoding<\/code>, which tells me the server has sent back the HTML web page response compressed using the <code class=\"calibre9\">GZIP<\/code> algorithm because it knows that the client can decompress that format. (This is not visible in <em class=\"calibre10\">Figure 12.6<\/em> because there is not enough space to expand the <strong class=\"calibre2\">Response Headers<\/strong> section.)<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close Chrome.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"13.6.4\" id=\"calibre_link-691\">\n<h3 data-number=\"13.6.4\" class=\"calibre8\">Understanding client-side web development technologies<\/h3>\n<p class=\"rights\">When building websites, a developer needs to know more than just C# and .NET. On the client (that is, in the web browser), you will use a combination of the following technologies:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">HTML5<\/strong>: This is used for the content and structure of a web page.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">CSS3<\/strong>: This is used for the styles applied to elements on the web page.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">JavaScript<\/strong>: This is used to code any business logic needed on the web page, for example, validating form input or making calls to a web service to fetch more data needed by the web page.<\/li>\n<\/ul>\n<p class=\"rights\">Although HTML5, CSS3, and JavaScript are the fundamental components of frontend web development, there are many additional technologies that can make frontend web development more productive, including:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Bootstrap<\/strong>, the world's most popular frontend open-source toolkit.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">SASS<\/strong> and <strong class=\"calibre2\">LESS<\/strong>, CSS preprocessors for styling.<\/li>\n<li class=\"calibre3\">Microsoft's <strong class=\"calibre2\">TypeScript<\/strong> language for writing more robust code.<\/li>\n<li class=\"calibre3\">JavaScript libraries such as <strong class=\"calibre2\">Angular<\/strong>, <strong class=\"calibre2\">jQuery<\/strong>, <strong class=\"calibre2\">React<\/strong>, and <strong class=\"calibre2\">Vue<\/strong>.<\/li>\n<\/ul>\n<p class=\"rights\">All these higher-level technologies ultimately translate or compile to the underlying three core technologies, so they work across all modern browsers.As part of the build and deploy process, you will likely use technologies such as:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Node.js<\/strong>, a framework for server-side development using JavaScript.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Node Package Manager<\/strong> (<strong class=\"calibre2\">npm<\/strong>) and <strong class=\"calibre2\">Yarn<\/strong>, both client-side package managers.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Webpack<\/strong>, a popular module bundler, and a tool for compiling, transforming, and bundling website source files.<\/li>\n<\/ul>\n<\/section>\n<\/section>\n<section data-number=\"13.7\" id=\"calibre_link-692\">\n<h2 data-number=\"13.7\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions and exploring this chapter's topics with deeper research.<\/p>\n<section data-number=\"13.7.1\" id=\"calibre_link-693\">\n<h3 data-number=\"13.7.1\" class=\"calibre8\">Exercise 12.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What was the name of Microsoft's first dynamic server-side executed web page technology and why is it still useful to know this history today?<\/li>\n<li class=\"calibre3\">What are the names of two Microsoft web servers?<\/li>\n<li class=\"calibre3\">What are some differences between a microservice and a nanoservice?<\/li>\n<li class=\"calibre3\">What is Blazor?<\/li>\n<li class=\"calibre3\">What was the first version of ASP.NET Core that could not be hosted on .NET Framework?<\/li>\n<li class=\"calibre3\">What is a user agent?<\/li>\n<li class=\"calibre3\">What impact does the HTTP request-response communication model have on web developers?<\/li>\n<li class=\"calibre3\">Name and describe four components of a URL.<\/li>\n<li class=\"calibre3\">What capabilities does Developer Tools give you?<\/li>\n<li class=\"calibre3\">What are the three main client-side web development technologies and what do they do?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"13.7.2\" id=\"calibre_link-694\">\n<h3 data-number=\"13.7.2\" class=\"calibre8\">Exercise 12.2 &ndash; Know your webbreviations<\/h3>\n<p class=\"rights\">What do the following web abbreviations stand for and what do they do?<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">URI<\/li>\n<li class=\"calibre3\">URL<\/li>\n<li class=\"calibre3\">WCF<\/li>\n<li class=\"calibre3\">TLD<\/li>\n<li class=\"calibre3\">API<\/li>\n<li class=\"calibre3\">SPA<\/li>\n<li class=\"calibre3\">CMS<\/li>\n<li class=\"calibre3\">Wasm<\/li>\n<li class=\"calibre3\">SASS<\/li>\n<li class=\"calibre3\">REST<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"13.7.3\" id=\"calibre_link-695\">\n<h3 data-number=\"13.7.3\" class=\"calibre8\">Exercise 12.3 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more details about the topics covered in this chapter:<\/p>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-12---introducing-web-development-using-aspnet-core\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-12---introducing-web-development-using-aspnet-core<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"13.8\" id=\"calibre_link-696\">\n<h2 data-number=\"13.8\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you have:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Been introduced to some of the app models that you can use to build websites and web services using C# and .NET.<\/li>\n<li class=\"calibre3\">Created class libraries to define an entity data model for working with the Northwind database using SQLite, SQL Server, or both.<\/li>\n<\/ul>\n<p class=\"rights\">In the following chapters, you will learn the details about how to build the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Simple websites using static HTML pages and dynamic Razor Pages.<\/li>\n<li class=\"calibre3\">Complex websites using the MVC design pattern.<\/li>\n<li class=\"calibre3\">Web services that can be called by any platform that can make an HTTP request, and client websites that call those web services.<\/li>\n<li class=\"calibre3\">Blazor user interface components that can be hosted on a web server, in the browser, or on hybrid web-native mobile and desktop apps.<\/li>\n<\/ul>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-939\">\n<div id=\"calibre_link-1939\" class=\"calibre1\">\n<section data-number=\"14\" id=\"calibre_link-697\">\n<h1 data-number=\"14\" class=\"title\">13 Building Websites Using ASP.NET Core Razor Pages<\/h1>\n<section data-number=\"14.1\" id=\"calibre_link-698\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"14.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000009.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about building websites with a modern HTTP architecture on the server side using Microsoft ASP.NET Core. You will learn about building simple websites using the ASP.NET Core Razor Pages feature introduced with ASP.NET Core 2 and the Razor class library feature introduced with ASP.NET Core 2.1.This chapter covers the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Exploring ASP.NET Core<\/li>\n<li class=\"calibre3\">Exploring ASP.NET Core Razor Pages<\/li>\n<li class=\"calibre3\">Using Entity Framework Core with ASP.NET Core<\/li>\n<li class=\"calibre3\">Configuring services and the HTTP request pipeline<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"14.2\" id=\"calibre_link-699\">\n<h2 data-number=\"14.2\" class=\"calibre5\">Exploring ASP.NET Core<\/h2>\n<p class=\"rights\">We will start by creating an empty ASP.NET Core project and explore how to enable it to serve simple web pages.<\/p>\n<section data-number=\"14.2.1\" id=\"calibre_link-700\">\n<h3 data-number=\"14.2.1\" class=\"calibre8\">Creating an empty ASP.NET Core project<\/h3>\n<p class=\"rights\">We will create an ASP.NET Core project that will show a list of suppliers from the Northwind database.The <code class=\"calibre9\">dotnet<\/code> tool has many project templates that do a lot of work for you, but it can be difficult to know which works best for a given situation, so we will start with the empty website project template and then add features step by step so that you can understand all the pieces:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Use your preferred code editor to open the <code class=\"calibre9\">PracticalApps<\/code> solution and then add a new project, as defined in the following list:<\/p>\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">ASP.NET Core Empty [C#]<\/strong> \/ <code class=\"calibre9\">web<\/code>. For JetBrains Rider, select the project template named <strong class=\"calibre2\">ASP.NET Core Web Application<\/strong>, and then set the <strong class=\"calibre2\">Type<\/strong> to <strong class=\"calibre2\">Empty<\/strong>.<\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">Northwind.Web<\/code>.<\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">PracticalApps<\/code>.<\/li>\n<li class=\"calibre3\">For Visual Studio 2022, leave all other options as their defaults, for example, <strong class=\"calibre2\">Framework<\/strong>: <strong class=\"calibre2\">.NET 8.0 (Long Term Support)<\/strong>, <strong class=\"calibre2\">Configure for HTTPS<\/strong>: selected, <strong class=\"calibre2\">Enable Docker<\/strong>: cleared, and <strong class=\"calibre2\">Do not use top-level statements<\/strong>: cleared.<\/li>\n<li class=\"calibre3\">For Visual Studio Code and the <code class=\"calibre9\">dotnet new web<\/code> command, the defaults are the options we want. In future projects, if you want to change from top-level statements to the old <code class=\"calibre9\">Program<\/code> class style, then specify the switch <code class=\"calibre9\">--use-program-main<\/code>.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Summaries of Visual Studio 2022 and <code class=\"calibre9\">dotnet new<\/code> options when creating new projects can be found in the GitHub repository at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch01-project-options.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch01-project-options.md<\/a>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.Web<\/code> project.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Northwind.Web.csproj<\/code>, note the project is like a class library except that the SDK is <code class=\"calibre9\">Microsoft.NET.Sdk.Web<\/code>, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Project Sdk=\"Microsoft.NET.Sdk.Web\"&gt;\n  &lt;PropertyGroup&gt;\n    &lt;TargetFramework&gt;net8.0&lt;\/TargetFramework&gt;\n    &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n    &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n  &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add an element to import the <code class=\"calibre9\">System.Console<\/code> class globally and statically.<\/li>\n<li class=\"calibre3\">If you are using Visual Studio 2022, in <strong class=\"calibre2\">Solution Explorer<\/strong>, toggle <strong class=\"calibre2\">Show All Files<\/strong>. If you are using JetBrains Rider, then mouse cursor over the <strong class=\"calibre2\">Solution<\/strong> pane, then click the \"eyeball\" icon.<\/li>\n<li class=\"calibre3\">Expand the <code class=\"calibre9\">obj<\/code> folder, expand the <code class=\"calibre9\">Debug<\/code> folder, expand the <code class=\"calibre9\">net8.0<\/code> folder, select the <code class=\"calibre9\">Northwind.Web.GlobalUsings.g.cs<\/code> file, and note how the implicitly imported namespaces include all the ones for a console app or class library, as well as some ASP.NET Core ones, such as <code class=\"calibre9\">Microsoft.AspNetCore.Builder<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ &lt;autogenerated \/&gt;\nglobal using global::Microsoft.AspNetCore.Builder;\nglobal using global::Microsoft.AspNetCore.Hosting;\nglobal using global::Microsoft.AspNetCore.Http;\nglobal using global::Microsoft.AspNetCore.Routing;\nglobal using global::Microsoft.Extensions.Configuration;\nglobal using global::Microsoft.Extensions.DependencyInjection;\nglobal using global::Microsoft.Extensions.Hosting;\nglobal using global::Microsoft.Extensions.Logging;\nglobal using global::System;\nglobal using global::System.Collections.Generic;\nglobal using global::System.IO;\nglobal using global::System.Linq;\nglobal using global::System.Net.Http;\nglobal using global::System.Net.Http.Json;\nglobal using global::System.Threading;\nglobal using global::System.Threading.Tasks;\nglobal using static global::System.Console;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close the file and collapse the <code class=\"calibre9\">obj<\/code> folder.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Web<\/code> project\/folder, expand the folder named <code class=\"calibre9\">Properties<\/code>, open the file named <code class=\"calibre9\">launchSettings.json<\/code>, and note the profiles named <code class=\"calibre9\">http<\/code> and <code class=\"calibre9\">https<\/code>. They have randomly assigned port numbers that you will change in the next step, so for now just note their locations, as shown highlighted in the following configuration:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"$schema\": \"http:\/\/json.schemastore.org\/launchsettings.json\",\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http:\/\/localhost:14842\",\n      \"sslPort\": 44352\n    }\n  },\n  \"profiles\": {\n    \"http\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchBrowser\": true,\n      \"applicationUrl\": \"http:\/\/localhost:5122\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    },\n    \"https\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchBrowser\": true,\n      \"applicationUrl\": \"https:\/\/localhost:7155;http:\/\/localhost:5122\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    },\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">launchSettings.json<\/code> file is only for use during development. It has no effect on the build process. It is not deployed with the compiled website project, so it has no effect on the production runtime. It is only processed by code editors like Visual Studio 2022 and JetBrains Rider to set up environment variables and define URLs for the web server to listen on when the project is started by a code editor.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">For the <code class=\"calibre9\">https<\/code> profile, for its <code class=\"calibre9\">applicationUrl<\/code>, change the assigned port numbers for <code class=\"calibre9\">http<\/code> to <code class=\"calibre9\">5130<\/code> and <code class=\"calibre9\">https<\/code> to <code class=\"calibre9\">5131<\/code>, and swap the order so <code class=\"calibre9\">http<\/code> is first in the list so it will be used by default, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\"applicationUrl\": \"http:\/\/localhost:5130;https:\/\/localhost:5131\",<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">http<\/code> and <code class=\"calibre9\">https<\/code> launch profiles have a <code class=\"calibre9\">commandName<\/code> of <code class=\"calibre9\">Project<\/code>, meaning they use the web server configured in the project to host the website, which is Kestrel by default. There is also a profile and settings for IIS, which is a Windows-only web server. In this book, we will only use Kestrel as the web server since it is cross-platform. To declutter your <code class=\"calibre9\">launchSettings.json<\/code> file you could even delete the <code class=\"calibre9\">iisSettings<\/code> and <code class=\"calibre9\">IIS Express<\/code> sections.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, note the following:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">An ASP.NET Core project is like a top-level console app, with a hidden <code class=\"calibre9\">&lt;Main&gt;$<\/code> method as its entry point that has an argument passed using the name <code class=\"calibre9\">args<\/code>.<\/li>\n<li class=\"calibre3\">It calls <code class=\"calibre9\">WebApplication.CreateBuilder<\/code>, which creates a host for the website using defaults for a web host that is then built.<\/li>\n<li class=\"calibre3\">The website will respond to all HTTP <code class=\"calibre9\">GET<\/code> requests with plain text: <code class=\"calibre9\">Hello World!<\/code>.<\/li>\n<li class=\"calibre3\">The call to the <code class=\"calibre9\">Run<\/code> method is a blocking call, so the hidden <code class=\"calibre9\">&lt;Main&gt;$<\/code> method does not return until the web server stops running.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p class=\"rights\">The contents of <code class=\"calibre9\">Program.cs<\/code> are shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var builder = WebApplication.CreateBuilder(args);\nvar app = builder.Build();\napp.MapGet(\"\/\", () =&gt; \"Hello World!\");\napp.Run();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of <code class=\"calibre9\">Program.cs<\/code>, add a comment to explain the <code class=\"calibre9\">Run<\/code> method and a statement to write a message to the console after <code class=\"calibre9\">Run<\/code> and therefore after the web server has stopped, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Start the web server, host the website, and wait for requests.\napp.Run(); \/\/ This is a thread-blocking call.\nWriteLine(\"This executes after the web server has stopped!\");<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"14.2.2\" id=\"calibre_link-701\">\n<h3 data-number=\"14.2.2\" class=\"calibre8\">Testing and securing the website<\/h3>\n<p class=\"rights\">We will now test the functionality of the ASP.NET Core Empty website project. We will also enable encryption of all traffic between the browser and web server for privacy by switching from HTTP to HTTPS. HTTPS is the secure encrypted version of HTTP.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">For Visual Studio 2022:\n<ol class=\"toc1\">\n<li class=\"calibre3\">\n<p class=\"rights\">In the toolbar, make sure that the <strong class=\"calibre2\">https<\/strong> profile is selected (rather than <strong class=\"calibre2\">http<\/strong>, <strong class=\"calibre2\">IIS Express<\/strong>, or <strong class=\"calibre2\">WSL<\/strong>), and then change <strong class=\"calibre2\">Web Browser<\/strong> to <strong class=\"calibre2\">Google Chrome<\/strong>, as shown in <em class=\"calibre10\">Figure 13.1<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 13.1: Selecting the https profile with its Kestrel web server in Visual Studio\" height=\"826\" src=\"\/images\/cs12\/000026.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 13.1: Selecting the https profile with its Kestrel web server in Visual Studio<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Without Debugging\u2026.<\/strong><\/li>\n<li class=\"calibre3\">On Windows, if you see a <strong class=\"calibre2\">Windows Security Alert<\/strong> saying <strong class=\"calibre2\">Windows Defender Firewall has blocked some features of this app<\/strong>, then click the <strong class=\"calibre2\">Allow access<\/strong> button.<\/li>\n<li class=\"calibre3\">The first time you start a secure website, you might be prompted that your project is configured to use SSL, and to avoid warnings in the browser, you can choose to trust the self-signed certificate that ASP.NET Core has generated. Click <strong class=\"calibre2\">Yes<\/strong>. When you see the <strong class=\"calibre2\">Security Warning<\/strong> dialog box, click <strong class=\"calibre2\">Yes<\/strong> again.<\/li>\n<\/ol>\n<\/li>\n<li class=\"calibre3\">For Visual Studio Code, enter the command to start the project with the <code class=\"calibre9\">https<\/code> profile, like this: <code class=\"calibre9\">dotnet run --launch-profile https<\/code>. Then start Chrome.<\/li>\n<li class=\"calibre3\">For JetBrains Rider:\n<ol class=\"toc1\">\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Run<\/strong> | <strong class=\"calibre2\">Edit Configurations\u2026<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Run\/Debug Configurations<\/strong> dialog box, select <strong class=\"calibre2\">Northwind.Web: https<\/strong>.<\/li>\n<li class=\"calibre3\">At the bottom of the dialog box, to the right of the <strong class=\"calibre2\">After launch<\/strong> check box, select <strong class=\"calibre2\">Chrome<\/strong> and then click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Run<\/strong> | <strong class=\"calibre2\">Run 'Northwind.Web: https'<\/strong>.<\/li>\n<\/ol>\n<\/li>\n<li class=\"calibre3\">In either Visual Studio's command prompt window or Visual Studio Code's terminal, note the following, as shown in the following output:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">The web server has started listening on the ports we assigned for HTTP and HTTPS.<\/li>\n<li class=\"calibre3\">You can press <span>Ctrl<\/span> + <em class=\"calibre10\"><\/em> <span>C<\/span> to shut down the Kestrel web server.<\/li>\n<li class=\"calibre3\">The hosting environment is <code class=\"calibre9\">Development<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">info: Microsoft.Hosting.Lifetime[14]\n  Now listening on: http:\/\/localhost:5130\ninfo: Microsoft.Hosting.Lifetime[14]\n  Now listening on: https:\/\/localhost:5131\ninfo: Microsoft.Hosting.Lifetime[0]\n  Application started. Press Ctrl+C to shut down.\ninfo: Microsoft.Hosting.Lifetime[0]\n  Hosting environment: Development\ninfo: Microsoft.Hosting.Lifetime[0]\n  Content root path: C:\\cs12dotnet8\\PracticalApps\\Northwind.Web<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Visual Studio 2022 will also start your chosen browser automatically and navigate to the first URL. If you are using Visual Studio Code, you will have to start Chrome manually.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Leave the Kestrel web server running in the command prompt or terminal.<\/li>\n<li class=\"calibre3\">In Chrome, show <strong class=\"calibre2\">Developer Tools<\/strong>, and click the <strong class=\"calibre2\">Network<\/strong> tab.<\/li>\n<li class=\"calibre3\">Request the home page for the website project:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">If you are using Visual Studio 2022 and Chrome launched automatically with the URL already entered for you, then click the <strong class=\"calibre2\">Reload this page<\/strong> button or press <span>F5<\/span>.<\/li>\n<li class=\"calibre3\">If you are using Visual Studio Code and the command prompt or terminal, then in the Chrome address bar, manually enter the address <code class=\"calibre9\">http:\/\/localhost:5130\/<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <strong class=\"calibre2\">Network<\/strong> tab, click <strong class=\"calibre2\">localhost<\/strong>, and note the response is <strong class=\"calibre2\">Hello World!<\/strong> in plain text, from the cross-platform Kestrel web server, as shown in <em class=\"calibre10\">Figure 13.2<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 13.2: Plain text response from the website project\" height=\"540\" src=\"\/images\/cs12\/000044.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 13.2: Plain text response from the website project<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Browsers like Chrome might also request a <code class=\"calibre9\">favicon.ico<\/code> file to show in their browser window or tab, but this file does not exist in our project, so it shows as a <strong class=\"calibre2\">404 Not Found<\/strong> error. If this annoys you, then you can generate a <code class=\"calibre9\">favicon.ico<\/code> file for free at the following link and put it in the project folder: <a href=\"https:\/\/favicon.io\/\">https:\/\/favicon.io\/<\/a>. On a web page, you can also specify one in the meta tags, for example, a blank one using Base64 encoding, as shown in the following markup:<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><code class=\"calibre9\">&lt;link rel=\"icon\" href=\"data:;base64,iVBORw0KGgo=\"&gt;<\/code><\/p>\n<\/blockquote>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Enter the address <code class=\"calibre9\">https:\/\/localhost:5131\/<\/code> and note that if you are not using Visual Studio 2022 or if you clicked <strong class=\"calibre2\">No<\/strong> when prompted to trust the SSL certificate, then the response is a privacy error. You will see this error when you have not configured a certificate that the browser can trust to encrypt and decrypt HTTPS traffic (if you do not see this error, it is because you have already configured a certificate). In a production environment, you would want to pay a company such as Verisign for an SSL certificate because they provide liability protection and technical support. During development, you can tell your OS to trust a temporary development certificate provided by ASP.NET Core.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">For Linux Developers<\/strong>: If you use a Linux variant that cannot create self-signed certificates or you do not mind reapplying for a new certificate every 90 days, then you can get a free certificate from the following link: <a href=\"https:\/\/letsencrypt.org\">https:\/\/letsencrypt.org<\/a>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">At the command prompt or terminal, press <span>Ctrl<\/span> + <span>C<\/span> to shut down the web server, and note the message that is written, as shown highlighted in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">info: Microsoft.Hosting.Lifetime[0]\n      Application is shutting down...<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This executes after the web server has stopped!<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">C:\\cs12dotnet8\\PracticalApps\\Northwind.Web\\bin\\Debug\\net8.0\\Northwind.Web.exe (process 19888) exited with code 0.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you need to trust a local self-signed SSL certificate, then at the command line or terminal, enter the following command: <code class=\"calibre9\">dotnet dev-certs https --trust<\/code>.<\/li>\n<li class=\"calibre3\">Note the message <strong class=\"calibre2\">Trusting the HTTPS development certificate was requested<\/strong>. You might be prompted to enter your password and a valid HTTPS certificate may already be present.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"14.2.3\" id=\"calibre_link-702\">\n<h3 data-number=\"14.2.3\" class=\"calibre8\">Enabling stronger security and redirecting to a secure connection<\/h3>\n<p class=\"rights\">It is good practice to enable stricter security and automatically redirect requests for HTTP to HTTPS.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: An optional but recommended security enhancement is <strong class=\"calibre2\">HTTP Strict Transport Security<\/strong> (<strong class=\"calibre2\">HSTS<\/strong>), which you should always enable. If a website specifies it and a browser supports it, then it forces all communication over HTTPS and prevents the visitor from using untrusted or invalid certificates.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's do that now:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, after the statement that builds the <code class=\"calibre9\">app<\/code>, add a region and an <code class=\"calibre9\">if<\/code> statement to enable HSTS when <em class=\"calibre10\">not<\/em> in development, and redirect HTTP requests to HTTPS, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var builder = WebApplication.CreateBuilder(args);\nvar app = builder.Build();\n#region Configure the HTTP pipeline and routes\nif (!app.Environment.IsDevelopment())\n{\n  app.UseHsts();\n}\napp.UseHttpsRedirection();\napp.MapGet(\"\/\", () =&gt; \"Hello World!\");\n#endregion\n\/\/ Start the web server, host the website, and wait for requests.\napp.Run(); \/\/ This is a thread-blocking call.\nWriteLine(\"This executes after the web server has stopped!\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Web<\/code> website project without debugging using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">If Chrome is still running, close and restart it.<\/li>\n<li class=\"calibre3\">In Chrome, show <strong class=\"calibre2\">Developer Tools<\/strong>, and click the <strong class=\"calibre2\">Network<\/strong> tab.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Enter the address <code class=\"calibre9\">http:\/\/localhost:5130\/<\/code>, and note how the server responds with a <strong class=\"calibre2\">307 Temporary Redirect<\/strong> to <code class=\"calibre9\">https:\/\/localhost:5131\/<\/code>, and that the certificate is valid and trusted, as shown in <em class=\"calibre10\">Figure 13.3<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 13.3: The connection is now secured using a valid certificate and a 307 redirect\" height=\"539\" src=\"\/images\/cs12\/000136.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 13.3: The connection is now secured using a valid certificate and a 307 redirect<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Remember to shut down the Kestrel web server by switching to the command prompt or terminal and pressing <span>Ctrl<\/span> + <span>C<\/span> whenever you have finished testing a website.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"14.2.4\" id=\"calibre_link-703\">\n<h3 data-number=\"14.2.4\" class=\"calibre8\">Controlling the hosting environment<\/h3>\n<p class=\"rights\">In ASP.NET Core 5 and earlier, the project template sets a rule to say that while in development mode, any unhandled exceptions will be shown in the browser window for the developer to see the details of the exception, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">if (app.Environment.IsDevelopment())\n{\n  app.UseDeveloperExceptionPage();\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">With ASP.NET Core 6 and later, this code is executed automatically so it is no longer included in the project template <code class=\"calibre9\">Program.cs<\/code> source code.How does ASP.NET Core know when we are running in development mode so that the <code class=\"calibre9\">IsDevelopment<\/code> method returns <code class=\"calibre9\">true<\/code>, and this extra code executes to set up the developer exception page? Let's find out.ASP.NET Core can read from settings files and environment variables to determine what hosting environment to use, for example, <code class=\"calibre9\">DOTNET_ENVIRONMENT<\/code> or <code class=\"calibre9\">ASPNETCORE_ENVIRONMENT<\/code>.You can override these settings during local development:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Web<\/code> folder, expand the folder named <code class=\"calibre9\">Properties<\/code>, and open the file named <code class=\"calibre9\">launchSettings.json<\/code>. Note the <code class=\"calibre9\">https<\/code> launch profile sets the environment variable for the hosting environment to <code class=\"calibre9\">Development<\/code>, as shown highlighted in the following configuration:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\"https\": {\n  \"commandName\": \"Project\",\n  \"dotnetRunMessages\": true,\n  \"launchBrowser\": true,\n  \"applicationUrl\": \"https:\/\/localhost:5131;http:\/\/localhost:5130\",\n  \"environmentVariables\": {\n    \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n  }\n},<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Change the <code class=\"calibre9\">ASPNETCORE_ENVIRONMENT<\/code> environment variable from <code class=\"calibre9\">Development<\/code> to <code class=\"calibre9\">Production<\/code>.<\/li>\n<li class=\"calibre3\">If you are using Visual Studio 2022, optionally, change <code class=\"calibre9\">launchBrowser<\/code> to <code class=\"calibre9\">false<\/code> to prevent Visual Studio from automatically launching a browser. This setting is ignored when you start a website project using <code class=\"calibre9\">dotnet run<\/code> or JetBrains Rider.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, modify the <code class=\"calibre9\">MapGet<\/code> statement, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.MapGet(\"\/\", () =&gt; \n  $\"Environment is {app.Environment.EnvironmentName}\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the website project using the <code class=\"calibre9\">https<\/code> launch profile and note the hosting environment is <code class=\"calibre9\">Production<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">info: Microsoft.Hosting.Lifetime[0]\n  Hosting environment: Production<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Chrome, note that the plain text is <code class=\"calibre9\">Environment is Production<\/code>.<\/li>\n<li class=\"calibre3\">Shut down the web server.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">launchSettings.json<\/code>, change the environment variable back to <code class=\"calibre9\">Development<\/code>.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about environments at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/environments\">https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/environments<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"14.2.5\" id=\"calibre_link-704\">\n<h3 data-number=\"14.2.5\" class=\"calibre8\">Enabling a website to serve static content<\/h3>\n<p class=\"rights\">A website that only ever returns a single plain text message isn't very useful!At a minimum, it ought to return static HTML pages, CSS that the web pages will use for styling, and any other static resources, such as images and videos.By convention, these files should be stored in a directory named <code class=\"calibre9\">wwwroot<\/code> to keep them separate from the dynamically executing parts of your website project.<\/p>\n<\/section>\n<section data-number=\"14.2.6\" id=\"calibre_link-705\">\n<h3 data-number=\"14.2.6\" class=\"calibre8\">Creating a folder for static files and a web page<\/h3>\n<p class=\"rights\">You will now create a folder for your static website resources and a basic index page that uses Bootstrap for styling:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Web<\/code> project\/folder, create a folder named <code class=\"calibre9\">wwwroot<\/code>. Note that Visual Studio 2022 recognizes it as a special type of folder by giving it a globe icon <img loading=\"lazy\" decoding=\"async\" height=\"30\" src=\"\/images\/cs12\/000152.png\" width=\"30\" class=\"calibre12\" \/>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">wwwroot<\/code> folder, add a new file named <code class=\"calibre9\">index.xhtml<\/code>. (In Visual Studio 2022, the project item template is named <strong class=\"calibre2\">HTML Page<\/strong>.)<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">index.xhtml<\/code>, modify its markup to link to CDN-hosted Bootstrap for styling, and use modern good practices such as setting the viewport, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;!doctype html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n  &lt;!-- Required meta tags --&gt;\n  &lt;meta charset=\"utf-8\" \/&gt;\n  &lt;meta name=\"viewport\" content=\n    \"width=device-width, initial-scale=1, shrink-to-fit=no\" \/&gt;\n  &lt;!-- Bootstrap CSS --&gt;\n  &lt;link href=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.3.0\/dist\/css\/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM\" crossorigin=\"anonymous\"&gt;\n  &lt;title&gt;Welcome ASP.NET Core!&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n  &lt;div class=\"container\"&gt;\n    &lt;div class=\"jumbotron\"&gt;\n      &lt;h1 class=\"display-3\"&gt;Welcome to Northwind B2B&lt;\/h1&gt;\n      &lt;p class=\"lead\"&gt;We supply products to our customers.&lt;\/p&gt;\n      &lt;hr \/&gt;\n      &lt;h2&gt;This is a static HTML page.&lt;\/h2&gt;\n      &lt;p&gt;Our customers include restaurants, hotels, and cruise lines.&lt;\/p&gt;\n      &lt;p&gt;\n        &lt;a class=\"btn btn-primary\" \n          href=\"https:\/\/www.asp.net\/\"&gt;Learn more&lt;\/a&gt;\n      &lt;\/p&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Check the latest version at the following link: <a href=\"https:\/\/getbootstrap.com\/docs\/versions\/\">https:\/\/getbootstrap.com\/docs\/versions\/<\/a>. Click the latest version to go to its <strong class=\"calibre2\">Get started with Bootstrap<\/strong> page. Scroll down the page to Step 2 to find the latest <code class=\"calibre9\">&lt;link&gt;<\/code> and <code class=\"calibre9\">&lt;script&gt;<\/code> elements, which you can then copy and paste.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"14.2.7\" id=\"calibre_link-706\">\n<h3 data-number=\"14.2.7\" class=\"calibre8\">Enabling static and default files<\/h3>\n<p class=\"rights\">If you were to start the website now and enter <code class=\"calibre9\">http:\/\/localhost:5130\/index.xhtml<\/code> or <code class=\"calibre9\">https:\/\/localhost:5131\/index.xhtml<\/code> in the address box, the website would return a <code class=\"calibre9\">404 Not Found<\/code> error saying no web page was found. To enable the website to return static files such as <code class=\"calibre9\">index.xhtml<\/code>, we must explicitly configure that feature.Even if we enable static files, if you were to start the website and enter <code class=\"calibre9\">http:\/\/localhost:5130\/<\/code> or <code class=\"calibre9\">https:\/\/localhost:5131\/<\/code> in the address box, the website will still return a <code class=\"calibre9\">404 Not Found<\/code> error because the web server does not know what to return by default if no named file is requested.You will now enable static files, explicitly configure default files, and change the URL path registered that returns the plain text <code class=\"calibre9\">Hello World!<\/code> response:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements after enabling HTTPS redirection to enable static files and default files. Also, modify the statement that maps a <code class=\"calibre9\">GET<\/code> request to return the plain text response containing the environment name to only respond to the URL path <code class=\"calibre9\">\/hello<\/code>, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.UseDefaultFiles(); \/\/ index.xhtml, default.xhtml, and so on.\napp.UseStaticFiles();\napp.MapGet(\"\/hello\", () =&gt; \n  $\"Environment is {app.Environment.EnvironmentName}\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> The call to <code class=\"calibre9\">UseDefaultFiles<\/code> must come before the call to <code class=\"calibre9\">UseStaticFiles<\/code>, or it will not work! You will learn more about the ordering of middleware and endpoint routing at the end of this chapter.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the website.<\/li>\n<li class=\"calibre3\">Start Chrome and show <strong class=\"calibre2\">Developer Tools<\/strong>.<\/li>\n<li class=\"calibre3\">In Chrome, enter <code class=\"calibre9\">http:\/\/localhost:5130\/<\/code> and note that you are redirected to the HTTPS address on port <code class=\"calibre9\">5131<\/code>, and the <code class=\"calibre9\">index.xhtml<\/code> file is now returned over that secure connection because it is one of the possible default files for this website and it was the first match found in the <code class=\"calibre9\">wwwroot<\/code> folder.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">Developer Tools<\/strong>, note the request for the Bootstrap stylesheet.<\/li>\n<li class=\"calibre3\">In Chrome, enter <code class=\"calibre9\">http:\/\/localhost:5130\/hello<\/code> and note that it returns the plain text environment name as before.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<p class=\"rights\">If all web pages are static, that is, they only get changed manually by a web editor, then our website programming work is complete. But almost all websites need dynamic content, which means a web page that is generated at runtime by executing code.The easiest way to do that is to use a feature of ASP.NET Core named <strong class=\"calibre2\">Razor Pages<\/strong>. But before that, let's understand why you might see additional requests in tools like <strong class=\"calibre2\">Developer Tools<\/strong> that you don't expect.<\/p>\n<\/section>\n<section data-number=\"14.2.8\" id=\"calibre_link-707\">\n<h3 data-number=\"14.2.8\" class=\"calibre8\">Understanding browser requests during development<\/h3>\n<p class=\"rights\">In <strong class=\"calibre2\">Developer Tools<\/strong>, we can see all the requests made by the browser. Some will be requests that you expect, for example:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">localhost<\/strong>: This is the request for the home page in the website project. For our current project, the address will be <code class=\"calibre9\">http:\/\/localhost:5130\/<\/code> or <code class=\"calibre9\">https:\/\/localhost:5131\/<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">bootstrap.min.css<\/strong>: This is the request for Bootstrap's styles. We added a reference to this on the home page, so the browser then made this request for the stylesheet.<\/li>\n<\/ul>\n<p class=\"rights\">Some of the requests are made only during development and are determined by the code editor that you use. You can usually ignore them if you see them in <strong class=\"calibre2\">Developer Tools<\/strong>. For example:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">browserLink<\/strong> and <strong class=\"calibre2\">aspnetcore-browser-refresh.js<\/strong>: These are requests made by Visual Studio 2022 to connect the browser to Visual Studio for debugging and Hot Reload. For example: <code class=\"calibre9\">https:\/\/localhost:5131\/_vs\/browserLink<\/code> and <code class=\"calibre9\">https:\/\/localhost:5131\/_framework\/aspnetcore-browser-refresh.js<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">negotiate?requestUrl<\/strong>, <strong class=\"calibre2\">connect?transport<\/strong>, <strong class=\"calibre2\">abort?Transport<\/strong>, and so on: These are additional requests used to connect Visual Studio 2022 with the browser.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Northwind.Web\/<\/strong>: This is a secure WebSockets request related to SignalR used to connect Visual Studio 2022 with the browser: <code class=\"calibre9\">wss:\/\/localhost:44396\/Northwind.Web\/<\/code>.<\/li>\n<\/ul>\n<p class=\"rights\">Now that you have seen how to set up a basic website with support for static files like HTML web pages and CSS stylesheets, let's make it more interesting by adding support for dynamic web pages. The simplest technology for dynamic web pages is ASP.NET Core Razor Pages.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"14.3\" id=\"calibre_link-708\">\n<h2 data-number=\"14.3\" class=\"calibre5\">Exploring ASP.NET Core Razor Pages<\/h2>\n<p class=\"rights\">ASP.NET Core Razor Pages allow a developer to easily mix C# code statements with HTML markup to make the generated web page dynamic. That is why Razor Pages use the <code class=\"calibre9\">.cshtml<\/code> file extension.By convention, ASP.NET Core looks for Razor Pages in a folder named <code class=\"calibre9\">Pages<\/code>.<\/p>\n<section data-number=\"14.3.1\" id=\"calibre_link-709\">\n<h3 data-number=\"14.3.1\" class=\"calibre8\">Enabling Razor Pages<\/h3>\n<p class=\"rights\">You will now copy and change the static HTML page into a dynamic Razor Page, and then add and enable the Razor Pages service:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Web<\/code> project folder, create a folder named <code class=\"calibre9\">Pages<\/code>.<\/li>\n<li class=\"calibre3\">Copy the <code class=\"calibre9\">index.xhtml<\/code> file into the <code class=\"calibre9\">Pages<\/code> folder. (In Visual Studio 2022 or JetBrains Rider, hold down <span>Ctrl<\/span> while dragging and dropping.)<\/li>\n<li class=\"calibre3\">For the file in the <code class=\"calibre9\">Pages<\/code> folder, rename the file extension for <code class=\"calibre9\">index.xhtml<\/code> from <code class=\"calibre9\">.xhtml<\/code> to <code class=\"calibre9\">.cshtml<\/code>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Pages<\/code> folder, in <code class=\"calibre9\">index.cshtml<\/code>, add the <code class=\"calibre9\">@page<\/code> directive to the top of the file.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">index.cshtml<\/code>, remove the <code class=\"calibre9\">&lt;h2&gt;<\/code> element that says that this is a static HTML page.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, after the statement that creates the <code class=\"calibre9\">builder<\/code>, add a statement to add ASP.NET Core Razor Pages and its related services, such as model binding, authorization, anti-forgery, views, and tag helpers, and optionally define a <code class=\"calibre9\">#region<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Configure the web server host and services.\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.Services.AddRazorPages();\nvar app = builder.Build();\n#endregion<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, before the statement that maps an HTTP <code class=\"calibre9\">GET<\/code> request for the path <code class=\"calibre9\">\/hello<\/code>, add a statement to call the <code class=\"calibre9\">MapRazorPages<\/code> method, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.MapRazorPages();\napp.MapGet(\"\/\", () =&gt; \n  $\"Environment is {app.Environment.EnvironmentName}\");<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> If you have installed ReSharper for Visual Studio, or you use JetBrains Rider, then they might give warnings like \"Cannot resolve symbol\" in your Razor Pages, Razor views, and Blazor components. This does not always mean there is an actual problem. If the file compiles, then you can ignore their errors. Sometimes the poor things get confused and needlessly worry developers.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">In Chrome, enter <code class=\"calibre9\">https:\/\/localhost:5131\/<\/code> and note the element that says that this is a static HTML page is gone. If it is still there, then you might have to empty the browser cache. View <strong class=\"calibre2\">Developer Tools<\/strong>, click and hold on the <strong class=\"calibre2\">Reload this page<\/strong> button, and then select <strong class=\"calibre2\">Empty cache and hard reload<\/strong>, as shown in <em class=\"calibre10\">Figure 13.4<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 13.4: View Developer Tools, then click and hold the Reload button to see more commands\" height=\"248\" src=\"\/images\/cs12\/000171.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 13.4: View Developer Tools, then click and hold the Reload button to see more commands<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"14.3.2\" id=\"calibre_link-710\">\n<h3 data-number=\"14.3.2\" class=\"calibre8\">Adding code to a Razor Page<\/h3>\n<p class=\"rights\">In the HTML markup of a web page, Razor syntax is indicated by the <code class=\"calibre9\">@<\/code> symbol. Razor Pages can be described as follows:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">\n<p class=\"rights\">Razor Pages requires the <code class=\"calibre9\">@page<\/code> directive at the top of the file.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> <em class=\"calibre10\">Razor Pages<\/em> are different from <em class=\"calibre10\">Razor Views<\/em> (used in ASP.NET Core MVC) but they share the same <code class=\"calibre9\">.cshtml<\/code> file extension. <em class=\"calibre10\">Razor Pages<\/em> must have the <code class=\"calibre9\">@page<\/code> directive. <em class=\"calibre10\">Razor Views<\/em> must not use the <code class=\"calibre9\">@page<\/code> directive.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Razor Pages can optionally have an <code class=\"calibre9\">@functions<\/code> section that defines any of the following:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Properties for storing data values, like in a class definition. An instance of that class is automatically instantiated, named <code class=\"calibre9\">Model<\/code>, which can have its properties set in special methods, and you can get the property values in the HTML.<\/li>\n<li class=\"calibre3\">Methods named <code class=\"calibre9\">OnGet<\/code>, <code class=\"calibre9\">OnPost<\/code>, <code class=\"calibre9\">OnDelete<\/code>, and so on that execute when HTTP requests are made, such as <code class=\"calibre9\">GET<\/code>, <code class=\"calibre9\">POST<\/code>, and <code class=\"calibre9\">DELETE<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Razor Pages markup can have comments using <code class=\"calibre9\">@*<\/code> and <code class=\"calibre9\">*@<\/code>, as shown in the following code: <code class=\"calibre9\">@* This is a comment. *@<\/code>.<\/li>\n<\/ul>\n<p class=\"rights\">Let's now add some dynamic content to the Razor Page using a <code class=\"calibre9\">@functions<\/code> code block:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Pages<\/code> folder, in <code class=\"calibre9\">index.cshtml<\/code>, make modifications as specified in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">After the <code class=\"calibre9\">@page<\/code> directive, add an <code class=\"calibre9\">@functions<\/code> statement block.<\/li>\n<li class=\"calibre3\">Define a property to store the name of the current day as a <code class=\"calibre9\">string<\/code> value.<\/li>\n<li class=\"calibre3\">Define a method to set <code class=\"calibre9\">DayName<\/code> that executes when a <code class=\"calibre9\">GET<\/code> request is made for the page, as shown in the following code:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page\n@functions\n{\n  public string? DayName { get; set; }\n  public void OnGet()\n  {\n    DayName = DateTime.Now.ToString(\"dddd\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the second HTML paragraph, <code class=\"calibre9\">&lt;p&gt;<\/code>, render the day name, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;p&gt;It's @DayName! Our customers include restaurants, hotels, and cruise lines.&lt;\/p&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">When you define properties in a <code class=\"calibre9\">@functions<\/code> block, you are adding code to an automatically generated class named <code class=\"calibre9\">Pages_&lt;razorpagename&gt;<\/code>. In this case, the class name would be <code class=\"calibre9\">Pages_index<\/code>. The class is automatically given a property named <code class=\"calibre9\">Model<\/code> that represents itself. You can use <code class=\"calibre9\">DayName<\/code>, <code class=\"calibre9\">this.DayName<\/code>, or <code class=\"calibre9\">Model.DayName<\/code> to refer to the property in the code or in the HTML markup. However, JetBrains Rider and ReSharper will give errors if you use <code class=\"calibre9\">Model.DayName<\/code> even though that syntax is valid, compiles, and runs.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the website project using the <code class=\"calibre9\">https<\/code> profile.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In Chrome, if necessary, enter <code class=\"calibre9\">https:\/\/localhost:5131\/<\/code>, and note the current day name is output on the page, as shown in <em class=\"calibre10\">Figure 13.5<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 13.5: Welcome to Northwind page showing the current day\" height=\"429\" src=\"\/images\/cs12\/000087.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 13.5: Welcome to Northwind page showing the current day<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">In Chrome, enter <code class=\"calibre9\">https:\/\/localhost:5131\/index.xhtml<\/code>, which exactly matches the static filename, and note that it returns the static HTML page as before.<\/li>\n<li class=\"calibre3\">In Chrome, enter <code class=\"calibre9\">https:\/\/localhost:5131\/hello<\/code>, which exactly matches the endpoint route that returns plain text, and note that it returns the plain text <strong class=\"calibre2\"><\/strong> as before.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"14.3.3\" id=\"calibre_link-711\">\n<h3 data-number=\"14.3.3\" class=\"calibre8\">Using shared layouts with Razor Pages<\/h3>\n<p class=\"rights\">Most websites have more than one page. If every page had to contain all of the boilerplate markup that is currently in <code class=\"calibre9\">index.cshtml<\/code>, that would become a pain to manage. So, ASP.NET Core has a feature named <strong class=\"calibre2\">layouts<\/strong>.To use layouts, we must create a Razor file to define the default layout for all Razor Pages (and all MVC views) and store it in a <code class=\"calibre9\">Shared<\/code> folder so that it can be easily found by convention. The name of this file can be anything, because we will specify it, but <code class=\"calibre9\">_Layout.cshtml<\/code> is good practice.We must also create a specially named file to set the default layout file for all Razor Pages (and all MVC views). This file <em class=\"calibre10\">must<\/em> be named <code class=\"calibre9\">_ViewStart.cshtml<\/code>.Let's see layouts in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Pages<\/code> folder, add a file named <code class=\"calibre9\">_ViewStart.cshtml<\/code>. (The Visual Studio 2022 project item template is named <strong class=\"calibre2\">Razor View Start<\/strong>.)<\/li>\n<li class=\"calibre3\">If you are using Visual Studio Code, modify the <code class=\"calibre9\">_ViewStart.cshtml<\/code> file content, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@{\n  Layout = \"_Layout\";\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Pages<\/code> folder, create a folder named <code class=\"calibre9\">Shared<\/code>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Shared<\/code> folder, create a file named <code class=\"calibre9\">_Layout.cshtml<\/code>. (The Visual Studio item template is named <strong class=\"calibre2\">Razor Layout<\/strong>.)<\/li>\n<li class=\"calibre3\">Modify the content of <code class=\"calibre9\">_Layout.cshtml<\/code>. It is similar to <code class=\"calibre9\">index.cshtml<\/code>, so you can copy and paste the HTML markup from there, and then make the changes, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;!doctype html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n  &lt;!-- Required meta tags --&gt;\n  &lt;meta charset=\"utf-8\" \/&gt;\n  &lt;meta name=\"viewport\" content=\n    \"width=device-width, initial-scale=1, shrink-to-fit=no\" \/&gt;\n  &lt;!-- Bootstrap CSS --&gt;\n  &lt;link href=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.3.0\/dist\/css\/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM\" crossorigin=\"anonymous\"&gt;\n  &lt;title&gt;@ViewData[\"Title\"]&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n  &lt;div class=\"container\"&gt;\n    @RenderBody()\n    &lt;hr \/&gt;\n    &lt;footer&gt;\n      &lt;p&gt;Copyright \u00a9 2023 - @ViewData[\"Title\"]&lt;\/p&gt;\n    &lt;\/footer&gt;\n  &lt;\/div&gt;\n  &lt;!-- JavaScript to enable features like carousel --&gt;\n  &lt;script src=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.3.0\/dist\/js\/bootstrap.bundle.min.js\" integrity=\"sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb\/j\/68SIy3Te4Bkz\" crossorigin=\"anonymous\"&gt;&lt;\/script&gt;\n  @RenderSection(\"Scripts\", required: false)\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">While reviewing the preceding markup, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">&lt;title&gt;<\/code> is set dynamically using server-side code by reading from a dictionary named <code class=\"calibre9\">ViewData<\/code>. This is a simple way to pass data between different parts of an ASP.NET Core website. In this case, the title value will be set in a Razor Page class file and then output in the shared layout.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">@RenderBody()<\/code> marks the insertion point for the view being requested.<\/li>\n<li class=\"calibre3\">A horizontal rule and footer will appear at the bottom of each page.<\/li>\n<li class=\"calibre3\">At the bottom of the layout is a script to implement some cool features of Bootstrap that we can use later, such as a carousel of images.<\/li>\n<li class=\"calibre3\">After the <code class=\"calibre9\">&lt;script&gt;<\/code> elements for Bootstrap, we have defined a section named <code class=\"calibre9\">Scripts<\/code> so that a Razor Page can optionally inject additional scripts that it needs.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">index.cshtml<\/code>, remove all HTML markup except <code class=\"calibre9\">&lt;div class=\"jumbotron\"&gt;<\/code> and its contents, and leave the C# code in the <code class=\"calibre9\">@functions<\/code> block that you added earlier. Add a statement to the <code class=\"calibre9\">OnGet<\/code> method to set a page title in the <code class=\"calibre9\">ViewData<\/code> dictionary, and modify the button to navigate to a suppliers page (which we will create in the next section), as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \n@functions\n{\n  public string? DayName { get; set; }\n  public void OnGet()\n  {\n    ViewData[\"Title\"] = \"Northwind B2B\";\n    DayName = DateTime.Now.ToString(\"dddd\");\n  }\n}\n&lt;div class=\"jumbotron\"&gt;\n  &lt;h1 class=\"display-3\"&gt;Welcome to @ViewData[\"Title\"]&lt;\/h1&gt;\n  &lt;p class=\"lead\"&gt;We supply products to our customers.&lt;\/p&gt;\n  &lt;hr \/&gt;\n  &lt;p&gt;It's @DayName! Our customers include restaurants, hotels, and cruise lines.&lt;\/p&gt;\n  &lt;p&gt;\n    &lt;a class=\"btn btn-primary\" href=\"suppliers\"&gt;\n      Learn more about our suppliers\n    &lt;\/a&gt;\n  &lt;\/p&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the website using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Visit it with Chrome and note that it has a similar behavior to before, although clicking the button for suppliers will give a <code class=\"calibre9\">404 Not Found<\/code> error because we have not created that page yet.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"14.3.4\" id=\"calibre_link-712\">\n<h3 data-number=\"14.3.4\" class=\"calibre8\">Temporarily storing data<\/h3>\n<p class=\"rights\">You often need to temporarily store data in a shared location that can then be accessed in other components of the website. This allows one part of the website to share data with another. For example, a specific page could share data with a layout for it to render, or one page could share data with another.There are two useful dictionaries that you can write and read to:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">ViewData<\/code>: This dictionary exists during the lifetime of a single HTTP request. A component of the website, like a controller or a specific page, can store some data in it that can then be read by another component of the website, like a view or a shared layout, that executes later in that same request process. It is named <code class=\"calibre9\">ViewData<\/code> because it is mostly used to store information that will later be needed for rendering in a Razor page or view.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">TempData<\/code>: This dictionary exists during the lifetime of an HTTP request and the next HTTP request from the same browser. This allows a part of the website, like a controller, to store some data in it, respond to the browser with a redirect, and then another part of the website can read the data on the second request. Only the browser that made the original request can access this data.<\/li>\n<\/ul>\n<p class=\"rights\">For example, a typical <code class=\"calibre9\">ViewData<\/code> scenario is shown in <em class=\"calibre10\">Figure 13.6<\/em> and includes the following steps:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">A browser makes a request for a page like the home page.<\/li>\n<li class=\"calibre3\">Middleware could store some information about the request in the <code class=\"calibre9\">ViewData<\/code> dictionary. (You will learn more about middleware later in this chapter.)<\/li>\n<li class=\"calibre3\">The controller could store some data needed by the request, like a list of categories, in the <code class=\"calibre9\">ViewData<\/code> dictionary. (You will learn about controllers in <em class=\"calibre10\">Chapter 14<\/em>, <em class=\"calibre10\">Building Websites Using the Model-View-Controller Pattern<\/em>.)<\/li>\n<li class=\"calibre3\">The page could store its title in the <code class=\"calibre9\">ViewData<\/code> dictionary.<\/li>\n<li class=\"calibre3\">The shared layout could read the title from the <code class=\"calibre9\">ViewData<\/code> dictionary and render it in the <code class=\"calibre9\">&lt;title&gt;<\/code> element in the <code class=\"calibre9\">&lt;head&gt;<\/code> section of the web page.<\/li>\n<li class=\"calibre3\">The page could read the information about the request and the data from the <code class=\"calibre9\">ViewData<\/code> dictionary and render it in appropriate elements of the web page.<\/li>\n<li class=\"calibre3\">The web page is returned as HTML to the browser.<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 13.6: Using ViewData to share information during a single request\" height=\"1121\" src=\"\/images\/cs12\/000102.png\" width=\"2060\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 13.6: Using ViewData to share information during a single request<\/figcaption><\/figure>\n<p class=\"rights\">For example, a typical <code class=\"calibre9\">TempData<\/code> scenario is shown in <em class=\"calibre10\">Figure 13.7<\/em> and includes the following steps:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">A browser makes a request for a page like the home page.<\/li>\n<li class=\"calibre3\">Middleware or a controller could store some information about the request in the <code class=\"calibre9\">TempData<\/code> dictionary and then respond with status code 307 to tell the browser to make a second request.<\/li>\n<li class=\"calibre3\">The browser makes a second request, for example, for the page of orders.<\/li>\n<li class=\"calibre3\">A controller could read the data stored in <code class=\"calibre9\">TempData<\/code> to process the request.<\/li>\n<li class=\"calibre3\">A Razor Page, Razor View, or Razor Layout could read the data stored in <code class=\"calibre9\">TempData<\/code> and render it to HTML.<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 13.7: Using TempData to share information between two requests\" height=\"746\" src=\"\/images\/cs12\/000120.png\" width=\"2050\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 13.7: Using TempData to share information between two requests<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"14.3.5\" id=\"calibre_link-713\">\n<h3 data-number=\"14.3.5\" class=\"calibre8\">Using code-behind files with Razor Pages<\/h3>\n<p class=\"rights\">Sometimes, it is better to separate the HTML markup from the data and executable code because it is more organized that way. Razor Pages allows you to do this by putting the C# code in <strong class=\"calibre2\">code-behind<\/strong> class files. They have the same name as the <code class=\"calibre9\">.cshtml<\/code> file but end with <code class=\"calibre9\">.cshtml.cs<\/code>.You will now create a Razor Page that shows a list of suppliers. In this example, we are focusing on learning about code-behind files. In the next topic, we will load the list of suppliers from a database, but for now, we will simulate that with a hardcoded array of <code class=\"calibre9\">string<\/code> values:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Pages<\/code> folder, add a new Razor Page file named <code class=\"calibre9\">Suppliers.cshtml<\/code>:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">If you are using Visual Studio 2022 or JetBrains Rider, then the project item template is named <strong class=\"calibre2\">Razor Page - Empty<\/strong> and it creates both a markup file and a code-behind file named <code class=\"calibre9\">Suppliers.cshtml<\/code> and <code class=\"calibre9\">Suppliers.cshtml.cs<\/code> respectively.<\/li>\n<li class=\"calibre3\">If you are using Visual Studio Code, then you will need to create two new files named <code class=\"calibre9\">Suppliers.cshtml<\/code> and <code class=\"calibre9\">Suppliers.cshtml.cs<\/code> manually, or you can use <code class=\"calibre9\">dotnet new<\/code> in the <code class=\"calibre9\">Pages<\/code> folder, as shown in the following command:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new page -n Suppliers --namespace Northwind.Web.Pages<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Suppliers.cshtml.cs<\/code>, add statements to define a property to store a list of supplier company names and populate it when an HTTP <code class=\"calibre9\">GET<\/code> request for this page is made, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.AspNetCore.Mvc.RazorPages; \/\/ To use PageModel.\nnamespace Northwind.Web.Pages;\npublic class SuppliersModel : PageModel\n{\n  public IEnumerable&lt;string&gt;? Suppliers { get; set; }\n  public void OnGet()\n  {\n    ViewData[\"Title\"] = \"Northwind B2B - Suppliers\";\n    Suppliers = new[]\n    {\n      \"Alpha Co\", \"Beta Limited\", \"Gamma Corp\"\n    };\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> If you are using JetBrains Rider, then it names the class <code class=\"calibre9\">Suppliers<\/code>. I recommend that you rename it <code class=\"calibre9\">SuppliersModel<\/code>.<\/p>\n<\/blockquote>\n<p class=\"rights\">While reviewing the preceding markup, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">SuppliersModel<\/code> inherits from <code class=\"calibre9\">PageModel<\/code>, so it has members such as the <code class=\"calibre9\">ViewData<\/code> dictionary for sharing data. You can right-click on <code class=\"calibre9\">PageModel<\/code> and select <strong class=\"calibre2\">Go To Definition<\/strong> to see that it has lots more useful features, such as the entire <code class=\"calibre9\">HttpContext<\/code> of the current request.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">SuppliersModel<\/code> defines a property for storing a collection of <code class=\"calibre9\">string<\/code> values named <code class=\"calibre9\">Suppliers<\/code>.<\/li>\n<li class=\"calibre3\">When an HTTP <code class=\"calibre9\">GET<\/code> request is made for this Razor Page, the <code class=\"calibre9\">OnGet<\/code> method executes and the <code class=\"calibre9\">Suppliers<\/code> property is populated with some example supplier names from an array of <code class=\"calibre9\">string<\/code> values. Later, we will populate this from the Northwind database.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Suppliers.cshtml<\/code>, replace the existing contents with markup to render a heading and an HTML table containing the supplier company names, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page\n@model Northwind.Web.Pages.SuppliersModel\n&lt;div class=\"row\"&gt;\n  &lt;h1 class=\"display-2\"&gt;Suppliers&lt;\/h1&gt;\n  &lt;table class=\"table\"&gt;\n    &lt;thead class=\"thead-inverse\"&gt;\n      &lt;tr&gt;\n        &lt;th&gt;Company Name&lt;\/th&gt;\n      &lt;\/tr&gt;\n    &lt;\/thead&gt;\n    &lt;tbody&gt;\n    @if (Model.Suppliers is not null)\n    {\n      @foreach(string name in Model.Suppliers)\n      {\n        &lt;tr&gt;\n          &lt;td&gt;@name&lt;\/td&gt;\n        &lt;\/tr&gt;\n      }\n    }\n    &lt;\/tbody&gt;\n  &lt;\/table&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">While reviewing the preceding markup, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The model type for this Razor Page is set to <code class=\"calibre9\">SuppliersModel<\/code>. This is the type for the property named <code class=\"calibre9\">Model<\/code>, which we can access anywhere within the HTML markup.<\/li>\n<li class=\"calibre3\">The page outputs an HTML table with Bootstrap styles.<\/li>\n<li class=\"calibre3\">The page uses Razor syntax <code class=\"calibre9\">@if<\/code> and <code class=\"calibre9\">@for<\/code> statements to embed C# code in HTML.<\/li>\n<li class=\"calibre3\">The data rows in the table are generated by looping through the <code class=\"calibre9\">Suppliers<\/code> property of <code class=\"calibre9\">Model<\/code> if it is not <code class=\"calibre9\">null<\/code>.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the website using the <code class=\"calibre9\">https<\/code> launch profile and visit it using Chrome.<\/li>\n<li class=\"calibre3\">Click on the button to learn more about suppliers, and note the table of suppliers, as shown in <em class=\"calibre10\">Figure 13.8<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 13.8: The table of suppliers loaded from an array of strings\" height=\"565\" src=\"\/images\/cs12\/000038.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 13.8: The table of suppliers loaded from an array of strings<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"14.3.6\" id=\"calibre_link-714\">\n<h3 data-number=\"14.3.6\" class=\"calibre8\">Configuring files included in an ASP.NET Core project<\/h3>\n<p class=\"rights\">Until now, most of our projects have been simple console apps and class libraries with a few C# class files. By default, when we compiled those projects, all <code class=\"calibre9\">.cs<\/code> files in the project folder or subfolders were automatically included in the build at compile time.ASP.NET Core projects get more complicated. There are many more file types; some of them can be compiled at runtime instead of compile time, and some of them are just content that do not need to be compiled but do need to be deployed along with the compiled assemblies.You can control how files are processed during a build, and which are included or excluded from a deployment, by putting elements in the project file. These are processed by <strong class=\"calibre2\">MS Build<\/strong> and other tools during builds and deployments.You declare items in the project file as child elements of an <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> element. For example:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;--Include the greet.proto file in the build process.--&gt;\n&lt;ItemGroup&gt;\n  &lt;Protobuf Include=\"Protos\\greet.proto\" GrpcServices=\"Server\" \/&gt;\n&lt;\/ItemGroup&gt;\n&lt;--Remove the stylecop.json file from the build process.--&gt;\n&lt;ItemGroup&gt;\n  &lt;None Remove=\"stylecop.json\" \/&gt;\n&lt;\/ItemGroup&gt;\n&lt;--Include the stylecop.json file in the deployment.--&gt;\n&lt;ItemGroup&gt;\n  &lt;AdditionalFiles Include=\"stylecop.json\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You can have as many <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> elements as you want, so it is good practice to use them to logically divide elements by type. They are merged automatically by build tools.Usually, you manually add these elements when you know you need to use them, but unfortunately, Visual Studio 2022 and other code editors sometimes mess things up by trying to be helpful.For example, you might have added a new Razor Page file in the <code class=\"calibre9\">Pages<\/code> folder named <code class=\"calibre9\">index.cshtml<\/code>. You start the web server, but the page does not appear. Or you are working on a GraphQL service, and you add a file named <code class=\"calibre9\">seafoodProducts.graphql<\/code>. But when you run the GraphQL tool to auto-generate client-side proxies, it fails.These are both common indications that your code editor has decided that the new file should not be part of the project. It has automatically added an element to the project file to remove the file from the build process without telling you.To solve this type of problem, review the project file for unexpected entries like the following, and delete them:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;Content Remove=\"Pages\\index.cshtml\" \/&gt;\n&lt;\/ItemGroup&gt;\n&lt;ItemGroup&gt;\n  &lt;GraphQL Remove=\"seafoodProducts.graphql\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: When using tools that automatically \"fix\" problems without telling you, review your project file for unexpected elements when unexpected results happen.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can read more about managing MS Build items at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/visualstudio\/msbuild\/msbuild-items\">https:\/\/learn.microsoft.com\/en-us\/visualstudio\/msbuild\/msbuild-items<\/a>.<\/p>\n<\/blockquote>\n<\/blockquote>\n<\/section>\n<section data-number=\"14.3.7\" id=\"calibre_link-715\">\n<h3 data-number=\"14.3.7\" class=\"calibre8\">Project file build actions<\/h3>\n<p class=\"rights\">As we have just seen, it is important that ASP.NET Core developers understand how project build actions affect compilation.All files in a .NET SDK project have a build action. Most are set implicitly based on their file extension. You can override the default behavior by explicitly setting a build action. You can do this either by directly editing the <code class=\"calibre9\">.csproj<\/code> project file or by using your code editor's <strong class=\"calibre2\">Properties<\/strong> window, as shown in <em class=\"calibre10\">Figure 13.9<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 13.9: Properties of Suppliers.cshtml.cs show its default Build Action is C# compiler\" height=\"925\" src=\"\/images\/cs12\/000054.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 13.9: Properties of Suppliers.cshtml.cs show its default Build Action is C# compiler<\/figcaption><\/figure>\n<p class=\"rights\">Common build actions for ASP.NET Core project files are shown in <em class=\"calibre10\">Table 13.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Build action<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><strong class=\"calibre2\">AdditionalFiles<\/strong><\/td>\n<td class=\"calibre21\">Provides inputs to analyzers to verify code quality.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><strong class=\"calibre2\">Compile<\/strong> or <strong class=\"calibre2\">C# compiler<\/strong><\/td>\n<td class=\"calibre21\">Passed to the compiler as a source file.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><strong class=\"calibre2\">Content<\/strong><\/td>\n<td class=\"calibre21\">Included as part of the website when it's deployed.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><strong class=\"calibre2\">Embedded Resource<\/strong><\/td>\n<td class=\"calibre21\">Passed to the compiler as a resource to be embedded in the assembly.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><strong class=\"calibre2\">None<\/strong><\/td>\n<td class=\"calibre21\">Not part of the build. This value can be used for documentation and other files that should not be deployed with the website.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 13.1: Common build actions for ASP.NET Core project files<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about <strong class=\"calibre2\">Build Action<\/strong> and <code class=\"calibre9\">.csproj<\/code> entries at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/visualstudio\/ide\/build-actions\">https:\/\/learn.microsoft.com\/en-us\/visualstudio\/ide\/build-actions<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"14.4\" id=\"calibre_link-716\">\n<h2 data-number=\"14.4\" class=\"calibre5\">Using Entity Framework Core with ASP.NET Core<\/h2>\n<p class=\"rights\">Entity Framework Core is a natural way to get real data onto a website. In <em class=\"calibre10\">Chapter 12<\/em>, <em class=\"calibre10\">Introducing Web Development Using ASP.NET Core<\/em>, you created two pairs of class libraries: one for the entity models and one for the Northwind database context, for SQL Server and SQLite. You will now use them in your website project.<\/p>\n<section data-number=\"14.4.1\" id=\"calibre_link-717\">\n<h3 data-number=\"14.4.1\" class=\"calibre8\">Configuring Entity Framework Core as a service<\/h3>\n<p class=\"rights\">Functionality, such as Entity Framework Core database contexts, that is needed by an ASP.NET Core project should be registered as a dependency service during website startup. The code in the GitHub repository solution and below uses SQLite, but you can easily use SQL Server if you prefer.Let's see how:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Web<\/code> project, add a project reference to the <code class=\"calibre9\">Northwind.DataContext<\/code> project for either SQLite or SQL Server, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;!-- Change Sqlite to SqlServer if you prefer. --&gt;\n&lt;ItemGroup&gt;\n  &lt;ProjectReference Include=\"..\\Northwind.DataContext.Sqlite\\\nNorthwind.DataContext.Sqlite.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> The project reference must go all on one line with no line break.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.Web<\/code> project.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, import the namespace to work with your entity model types, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.EntityModels; \/\/ To use AddNorthwindContext method.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, after the statement that adds Razor Pages to the registered services, add a statement to register the <code class=\"calibre9\">Northwind<\/code> database context class, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddNorthwindContext();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Pages<\/code> folder, in <code class=\"calibre9\">Suppliers.cshtml.cs<\/code>, import the namespace for our database context, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.EntityModels; \/\/ To use NorthwindContext.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">SuppliersModel<\/code> class, add a private field to store the <code class=\"calibre9\">Northwind<\/code> database context and a constructor to set it, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private NorthwindContext _db;\npublic SuppliersModel(NorthwindContext db)\n{\n  _db = db;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Change the <code class=\"calibre9\">Suppliers<\/code> property to be declared as a sequence of <code class=\"calibre9\">Supplier<\/code> objects instead of <code class=\"calibre9\">string<\/code> values, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public IEnumerable&lt;Supplier&gt;? Suppliers { get; set; }<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">OnGet<\/code> method, modify the statements to set the <code class=\"calibre9\">Suppliers<\/code> property of the model from the <code class=\"calibre9\">Suppliers<\/code> property of the database context, sorted by country and then company name, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public void OnGet()\n{\n  ViewData[\"Title\"] = \"Northwind B2B - Suppliers\";\n  Suppliers = _db.Suppliers\n    .OrderBy(c =&gt; c.Country)\n    .ThenBy(c =&gt; c.CompanyName);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the contents of <code class=\"calibre9\">Suppliers.cshtml<\/code> to import the namespace for Northwind entity models and render multiple columns for each supplier, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page\n@using Northwind.EntityModels\n@model Northwind.Web.Pages.SuppliersModel\n&lt;div class=\"row\"&gt;\n  &lt;h1 class=\"display-2\"&gt;Suppliers&lt;\/h1&gt;\n  &lt;table class=\"table\"&gt;\n    &lt;thead class=\"thead-inverse\"&gt;\n      &lt;tr&gt;\n        &lt;th&gt;Company Name&lt;\/th&gt;\n        &lt;th&gt;Country&lt;\/th&gt;\n        &lt;th&gt;Phone&lt;\/th&gt;\n      &lt;\/tr&gt;\n    &lt;\/thead&gt;\n    &lt;tbody&gt;\n    @if (Model.Suppliers is not null)\n    {\n      @foreach(Supplier s in Model.Suppliers)\n      {\n        &lt;tr&gt;\n          &lt;td&gt;@s.CompanyName&lt;\/td&gt;\n          &lt;td&gt;@s.Country&lt;\/td&gt;\n          &lt;td&gt;@s.Phone&lt;\/td&gt;\n        &lt;\/tr&gt;\n      }\n    }\n    &lt;\/tbody&gt;\n  &lt;\/table&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the website using the <code class=\"calibre9\">https<\/code> launch profile and go to the website home page.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Learn more about our suppliers<\/strong> and note that the supplier table now loads from the database and the data is sorted first by country and then by company name, as shown in <em class=\"calibre10\">Figure 13.10<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 13.10: The suppliers table loaded from the Northwind database\" height=\"492\" src=\"\/images\/cs12\/000068.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 13.10: The suppliers table loaded from the Northwind database<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"14.4.2\" id=\"calibre_link-718\">\n<h3 data-number=\"14.4.2\" class=\"calibre8\">Enabling a model to insert entities<\/h3>\n<p class=\"rights\">You will now add functionality to insert a new supplier. First, you will modify the supplier model so that it responds to HTTP <code class=\"calibre9\">POST<\/code> requests when a visitor submits a form to insert a new supplier:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Pages<\/code> folder, in <code class=\"calibre9\">Suppliers.cshtml.cs<\/code>, import the following namespace:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.AspNetCore.Mvc; \/\/ To use [BindProperty], IActionResult.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">SuppliersModel<\/code> class, add a property to store a single supplier and a method named <code class=\"calibre9\">OnPost<\/code> that adds the supplier to the <code class=\"calibre9\">Suppliers<\/code> table in the Northwind database if its model is valid, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[BindProperty]\npublic Supplier? Supplier { get; set; }\npublic IActionResult OnPost()\n{\n  if (Supplier is not null &amp;&amp; ModelState.IsValid)\n  {\n    _db.Suppliers.Add(Supplier);\n    _db.SaveChanges();\n    return RedirectToPage(\"\/suppliers\");\n  }\n  else\n  {\n    return Page(); \/\/ Return to original page.\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">While reviewing the preceding code, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">We added a property named <code class=\"calibre9\">Supplier<\/code> that is decorated with the <code class=\"calibre9\">[BindProperty]<\/code> attribute so that we can easily connect HTML elements on the web page to properties in the <code class=\"calibre9\">Supplier<\/code> class.<\/li>\n<li class=\"calibre3\">We added a method that responds to HTTP <code class=\"calibre9\">POST<\/code> requests. It checks that all property values conform to validation rules on the <code class=\"calibre9\">Supplier<\/code> class entity model (such as <code class=\"calibre9\">[Required]<\/code> and <code class=\"calibre9\">[StringLength]<\/code>) and then adds the supplier to the existing table and saves the changes to the database context. This will generate a SQL statement to perform the insert into the database. Then, it redirects to the <code class=\"calibre9\">Suppliers<\/code> page so that the visitor sees the newly added supplier.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"14.4.3\" id=\"calibre_link-719\">\n<h3 data-number=\"14.4.3\" class=\"calibre8\">Defining a form to insert a new supplier<\/h3>\n<p class=\"rights\">Next, you will modify the Razor Page to define a form that a visitor can fill in and submit to insert a new supplier:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Suppliers.cshtml<\/code>, after the <code class=\"calibre9\">@model<\/code> declaration, add Microsoft common tag helpers so that we can use the tag helper <code class=\"calibre9\">asp-for<\/code> on this Razor Page, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the bottom of the file, add a form to insert a new supplier, and use the <code class=\"calibre9\">asp-for<\/code> tag helper to bind the <code class=\"calibre9\">CompanyName<\/code>, <code class=\"calibre9\">Country<\/code>, and <code class=\"calibre9\">Phone<\/code> properties of the <code class=\"calibre9\">Supplier<\/code> class to the input box, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;div class=\"row\"&gt;\n  &lt;p&gt;Enter details for a new supplier:&lt;\/p&gt;\n  &lt;form method=\"POST\"&gt;\n    &lt;div&gt;&lt;input asp-for=\"Supplier.CompanyName\" \n                placeholder=\"Company Name\" \/&gt;&lt;\/div&gt;\n    &lt;div&gt;&lt;input asp-for=\"Supplier.Country\" \n                placeholder=\"Country\" \/&gt;&lt;\/div&gt;\n    &lt;div&gt;&lt;input asp-for=\"Supplier.Phone\" \n                placeholder=\"Phone\" \/&gt;&lt;\/div&gt;\n    &lt;input type=\"submit\" \/&gt;\n  &lt;\/form&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">While reviewing the preceding markup, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The <code class=\"calibre9\">&lt;form&gt;<\/code> element with a <code class=\"calibre9\">POST<\/code> method is ordinary HTML, so an <code class=\"calibre9\">&lt;input type=\"submit\" \/&gt;<\/code> element inside it will make an HTTP <code class=\"calibre9\">POST<\/code> request back to the current page with values of any other elements inside that form.<\/li>\n<li class=\"calibre3\">An <code class=\"calibre9\">&lt;input&gt;<\/code> element with a tag helper named <code class=\"calibre9\">asp-for<\/code> enables data binding to the model behind the Razor Page.<\/li>\n<li class=\"calibre3\">JetBrains Rider can be overzealous with null warnings. If you get them in the model binding expressions, you can apply the null-forgiving operator, as shown in the following code expression: <code class=\"calibre9\">Supplier!.CompanyName<\/code>.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the website using the <code class=\"calibre9\">https<\/code> launch profile and navigate to the website home page.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Learn more about our suppliers<\/strong>, scroll down to the bottom of the page, enter <code class=\"calibre9\">Bob's Burgers<\/code>, <code class=\"calibre9\">USA<\/code>, and <code class=\"calibre9\">(603) 555-4567<\/code>, and then click <strong class=\"calibre2\">Submit<\/strong>.<\/li>\n<li class=\"calibre3\">Note that you see a refreshed suppliers table with the new supplier added near the bottom because it is sorted by the USA suppliers.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"14.4.4\" id=\"calibre_link-720\">\n<h3 data-number=\"14.4.4\" class=\"calibre8\">Injecting a dependency service into a Razor Page<\/h3>\n<p class=\"rights\">If you have a <code class=\"calibre9\">.cshtml<\/code> Razor Page file that does not have a code-behind file, then you can inject a dependency service using the <code class=\"calibre9\">@inject<\/code> directive instead of constructor parameter injection, and then directly reference the injected database context using Razor syntax in the middle of the markup.Let's create a simple example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Pages<\/code> folder, add a new file named <code class=\"calibre9\">Orders.cshtml<\/code>. (The Visual Studio 2022 item template is named <strong class=\"calibre2\">Razor Page - Empty<\/strong> and it creates two files. Delete the <code class=\"calibre9\">.cshtml.cs<\/code> file.)<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Orders.cshtml<\/code>, replace the existing code with markup to output the number of orders in the Northwind database, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page\n@using Northwind.EntityModels\n@inject NorthwindContext _db\n@{\n  string title = \"Orders\";\n  ViewData[\"Title\"] = $\"Northwind B2B - {title}\";\n}\n&lt;div class=\"row\"&gt;\n  &lt;h1 class=\"display-2\"&gt;@title&lt;\/h1&gt;\n  &lt;p&gt;\n    There are @_db.Orders.Count() orders in the Northwind database.\n  &lt;\/p&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the website using the <code class=\"calibre9\">https<\/code> launch profile and navigate to the website home page.<\/li>\n<li class=\"calibre3\">In the browser address bar, navigate to the relative address, <code class=\"calibre9\">\/orders<\/code>, and you will see that there are 830 orders in the Northwind database.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<\/section>\n<section data-number=\"14.5\" id=\"calibre_link-721\">\n<h2 data-number=\"14.5\" class=\"calibre5\">Configuring services and the HTTP request pipeline<\/h2>\n<p class=\"rights\">Now that we have built a website that reads and writes to a database, we will return to the website configuration and review how services and the HTTP request pipeline work in more detail.<\/p>\n<section data-number=\"14.5.1\" id=\"calibre_link-722\">\n<h3 data-number=\"14.5.1\" class=\"calibre8\">Understanding endpoint routing<\/h3>\n<p class=\"rights\">Endpoint routing is designed to enable better interoperability between frameworks that need routing, such as Razor Pages, MVC, or Web APIs, and middleware that needs to understand how routing affects them, such as localization, authorization, and so on.Endpoint routing gets its name because it represents the route table as a compiled tree of endpoints that can be walked efficiently by the routing system. One of the biggest improvements is the performance of routing and action method selection.<\/p>\n<\/section>\n<section data-number=\"14.5.2\" id=\"calibre_link-723\">\n<h3 data-number=\"14.5.2\" class=\"calibre8\">Configuring endpoint routing<\/h3>\n<p class=\"rights\">For more complex scenarios than we have seen so far, endpoint routing can use a pair of calls to the <code class=\"calibre9\">UseRouting<\/code> and <code class=\"calibre9\">UseEndpoints<\/code> methods:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">UseRouting<\/code> marks the pipeline position where a routing decision is made.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">UseEndpoints<\/code> marks the pipeline position where the selected endpoint is executed.<\/li>\n<\/ul>\n<p class=\"rights\">Middleware such as the localization that runs in between these methods can see the selected endpoint and switch to a different endpoint if necessary.Endpoint routing uses the same route template syntax that has been used in ASP.NET MVC since 2010 and the <code class=\"calibre9\">[Route]<\/code> attribute introduced with ASP.NET MVC 5 in 2013.<\/p>\n<\/section>\n<section data-number=\"14.5.3\" id=\"calibre_link-724\">\n<h3 data-number=\"14.5.3\" class=\"calibre8\">Reviewing the endpoint routing configuration in our project<\/h3>\n<p class=\"rights\">Review the statements in <code class=\"calibre9\">Program.cs<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.EntityModels; \/\/ To use AddNorthwindContext method.\n#region Configure the web server host and services\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.Services.AddRazorPages();\nbuilder.Services.AddNorthwindContext();\nvar app = builder.Build();\n#endregion\n#region Configure the HTTP pipeline and routes\nif (!app.Environment.IsDevelopment())\n{\n  app.UseHsts();\n}\napp.UseHttpsRedirection();\napp.UseDefaultFiles(); \/\/ index.xhtml, default.xhtml, and so on.\napp.UseStaticFiles();\napp.MapRazorPages();\napp.MapGet(\"\/\", () =&gt; \n  $\"Environment is {app.Environment.EnvironmentName}\");\n#endregion\n\/\/ Start the web server, host the website, and wait for requests.\napp.Run(); \/\/ This is a thread-blocking call.\nWriteLine(\"This executes after the web server has stopped!\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The web application <code class=\"calibre9\">builder<\/code> registers services that can then be retrieved when the functionality they provide is needed using dependency injection. The naming convention for a method that registers a service is <code class=\"calibre9\">AddService<\/code> where <code class=\"calibre9\">Service<\/code> is the service name, for example, <code class=\"calibre9\">AddRazorPages<\/code> or <code class=\"calibre9\">AddNorthwindContext<\/code>. Our code registers two services: Razor Pages and an EF Core database context.Common methods that register dependency services, including services that combine other method calls that register services, are shown in <em class=\"calibre10\">Table 13.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre19\"><\/col>\n<col class=\"calibre19\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Method<\/td>\n<td class=\"calibre21\">Services that it registers<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddMvcCore<\/code><\/td>\n<td class=\"calibre21\">Minimum set of services necessary to route requests and invoke controllers. Most websites will need more configuration than this.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddAuthorization<\/code><\/td>\n<td class=\"calibre21\">Authentication and authorization services.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddDataAnnotations<\/code><\/td>\n<td class=\"calibre21\">MVC data annotations service.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddCacheTagHelper<\/code><\/td>\n<td class=\"calibre21\">MVC cache tag helper service.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddRazorPages<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Razor Pages service, including the Razor view engine. Commonly used in simple website projects. It calls the following additional methods:<\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddMvcCore<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddAuthorization<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddDataAnnotations<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddCacheTagHelper<\/code><\/p>\n<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddApiExplorer<\/code><\/td>\n<td class=\"calibre21\">Web API explorer service.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddCors<\/code><\/td>\n<td class=\"calibre21\">Cross-origin resource sharing (CORS) support for enhanced security.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddFormatterMappings<\/code><\/td>\n<td class=\"calibre21\">Mappings between a URL format and its corresponding media type.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddControllers<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Controller services but not services for views or pages. Commonly used in ASP.NET Core Web API projects. It calls the following additional methods:<\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddMvcCore<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddAuthorization<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddDataAnnotations<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddCacheTagHelper<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddApiExplorer<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddCors<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddFormatterMappings<\/code><\/p>\n<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddViews<\/code><\/td>\n<td class=\"calibre21\">Support for <code class=\"calibre9\">.cshtml<\/code> views including default conventions.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddRazorViewEngine<\/code><\/td>\n<td class=\"calibre21\">Support for the Razor view engine including processing the <code class=\"calibre9\">@<\/code> symbol.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddControllersWithViews<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Controller, view, and page services. Commonly used in ASP.NET Core MVC website projects. It calls the following additional methods:<\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddMvcCore<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddAuthorization<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddDataAnnotations<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddCacheTagHelper<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddApiExplorer<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddCors<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddFormatterMappings<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddViews<\/code><\/p>\n<p class=\"rights\"><code class=\"calibre9\">AddRazorViewEngine<\/code><\/p>\n<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddMvc<\/code><\/td>\n<td class=\"calibre21\">Similar to <code class=\"calibre9\">AddControllersWithViews<\/code> , but you should only use it for backward compatibility.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddDbContext&lt;T&gt;<\/code><\/td>\n<td class=\"calibre21\">Your <code class=\"calibre9\">DbContext<\/code> type and its optional <code class=\"calibre9\">DbContextOptions&lt;TContext&gt;<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">AddNorthwindContext<\/code><\/td>\n<td class=\"calibre21\">A custom extension method we created to make it easier to register the <code class=\"calibre9\">NorthwindContext<\/code> class for either SQLite or SQL Server based on the project referenced.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 13.2: Common methods that register dependency services<\/p>\n<p class=\"rights\">You will see more examples of using these extension methods to register services in the next few chapters when working with ASP.NET Core MVC and ASP.NET Core Web API services.<\/p>\n<\/section>\n<section data-number=\"14.5.4\" id=\"calibre_link-725\">\n<h3 data-number=\"14.5.4\" class=\"calibre8\">Setting up the HTTP pipeline<\/h3>\n<p class=\"rights\">After building the web application and its services, the next statements configure the HTTP pipeline through which HTTP requests and responses flow in and out. The pipeline is made up of a connected sequence of delegates that can perform processing and then decide to either return a response themselves or pass processing on to the next delegate in the pipeline. Responses that come back can also be manipulated.Remember that delegates define a method signature that a delegate implementation can plug into. You might want to refer to <em class=\"calibre10\">Chapter 6<\/em>, <em class=\"calibre10\">Implementing Interfaces and Inheriting Classes<\/em>, to refresh your understanding of delegates.The delegate for the HTTP request pipeline is simple, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public delegate Task RequestDelegate(HttpContext context);<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You can see that the input parameter is an <code class=\"calibre9\">HttpContext<\/code>. This provides access to everything you might need to process the incoming HTTP request, including the URL path, query string parameters, cookies, and user agent.These delegates are often called <strong class=\"calibre2\">middleware<\/strong> because they sit in between the browser client and the website or web service.Middleware delegates are configured using one of the following methods or a custom method that calls them itself:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Run<\/code>: Adds a middleware delegate that terminates the pipeline by immediately returning a response instead of calling the next middleware delegate.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Map<\/code>: Adds a middleware delegate that creates a branch in the pipeline when there is a matching request usually based on a URL path like <code class=\"calibre9\">\/hello<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Use<\/code>: Adds a middleware delegate that forms part of the pipeline so it can decide if it wants to pass the request to the next delegate in the pipeline. It can modify the request and response before and after the next delegate.<\/li>\n<\/ul>\n<p class=\"rights\">For convenience, there are many extension methods that make it easier to build the pipeline, for example, <code class=\"calibre9\">UseMiddleware&lt;T&gt;<\/code>, where <code class=\"calibre9\">T<\/code> is a class that has:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A constructor with a <code class=\"calibre9\">RequestDelegate<\/code> parameter that will be passed to the next pipeline component.<\/li>\n<li class=\"calibre3\">An <code class=\"calibre9\">Invoke<\/code> method with a <code class=\"calibre9\">HttpContext<\/code> parameter and returns a <code class=\"calibre9\">Task<\/code>.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"14.5.5\" id=\"calibre_link-726\">\n<h3 data-number=\"14.5.5\" class=\"calibre8\">Summarizing key middleware extension methods<\/h3>\n<p class=\"rights\">Key middleware extension methods used in our code include the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">UseHsts<\/code>: Adds middleware for using HSTS, which adds the <code class=\"calibre9\">Strict-Transport-Security<\/code> header.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">UseHttpsRedirection<\/code>: Adds middleware for redirecting HTTP requests to HTTPS, so in our code a request for <code class=\"calibre9\">http:\/\/localhost:5130<\/code> would receive a 307 response telling the browser to request <code class=\"calibre9\">https:\/\/localhost:5131<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">UseDefaultFiles<\/code>: Adds middleware that enables default file mapping on the current path, so in our code it would identify files such as <code class=\"calibre9\">index.xhtml<\/code> or <code class=\"calibre9\">default.xhtml<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">UseStaticFiles<\/code>: Adds middleware that looks in <code class=\"calibre9\">wwwroot<\/code> for static files to return in the HTTP response.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">MapRazorPages<\/code>: Adds middleware that will map URL paths such as <code class=\"calibre9\">\/suppliers<\/code> to a Razor Page file in the <code class=\"calibre9\">\/Pages<\/code> folder named <code class=\"calibre9\">suppliers.cshtml<\/code> and return the results as the HTTP response.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">MapGet<\/code>: Adds middleware that will map URL paths such as <code class=\"calibre9\">\/hello<\/code> to an inline delegate that writes plain text directly to the HTTP response.<\/li>\n<\/ul>\n<p class=\"rights\">If we had chosen a different project template that supports more complex routing scenarios, for example, the ASP.NET Core MVC website project template, then we would have seen other common middleware extension methods, which include the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">UseRouting<\/code>: Adds middleware that defines a point in the pipeline where routing decisions are made and must be combined with a call to <code class=\"calibre9\">UseEndpoints<\/code> where the processing is then executed<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">UseEndpoints<\/code>: Adds middleware to execute to generate responses from decisions made earlier in the pipeline<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"14.5.6\" id=\"calibre_link-727\">\n<h3 data-number=\"14.5.6\" class=\"calibre8\">Visualizing the HTTP pipeline<\/h3>\n<p class=\"rights\">The HTTP request and response pipeline can be visualized as a sequence of request delegates, called one after the other in a chain or pipeline, as shown in the simplified diagram shown in <em class=\"calibre10\">Figure 13.11<\/em>, which excludes some middleware delegates, such as <code class=\"calibre9\">UseHsts<\/code> and <code class=\"calibre9\">MapGet<\/code>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 13.11: The HTTP request and response pipeline\" height=\"1055\" src=\"\/images\/cs12\/000149.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 13.11: The HTTP request and response pipeline<\/figcaption><\/figure>\n<p class=\"rights\">The diagram shows two HTTP requests, as described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">First, in yellow, an HTTP request is made for the static file <code class=\"calibre9\">index.xhtml<\/code>. The first middleware to process this request is HTTPS redirection, which detects that the request is not for HTTPS and responds with a <code class=\"calibre9\">307<\/code> status code and the URL for the secure version of the resource. The browser then makes another request using HTTPS, which gets past the HTTPS redirection middleware and is passed on to the <code class=\"calibre9\">UseDefaultFiles<\/code> and <code class=\"calibre9\">UseStaticFiles<\/code> middleware. This finds a matching static file in the <code class=\"calibre9\">wwwroot<\/code> folder and returns it.<\/li>\n<li class=\"calibre3\">Second, in blue, an HTTPS request is made for the relative path <code class=\"calibre9\">index<\/code>. The request uses HTTPS, so the HTTPS redirection middleware passes it through to the next middleware component. No matching static file is found in the <code class=\"calibre9\">wwwroot<\/code> folder, so the static files middleware passes the request through to the next middleware in the pipeline. A match is found in the <code class=\"calibre9\">Pages<\/code> folder for the Razor Page file <code class=\"calibre9\">index.cshtml<\/code>. The Razor Page is executed to generate an HTML page that is returned as the HTTP response. Any code in the middleware that is part of the pipeline could make changes to this HTTP response as it flows back through them if needed, although in this scenario none of them do.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"14.5.7\" id=\"calibre_link-728\">\n<h3 data-number=\"14.5.7\" class=\"calibre8\">Implementing an anonymous inline delegate as middleware<\/h3>\n<p class=\"rights\">A delegate can be specified as an inline anonymous method. We will register one that plugs into the pipeline after routing decisions for endpoints have been made.It will output which endpoint was chosen, as well as handling one specific route: <code class=\"calibre9\">\/bonjour<\/code>. If that route is matched, it will respond with plain text, without calling any further into the pipeline to find a match:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements before the call to <code class=\"calibre9\">UseHttpsRedirection<\/code> to use an anonymous method as a middleware delegate, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Implementing an anonymous inline delegate as middleware\n\/\/ to intercept HTTP requests and responses.\napp.Use(async (HttpContext context, Func&lt;Task&gt; next) =&gt;\n{\n  RouteEndpoint? rep = context.GetEndpoint() as RouteEndpoint;\n  if (rep is not null)\n  {\n    WriteLine($\"Endpoint name: {rep.DisplayName}\");\n    WriteLine($\"Endpoint route pattern: {rep.RoutePattern.RawText}\");\n  }\n  if (context.Request.Path == \"\/bonjour\")\n  {\n    \/\/ In the case of a match on URL path, this becomes a terminating\n    \/\/ delegate that returns so does not call the next delegate.\n    await context.Response.WriteAsync(\"Bonjour Monde!\");\n    return;\n  }\n  \/\/ We could modify the request before calling the next delegate.\n  await next();\n  \/\/ We could modify the response after calling the next delegate.\n});<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the website using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Arrange the command prompt or terminal and the browser window so that you can see both.<\/li>\n<li class=\"calibre3\">In Chrome, navigate to <code class=\"calibre9\">https:\/\/localhost:5131\/<\/code>, look at the console output, and note that there was a match on an endpoint route <code class=\"calibre9\">\/<\/code>; it was processed as <code class=\"calibre9\">\/index<\/code>, and the <code class=\"calibre9\">Index.cshtml<\/code> Razor Page was executed to return the response, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Endpoint name: \/index \nEndpoint route pattern:<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <code class=\"calibre9\">https:\/\/localhost:5131\/suppliers<\/code> and note that you can see that there was a match on an endpoint route <code class=\"calibre9\">\/Suppliers<\/code>, and the <code class=\"calibre9\">Suppliers.cshtml<\/code> Razor Page was executed to return the response, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Endpoint name: \/Suppliers \nEndpoint route pattern: Suppliers<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <code class=\"calibre9\">https:\/\/localhost:5131\/index<\/code> and note that there was a match on an endpoint route <code class=\"calibre9\">\/index<\/code>, and the <code class=\"calibre9\">Index.cshtml<\/code> Razor Page was executed to return the response, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Endpoint name: \/index \nEndpoint route pattern: index<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Navigate to <code class=\"calibre9\">https:\/\/localhost:5131\/index.xhtml<\/code> and note that there is no output written to the console because there was no match on an endpoint route, but there was a match for a static file, so it was returned as the response.<\/li>\n<li class=\"calibre3\">Navigate to <code class=\"calibre9\">https:\/\/localhost:5131\/bonjour<\/code> and note that there is no output written to the console because there was no match on an endpoint route. Instead, our delegate matched on <code class=\"calibre9\">\/bonjour<\/code>, wrote directly to the response stream, and returned with no further processing.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about the HTTP pipeline and middleware order at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/middleware\/#middleware-order\">https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/middleware\/#middleware-order<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"14.6\" id=\"calibre_link-729\">\n<h2 data-number=\"14.6\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring this chapter's topics with deeper research.<\/p>\n<section data-number=\"14.6.1\" id=\"calibre_link-730\">\n<h3 data-number=\"14.6.1\" class=\"calibre8\">Exercise 13.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">List six method names that can be specified in an HTTP request.<\/li>\n<li class=\"calibre3\">List six status codes and their descriptions that can be returned in an HTTP response.<\/li>\n<li class=\"calibre3\">In ASP.NET Core, what is the <code class=\"calibre9\">Program<\/code> class used for?<\/li>\n<li class=\"calibre3\">What does the acronym HSTS stand for and what does it do?<\/li>\n<li class=\"calibre3\">How do you enable static HTML pages for a website?<\/li>\n<li class=\"calibre3\">How do you mix C# code into the middle of HTML to create a dynamic page?<\/li>\n<li class=\"calibre3\">How can you define shared layouts for Razor Pages?<\/li>\n<li class=\"calibre3\">How can you separate the markup from the code-behind in a Razor Page?<\/li>\n<li class=\"calibre3\">How do you configure an Entity Framework Core data context for use with an ASP.NET Core website?<\/li>\n<li class=\"calibre3\">How can you reuse Razor Pages with ASP.NET Core 2.2 or later?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"14.6.2\" id=\"calibre_link-731\">\n<h3 data-number=\"14.6.2\" class=\"calibre8\">Exercise 13.2 &ndash; Using Razor class libraries<\/h3>\n<p class=\"rights\">Everything related to a Razor Page can be compiled into a class library for easier reuse in multiple projects. I have written an online-only section showing how to build a Razor class library and use it in an ASP.NET Core project like <code class=\"calibre9\">Northwind.Web<\/code>. You can read it at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch13-razor-library.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch13-razor-library.md<\/a><\/p>\n<\/section>\n<section data-number=\"14.6.3\" id=\"calibre_link-732\">\n<h3 data-number=\"14.6.3\" class=\"calibre8\">Exercise 13.3 &ndash; Enabling HTTP\/3 and request decompression support<\/h3>\n<p class=\"rights\">HTTP\/3 brings benefits to all internet-connected apps, but especially mobile. I have written an online-only section introducing HTTP\/3 and showing how to enable it in an ASP.NET Core project like <code class=\"calibre9\">Northwind.Web<\/code> when targeting .NET 7. In previews of .NET 8, HTTP\/3 was enabled by default, but the Microsoft team decided to revert to disabling HTTP\/3 by default. They did this due to a bad experience caused by some anti-virus software. Hopefully in ASP.NET Core 9 they will resolve this issue and re-enable HTTP\/3 by default. You can read more about their decision at the following link:<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/asp-net-core-updates-in-dotnet-8-rc-1\/#http-3-disabled-by-default\">https:\/\/devblogs.microsoft.com\/dotnet\/asp-net-core-updates-in-dotnet-8-rc-1\/#http-3-disabled-by-default<\/a>The page also includes a section about enabling request decompression support. You can read the page at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch13-enabling-http3.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch13-enabling-http3.md<\/a><\/p>\n<\/section>\n<section data-number=\"14.6.4\" id=\"calibre_link-733\">\n<h3 data-number=\"14.6.4\" class=\"calibre8\">Exercise 13.4 &ndash; Practice building a data-driven web page<\/h3>\n<p class=\"rights\">Add a Razor Page to the <code class=\"calibre9\">Northwind.Web<\/code> website that enables the user to see a list of customers grouped by country. When the user clicks on a customer record, they should then see a page showing the full contact details of that customer and a list of their orders.My suggested solution can be found at the following links:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Customers.cshtml\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Customers.cshtml<\/a><\/li>\n<li class=\"calibre3\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Customers.cshtml.cs\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Customers.cshtml.cs<\/a><\/li>\n<li class=\"calibre3\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/CustomerOrders.cshtml\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/CustomerOrders.cshtml<\/a><\/li>\n<li class=\"calibre3\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/CustomerOrders.cshtml.cs\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/CustomerOrders.cshtml.cs<\/a><\/li>\n<\/ul>\n<\/section>\n<section data-number=\"14.6.5\" id=\"calibre_link-734\">\n<h3 data-number=\"14.6.5\" class=\"calibre8\">Exercise 13.5 &ndash; Practice building web pages for functions<\/h3>\n<p class=\"rights\">Reimplement some of the console apps from earlier chapters as Razor Pages; for example, from <em class=\"calibre10\">Chapter 4, Writing, Debugging, and Testing Functions<\/em>, provide a web user interface to output times tables, calculate tax, and generate factorials and the Fibonacci sequence.My suggested solution can be found at the following links:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Functions.cshtml\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Functions.cshtml<\/a><\/li>\n<li class=\"calibre3\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Functions.cshtml.cs\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Functions.cshtml.cs<\/a><\/li>\n<\/ul>\n<\/section>\n<section data-number=\"14.6.6\" id=\"calibre_link-735\">\n<h3 data-number=\"14.6.6\" class=\"calibre8\">Exercise 13.6 &ndash; Introducing Bootstrap<\/h3>\n<p class=\"rights\">Bootstrap is the world's most popular framework for building responsive, mobile-first websites. For the companion book, <em class=\"calibre10\">Apps and Services with .NET 8<\/em>, I wrote an online-only section introducing some of Bootstrap\u2019s most important features. You can read it at the following link:<a href=\"https:\/\/github.com\/markjprice\/apps-services-net8\/blob\/main\/docs\/ch14-bootstrap.md\">https:\/\/github.com\/markjprice\/apps-services-net8\/blob\/main\/docs\/ch14-bootstrap.md<\/a><\/p>\n<\/section>\n<section data-number=\"14.6.7\" id=\"calibre_link-736\">\n<h3 data-number=\"14.6.7\" class=\"calibre8\">Exercise 13.7 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more about the topics covered in this chapter:<\/p>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-13---building-websites-using-aspnet-core-razor-pages\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-13---building-websites-using-aspnet-core-razor-pages<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"14.7\" id=\"calibre_link-737\">\n<h2 data-number=\"14.7\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">About the foundations of web development using HTTP.<\/li>\n<li class=\"calibre3\">How to build a simple website that returns static files.<\/li>\n<li class=\"calibre3\">How to use ASP.NET Core Razor Pages with Entity Framework Core to create web pages that are dynamically generated from information in a database.<\/li>\n<li class=\"calibre3\">How to configure the HTTP request and response pipeline, what the helper extension methods do, and how you can add your own middleware that affects processing.<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will learn how to build more complex websites using ASP.NET Core MVC, which separates the technical concerns of building a website into models, views, and controllers to make them easier to manage.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-938\">\n<div id=\"calibre_link-1940\" class=\"calibre1\">\n<section data-number=\"15\" id=\"calibre_link-738\">\n<h1 data-number=\"15\" class=\"title\">14 Building Websites Using the Model-View-Controller Pattern<\/h1>\n<section data-number=\"15.1\" id=\"calibre_link-739\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"15.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000166.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about building websites with a modern HTTP architecture on the server side using ASP.NET Core MVC, including the configuration, authentication, authorization, routes, request and response pipeline, models, views, and controllers that make up an ASP.NET Core MVC project.This chapter will cover the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Setting up an ASP.NET Core MVC website<\/li>\n<li class=\"calibre3\">Exploring an ASP.NET Core MVC website<\/li>\n<li class=\"calibre3\">Customizing an ASP.NET Core MVC website<\/li>\n<li class=\"calibre3\">Improving performance and scalability using caching<\/li>\n<li class=\"calibre3\">Querying a database and using display templates<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"15.2\" id=\"calibre_link-740\">\n<h2 data-number=\"15.2\" class=\"calibre5\">Setting up an ASP.NET Core MVC website<\/h2>\n<p class=\"rights\">ASP.NET Core Razor Pages are good for simple websites. For more complex websites, it would be better to have a more formal structure to manage that complexity.This is where the <strong class=\"calibre2\">Model-View-Controller<\/strong> (<strong class=\"calibre2\">MVC<\/strong>) design pattern is useful. It uses technologies like Razor syntax, but allows a cleaner separation between technical concerns, as shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Models<\/strong>: Classes that represent the data entities and view models used on the website.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Views<\/strong>: <em class=\"calibre10\">Razor View<\/em> files, that is, <code class=\"calibre9\">.cshtml<\/code> files, that render data in view models into HTML web pages. <em class=\"calibre10\">Razor Views<\/em> are different from <em class=\"calibre10\">Razor Pages<\/em> but they share the same file extension <code class=\"calibre9\">.cshtml<\/code>. When creating a <em class=\"calibre10\">Razor Page<\/em>, it must have the <code class=\"calibre9\">@page<\/code> directive at the top of its file. When creating a <em class=\"calibre10\">Razor View<\/em>, you must <em class=\"calibre10\">not<\/em> use the <code class=\"calibre9\">@page<\/code> directive! If you do, the controller will not pass the model and it will be <code class=\"calibre9\">null<\/code>, throwing a <code class=\"calibre9\">NullReferenceException<\/code> when you try to access any of its members.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Controllers<\/strong>: Classes that execute code when an HTTP request arrives at the web server. The controller methods usually instantiate a view model and pass that to a view in order to generate an HTTP response. This is returned to the web browser or other client that made the original request.<\/li>\n<\/ul>\n<p class=\"rights\">The best way to understand using the MVC design pattern is to see a working example.<\/p>\n<section data-number=\"15.2.1\" id=\"calibre_link-741\">\n<h3 data-number=\"15.2.1\" class=\"calibre8\">Creating an ASP.NET Core MVC website<\/h3>\n<p class=\"rights\">You will use a project template to create an ASP.NET Core MVC website project that has a database for authenticating and authorizing users. Visual Studio 2022 defaults to using SQL Server LocalDB for the accounts database. Visual Studio Code (or more accurately the <code class=\"calibre9\">dotnet<\/code> CLI tool) uses SQLite by default and you can specify a switch to use SQL Server LocalDB instead.Let's see it in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to open the <code class=\"calibre9\">PracticalApps<\/code> solution.<\/li>\n<li class=\"calibre3\">Add an MVC website project with authentication accounts stored in a database, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">ASP.NET Core Web App (Model-View-Controller) [C#]<\/strong> \/ <code class=\"calibre9\">mvc<\/code>.<\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">Northwind.Mvc<\/code>.<\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">PracticalApps<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Authentication type<\/strong>: <strong class=\"calibre2\">Individual Accounts<\/strong> \/ <code class=\"calibre9\">--auth Individual<\/code>.<\/li>\n<li class=\"calibre3\">For Visual Studio 2022, leave all other options as their defaults, for example, HTTPS is enabled, and Docker is disabled.<\/li>\n<li class=\"calibre3\">For Visual Studio Code, in the <code class=\"calibre9\">PracticalApps<\/code> solution folder, use <code class=\"calibre9\">dotnet new mvc --auth Individual -o Northwind.Mvc<\/code> and <code class=\"calibre9\">dotnet sln add Northwind.Mvc<\/code>.<\/li>\n<li class=\"calibre3\">For JetBrains Rider, right-click the <code class=\"calibre9\">PracticalApps<\/code> solution, navigate to <strong class=\"calibre2\">Add<\/strong> | <strong class=\"calibre2\">New Project\u2026<\/strong>, in the <strong class=\"calibre2\">New Project<\/strong> dialog box, select <strong class=\"calibre2\">ASP.NET Core Web Application<\/strong>, for <strong class=\"calibre2\">Type<\/strong>, select <strong class=\"calibre2\">Web App (Model-View-Controller)<\/strong>, and for <strong class=\"calibre2\">Auth<\/strong>, select <strong class=\"calibre2\">Individual authentication<\/strong>, and then click <strong class=\"calibre2\">Create<\/strong>.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.Mvc<\/code> project.<\/li>\n<li class=\"calibre3\">At the command prompt or terminal, use the <code class=\"calibre9\">help<\/code> switch to see other options for this project template, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new mvc --help<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the results, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">ASP.NET Core Web App (Model-View-Controller) (C#)\nAuthor: Microsoft\nDescription: A project template for creating an ASP.NET Core application with example ASP.NET Core MVC Views and Controllers. This template can also be used for RESTful HTTP services.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">There are many options, especially related to authentication, as shown in <em class=\"calibre10\">Table 14.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre19\"><\/col>\n<col class=\"calibre19\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Switches<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">-au<\/code> or <code class=\"calibre9\">--auth<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">The type of authentication to use:<\/p>\n<p class=\"rights\"><code class=\"calibre9\">None<\/code> (default): This choice also allows you to disable HTTPS.<\/p>\n<p class=\"rights\"><code class=\"calibre9\">Individual<\/code>: Individual authentication that stores registered users and their passwords in a database (SQLite by default). We will use this in the project we create for this chapter.<\/p>\n<p class=\"rights\"><code class=\"calibre9\">IndividualB2C<\/code>: Individual authentication with Azure AD B2C.<\/p>\n<p class=\"rights\"><code class=\"calibre9\">SingleOrg<\/code>: Organizational authentication for a single tenant.<\/p>\n<p class=\"rights\"><code class=\"calibre9\">MultiOrg<\/code>: Organizational authentication for multiple tenants.<\/p>\n<p class=\"rights\"><code class=\"calibre9\">Windows<\/code>: Windows authentication. Mostly useful for intranets.<\/p>\n<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">-uld<\/code> or <code class=\"calibre9\">--use-local-db<\/code><\/td>\n<td class=\"calibre21\">Whether to use SQL Server LocalDB instead of SQLite. This option only applies if <code class=\"calibre9\">--auth Individual<\/code> or <code class=\"calibre9\">--auth IndividualB2C<\/code> is specified. The value is an optional bool with a default of <code class=\"calibre9\">false<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">-rrc<\/code> or <code class=\"calibre9\">--razor-runtime-compilation<\/code><\/td>\n<td class=\"calibre21\">Determines if the project is configured to use Razor runtime compilation in Debug builds. This can improve the performance of the startup process during debugging because it can defer the compilation of Razor views. The value is an optional bool with a default of <code class=\"calibre9\">false<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">-f<\/code> or <code class=\"calibre9\">--framework<\/code><\/td>\n<td class=\"calibre21\">The target framework for the project. Values can be <code class=\"calibre9\">net8.0<\/code> (default), <code class=\"calibre9\">net7.0<\/code> , or <code class=\"calibre9\">net6.0<\/code> . Older versions are no longer supported.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 14.1: Additional switches for the dotnet new mvc project template<br \/>\n<\/section>\n<section data-number=\"15.2.2\" id=\"calibre_link-742\">\n<h3 data-number=\"15.2.2\" class=\"calibre8\">Creating the authentication database for SQL Server LocalDB<\/h3>\n<p class=\"rights\">If you created the MVC project using Visual Studio 2022, or you used <code class=\"calibre9\">dotnet new mvc<\/code> with the <code class=\"calibre9\">-uld<\/code> or <code class=\"calibre9\">--use-local-db<\/code> switch, then the database for authentication and authorization will be stored in SQL Server LocalDB. But the database does not yet exist.If you created the MVC project using <code class=\"calibre9\">dotnet new<\/code> or JetBrains Rider, then the database for authentication and authorization will be stored in SQLite and the file has already been created, named <code class=\"calibre9\">app.db<\/code>.The connection string for the authentication database is named <code class=\"calibre9\">DefaultConnection<\/code> and it is stored in the <code class=\"calibre9\">appsettings.json<\/code> file in the root folder for the MVC website project.For SQLite, see the following setting:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"DataSource=app.db;Cache=Shared\"\n  },<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you created the MVC project using Visual Studio 2022 only, then let's create its authentication database now by following a few simple steps:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Mvc<\/code> project, in <code class=\"calibre9\">appsettings.json,<\/code> note the database connection string named <code class=\"calibre9\">DefaultConnection<\/code>, as shown highlighted in the following configuration:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Server=(localdb)\\\\mssqllocaldb;Database=aspnet-Northwind.Mvc-440bc3c1-f7e7-4463-99d5-896b6a6500e0;Trusted_Connection=True;MultipleActiveResultSets=true\"\n  },\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Your database name will use the pattern <code class=\"calibre9\">aspnet-[ProjectName]-[GUID]<\/code> and have a different GUID value from the example above.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">At a command prompt or terminal, in the <code class=\"calibre9\">Northwind.Mvc<\/code> folder, enter the command to run database migrations so that the database used to store credentials for authentication is created, as shown in the following command:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet ef database update<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the database is created with tables like <code class=\"calibre9\">AspNetRoles<\/code>, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Build started...\nBuild succeeded.\ninfo: Microsoft.EntityFrameworkCore.Infrastructure[10403]\n      Entity Framework Core 8.0.0 initialized 'ApplicationDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer:8.0.0' with options: None\ninfo: Microsoft.EntityFrameworkCore.Database.Command[20101]\n      Executed DbCommand (129ms) [Parameters=[], CommandType='Text', CommandTimeout='60']\n      CREATE DATABASE [aspnet-Northwind.Mvc2-440bc3c1-f7e7-4463-99d5-896b6a6500e0];\n...\ninfo: Microsoft.EntityFrameworkCore.Database.Command[20101]\n      Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']\n      CREATE TABLE [AspNetRoles] (\n          [Id] nvarchar(450) NOT NULL,\n          [Name] nvarchar(256) NULL,\n          [NormalizedName] nvarchar(256) NULL,\n          [ConcurrencyStamp] nvarchar(max) NULL,\n          CONSTRAINT [PK_AspNetRoles] PRIMARY KEY ([Id])\n      );\n...\ninfo: Microsoft.EntityFrameworkCore.Database.Command[20101]\n      Executed DbCommand (8ms) [Parameters=[], CommandType='Text', CommandTimeout='30']\n      INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])\n      VALUES (N'00000000000000_CreateIdentitySchema', N'8.0.0');<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"15.2.3\" id=\"calibre_link-743\">\n<h3 data-number=\"15.2.3\" class=\"calibre8\">Changing the port numbers and starting the website<\/h3>\n<p class=\"rights\">Let's review the behavior of the default ASP.NET Core MVC website project template:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Mvc<\/code> project, expand the <code class=\"calibre9\">Properties<\/code> folder.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">launchSettings.json<\/code>, change the configured port numbers for the <code class=\"calibre9\">https<\/code> profile, as shown highlighted in the following configuration:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\"applicationUrl\": \"https:\/\/localhost:5141;http:\/\/localhost:5140\",<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Save the changes to the <code class=\"calibre9\">launchSettings.json<\/code> file.<\/li>\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website using the <code class=\"calibre9\">https<\/code> launch profile:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">If you are using Visual Studio 2022, then in the toolbar, select the <strong class=\"calibre2\">https<\/strong> profile, select <strong class=\"calibre2\">Google Chrome<\/strong> as the <strong class=\"calibre2\">Web Browser<\/strong>, and then start the project without debugging.<\/li>\n<li class=\"calibre3\">If you are using Visual Studio Code, then enter the command to start the project with the <code class=\"calibre9\">https<\/code> launch profile, as shown in the following command: <code class=\"calibre9\">dotnet run --launch-profile https<\/code>, and then start Chrome.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In Chrome, open <strong class=\"calibre2\">Developer Tools<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Navigate to <code class=\"calibre9\">http:\/\/localhost:5140\/<\/code> and note the following, as shown in <em class=\"calibre10\">Figure 14.1<\/em>:<\/p>\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Requests for HTTP on port <code class=\"calibre9\">5140<\/code> are automatically redirected to HTTPS on port <code class=\"calibre9\">5141<\/code>.<\/li>\n<li class=\"calibre3\">The top navigation menu with links to <strong class=\"calibre2\">Home<\/strong>, <strong class=\"calibre2\">Privacy<\/strong>, <strong class=\"calibre2\">Register<\/strong>, and <strong class=\"calibre2\">Login<\/strong>. If the viewport width is 575 pixels or less, then the navigation collapses into a hamburger menu.<\/li>\n<li class=\"calibre3\">The title of the website, <strong class=\"calibre2\">Northwind.Mvc<\/strong>, shown in the header and footer:<\/li>\n<\/ul>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 14.1: The ASP.NET Core MVC project template website home page\" height=\"547\" src=\"\/images\/cs12\/000019.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 14.1: The ASP.NET Core MVC project template website home page<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Leave the browser running.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"15.2.4\" id=\"calibre_link-744\">\n<h3 data-number=\"15.2.4\" class=\"calibre8\">Exploring visitor registration<\/h3>\n<p class=\"rights\">By default, passwords must have at least one non-alphanumeric character, at least one digit (0-9), and at least one uppercase letter (A-Z). I use <code class=\"calibre9\">Pa$$w0rd<\/code> in scenarios like this when I am just exploring.The MVC project template follows best practices for <strong class=\"calibre2\">double-opt-in<\/strong> (<strong class=\"calibre2\">DOI<\/strong>), meaning that after filling in an email and password to register, an email is sent to the email address, and the visitor must click a link in that email to confirm that they want to register.We have not yet configured an email provider to send that email, so we must simulate that step:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Chrome, close the <strong class=\"calibre2\">Developer Tools<\/strong> pane.<\/li>\n<li class=\"calibre3\">In the top navigation menu, click <strong class=\"calibre2\">Register<\/strong>.<\/li>\n<li class=\"calibre3\">Enter an email and password, and then click the <strong class=\"calibre2\">Register<\/strong> button. (I used <code class=\"calibre9\">test@example.com<\/code> and <code class=\"calibre9\">Pa$$w0rd<\/code>.)<\/li>\n<li class=\"calibre3\">On the <strong class=\"calibre2\">Register confirmation<\/strong> page, click the link with the text <strong class=\"calibre2\">Click here to confirm your account<\/strong> and note that you are redirected to a <strong class=\"calibre2\">Confirm email<\/strong> web page that you could customize. By default, the <strong class=\"calibre2\">Confirm email<\/strong> page just says <strong class=\"calibre2\">Thank you for confirming your email<\/strong>.<\/li>\n<li class=\"calibre3\">In the top navigation menu, click <strong class=\"calibre2\">Login<\/strong>, enter your email and password (note that there is an optional checkbox to remember you, and there are links if the visitor has forgotten their password or they want to register as a new visitor), and then click the <strong class=\"calibre2\">Log in<\/strong> button.<\/li>\n<li class=\"calibre3\">In the top navigation menu, click your email address. This will navigate to an account management page. Note that you can set a phone number, change your email address, change your password, enable two-factor authentication (if you add an authenticator app), and download and delete your personal data. This last feature is good for compliance with legal regulations like the European GDPR.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"15.2.5\" id=\"calibre_link-745\">\n<h3 data-number=\"15.2.5\" class=\"calibre8\">Reviewing an MVC website project structure<\/h3>\n<p class=\"rights\">In your code editor, in Visual Studio <strong class=\"calibre2\">Solution Explorer<\/strong> (toggle on <strong class=\"calibre2\">Show All Files<\/strong>), Visual Studio Code <strong class=\"calibre2\">EXPLORER<\/strong>, or JetBrains Rider, hover your mouse in the <strong class=\"calibre2\">Solution<\/strong> pane and click the eyeball icon, and then review the structure of an MVC website project. We will look in more detail at some of these parts later, but for now, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Areas<\/code>: This folder contains nested folders and a file needed to integrate your website project with <strong class=\"calibre2\">ASP.NET Core Identity<\/strong>, which is used for authentication.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">bin<\/code>, <code class=\"calibre9\">obj<\/code>: These folders contain temporary files needed during the build process and the compiled assemblies for the project.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Controllers<\/code>: This folder contains C# classes that have methods (known as actions) that fetch a model and pass it to a view, for example, <code class=\"calibre9\">HomeController.cs<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Data<\/code>: This folder contains Entity Framework Core migration classes used by the ASP.NET Core Identity system to provide data storage for authentication and authorization, for example, <code class=\"calibre9\">ApplicationDbContext.cs<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Models<\/code>: This folder contains C# classes that represent all of the data gathered together by a controller and passed to a view, for example, <code class=\"calibre9\">ErrorViewModel.cs<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Properties<\/code>: This folder contains a configuration file for IIS or IIS Express on Windows and for launching the website during development named <code class=\"calibre9\">launchSettings.json<\/code>. This file is only used on the local development machine and is not deployed to your production website.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Views<\/code>: This folder contains the <code class=\"calibre9\">.cshtml<\/code> Razor files that combine HTML and C# code to dynamically generate HTML responses. The <code class=\"calibre9\">_ViewStart<\/code> file sets the default layout and <code class=\"calibre9\">_ViewImports<\/code> imports common namespaces used in all views like tag helpers:\n<ul class=\"calibre16\">\n<li class=\"calibre3\"><code class=\"calibre9\">Home<\/code>: This subfolder contains Razor files for the home and privacy pages.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Shared<\/code>: This subfolder contains Razor files for the shared layout, an error page, and two partial views for logging in and validation scripts.<\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">wwwroot<\/code>: This folder contains static content used by the website, such as CSS for styling, libraries of JavaScript, JavaScript for this website project, and a <code class=\"calibre9\">favicon.ico<\/code> file. You also put images and other static file resources like PDF documents in here. The project template includes Bootstrap and jQuery libraries.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">app.db<\/code>: This is the SQLite database that stores registered visitors. (If you used SQL Server LocalDB, then it will not be needed.)<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">appsettings.json<\/code> and <code class=\"calibre9\">appsettings.Development.json<\/code>: These files contain settings that your website can load at runtime, for example, the database connection string for the ASP.NET Core Identity system and logging levels.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Northwind.Mvc.csproj<\/code>: This file contains project settings like the use of the web .NET SDK, an entry for SQLite to ensure that the <code class=\"calibre9\">app.db<\/code> file is copied to the website's output folder, and a list of NuGet packages that your project requires, including EF Core and ASP.NET Core Identity packages.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Northwind.Mvc.csproj.user<\/code>: This file contains Visual Studio 2022 session settings for remembering options. For example, which launch profile was selected, like <code class=\"calibre9\">https<\/code>. Visual Studio 2022 hides this file, and it should not normally be included in source code control because it is specific to an individual developer.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Program.cs<\/code>: This file defines a hidden <code class=\"calibre9\">Program<\/code> class that contains the <code class=\"calibre9\">&lt;Main&gt;$<\/code> entry point. It builds a pipeline for processing incoming HTTP requests and hosts the website using default options like configuring the Kestrel web server and loading <code class=\"calibre9\">appsettings<\/code>. It adds and configures services that your website needs, for example, ASP.NET Core Identity for authentication, SQLite or SQL Server for identity data storage, and so on, and routes for your application.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"15.2.6\" id=\"calibre_link-746\">\n<h3 data-number=\"15.2.6\" class=\"calibre8\">Reviewing the ASP.NET Core Identity database<\/h3>\n<p class=\"rights\">Open <code class=\"calibre9\">appsettings.json<\/code> to find the connection string used for the ASP.NET Core Identity database, as shown highlighted for SQL Server LocalDB in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Server=(localdb)\\\\mssqllocaldb;Database=aspnet-Northwind.Mvc-2F6A1E12-F9CF-480C-987D-FEFB4827DE22;Trusted_Connection=True;MultipleActiveResultSets=true\"\n  },\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you used SQL Server LocalDB for the identity data store, then you can use <strong class=\"calibre2\">Server Explorer<\/strong> to connect to the database. You can copy and paste the connection string from the <code class=\"calibre9\">appsettings.json<\/code> file. Remember to remove the second backslash between <code class=\"calibre9\">(localdb)<\/code> and <code class=\"calibre9\">mssqllocaldb<\/code>. If you installed an SQLite tool such as SQLiteStudio, then you can open the SQLite <code class=\"calibre9\">app.db<\/code> database file.You can then see the tables that the ASP.NET Core Identity system uses to register users and roles, including the <code class=\"calibre9\">AspNetUsers<\/code> table used to store the registered visitor, as shown in <em class=\"calibre10\">Figure 14.2<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 14.2: AspNetUsers table with the registered user\" height=\"839\" src=\"\/images\/cs12\/000132.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 14.2: AspNetUsers table with the registered user<\/figcaption><\/figure>\n<\/section>\n<\/section>\n<section data-number=\"15.3\" id=\"calibre_link-747\">\n<h2 data-number=\"15.3\" class=\"calibre5\">Exploring an ASP.NET Core MVC website<\/h2>\n<p class=\"rights\">Let's walk through the parts that make up a modern ASP.NET Core MVC website.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">.NET 5 and earlier ASP.NET Core project templates used both a <code class=\"calibre9\">Program<\/code> class and a <code class=\"calibre9\">Startup<\/code> class to separate initialization and configuration, but with .NET 6 and later, Microsoft encourages putting everything in a single <code class=\"calibre9\">Program.cs<\/code> file.<\/p>\n<\/blockquote>\n<section data-number=\"15.3.1\" id=\"calibre_link-748\">\n<h3 data-number=\"15.3.1\" class=\"calibre8\">ASP.NET Core MVC initialization<\/h3>\n<p class=\"rights\">Appropriately enough, we will start by exploring the MVC website's default initialization and configuration:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, note that it can be divided into four important sections from top to bottom. As you review the sections, you might want to add regions to remind yourself of what each section is used for.<\/li>\n<li class=\"calibre3\">The first section imports some namespaces, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Import namespaces\nusing Microsoft.AspNetCore.Identity; \/\/ To use IdentityUser.\nusing Microsoft.EntityFrameworkCore; \/\/ To use UseSqlServer method.\nusing Northwind.Mvc.Data; \/\/ To use ApplicationDbContext.\n#endregion<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Remember that, by default, many other namespaces are imported using the implicit usings feature of .NET 6 and later. Build the project and then the globally imported namespaces can be found in the following file: <code class=\"calibre9\">obj\\Debug\\net8.0\\Northwind.Mvc.GlobalUsings.g.cs<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">The second section creates and configures a web host builder that does the following:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Registers an application database context using SQL Server or SQLite. The database connection string is loaded from the <code class=\"calibre9\">appsettings.json<\/code> file.<\/li>\n<li class=\"calibre3\">Adds ASP.NET Core Identity for authentication and configures it to use the application database.<\/li>\n<li class=\"calibre3\">Adds support for MVC controllers with views, as shown in the following code:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Configure the host web server including services\nvar builder = WebApplication.CreateBuilder(args);\n\/\/ Add services to the container.\nvar connectionString = builder.Configuration\n  .GetConnectionString(\"DefaultConnection\") ??\n  throw new InvalidOperationException(\n    \"Connection string 'DefaultConnection' not found.\");\nbuilder.Services.AddDbContext&lt;ApplicationDbContext&gt;(options =&gt;\n  options.UseSqlServer(connectionString)); \/\/ Or UseSqlite.\nbuilder.Services.AddDatabaseDeveloperPageExceptionFilter();\nbuilder.Services.AddDefaultIdentity&lt;IdentityUser&gt;(options =&gt; \n  options.SignIn.RequireConfirmedAccount = true)\n  .AddEntityFrameworkStores&lt;ApplicationDbContext&gt;();\nbuilder.Services.AddControllersWithViews();\nvar app = builder.Build();\n#endregion<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">builder<\/code> object has two commonly used objects, <code class=\"calibre9\">Configuration<\/code> and <code class=\"calibre9\">Services<\/code>:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Configuration<\/code> contains merged values from all the places you could set configuration: <code class=\"calibre9\">appsettings.json<\/code>, environment variables, command-line arguments, and so on.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Services<\/code> is a collection of registered dependency services.<\/li>\n<\/ul>\n<p class=\"rights\">The call to <code class=\"calibre9\">AddDbContext<\/code> is an example of registering a dependency service. ASP.NET Core implements the <strong class=\"calibre2\">dependency injection<\/strong> (<strong class=\"calibre2\">DI<\/strong>) design pattern so that other components like controllers can request needed services through their constructors. Developers register those services in this section of <code class=\"calibre9\">Program.cs<\/code> (or if using a <code class=\"calibre9\">Startup<\/code> class then in its <code class=\"calibre9\">ConfigureServices<\/code> method).<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">The third section configures the HTTP pipeline through which requests and responses flow in and out. It configures a relative URL path to run database migrations if the website runs in development, or a friendlier error page and HSTS for production. HTTPS redirection, static files, routing, and ASP.NET Identity are enabled, and an MVC default route and Razor Pages are configured, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Configure the HTTP request pipeline.\nif (app.Environment.IsDevelopment())\n{\n  app.UseMigrationsEndPoint();\n}\nelse\n{\n  app.UseExceptionHandler(\"\/Home\/Error\");\n  \/\/ The default HSTS value is 30 days. You may want to change this for production scenarios, see https:\/\/aka.ms\/aspnetcore-hsts.\n  app.UseHsts();\n}\napp.UseHttpsRedirection();\napp.UseStaticFiles();\napp.UseRouting();\napp.UseAuthorization();\napp.MapControllerRoute(\n  name: \"default\",\n  pattern: \"{controller=Home}\/{action=Index}\/{id?}\");\napp.MapRazorPages();\n#endregion<\/code><\/pre>\n<\/div>\n<p class=\"rights\">We learned about most of these methods and features in <em class=\"calibre10\">Chapter 13<\/em>, <em class=\"calibre10\">Building Websites Using ASP.NET Core Razor Pages<\/em>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: What does the extension method <code class=\"calibre9\">UseMigrationsEndPoint<\/code> do? You could read the official documentation, but it does not help much. For example, it does not tell us what relative URL path it defines by default: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.builder.migrationsendpointextensions.usemigrationsendpoint\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.builder.migrationsendpointextensions.usemigrationsendpoint<\/a>. Luckily, ASP.NET Core is open source, so we can read the source code and discover what it does, at the following link: <a href=\"https:\/\/github.com\/dotnet\/aspnetcore\/blob\/main\/src\/Middleware\/Diagnostics.EntityFrameworkCore\/src\/MigrationsEndPointOptions.cs#L18\">https:\/\/github.com\/dotnet\/aspnetcore\/blob\/main\/src\/Middleware\/Diagnostics.EntityFrameworkCore\/src\/MigrationsEndPointOptions.cs#L18<\/a>. Get into the habit of exploring the source code for ASP.NET Core to understand how it works.<\/p>\n<\/blockquote>\n<p class=\"rights\">Apart from the <code class=\"calibre9\">UseAuthorization<\/code> method, the most important new method in this section of <code class=\"calibre9\">Program.cs<\/code> is <code class=\"calibre9\">MapControllerRoute<\/code>, which maps a default route for use by MVC. This route is very flexible because it will map to almost any incoming URL, as you will see in the next topic.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Although we will not create any Razor Pages in this chapter, we need to leave the method call that maps Razor Page support because our MVC website uses ASP.NET Core Identity for authentication and authorization, and it uses a Razor Class Library for its user interface components, like visitor registration and login.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">The fourth and final section has a thread-blocking method call that runs the website and waits for incoming HTTP requests to respond to, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#region Start the host web server listening for HTTP requests.\napp.Run(); \/\/ This is a blocking call.\n#endregion<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"15.3.2\" id=\"calibre_link-749\">\n<h3 data-number=\"15.3.2\" class=\"calibre8\">The default MVC route<\/h3>\n<p class=\"rights\">The responsibility of a route is to discover the name of a controller class to instantiate and an action method to execute, with an optional <code class=\"calibre9\">id<\/code> parameter to pass into the method that will generate an HTTP response.A default route is configured for MVC, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">endpoints.MapControllerRoute(\n  name: \"default\",\n  pattern: \"{controller=Home}\/{action=Index}\/{id?}\");<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The route pattern has parts in curly brackets <code class=\"calibre9\">{}<\/code> called <strong class=\"calibre2\">segments<\/strong>, and they are like named parameters of a method. The value of these segments can be any <code class=\"calibre9\">string<\/code>. Segments in URLs are not case-sensitive.The route pattern looks at any URL path requested by the browser and matches it to extract the name of a <code class=\"calibre9\">controller<\/code>, the name of an <code class=\"calibre9\">action<\/code>, and an optional <code class=\"calibre9\">id<\/code> value (the <code class=\"calibre9\">?<\/code> symbol makes it optional).If the user hasn't entered these names, it uses the defaults of <code class=\"calibre9\">Home<\/code> for the controller and <code class=\"calibre9\">Index<\/code> for the action (the <code class=\"calibre9\">=<\/code> assignment sets a default for a named segment).<em class=\"calibre10\">Table 14.2<\/em> contains example URLs and how the default route would work out the names of a controller and action:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">URL<\/td>\n<td class=\"calibre21\">Controller<\/td>\n<td class=\"calibre21\">Action<\/td>\n<td class=\"calibre21\">ID<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\/<\/code><\/td>\n<td class=\"calibre21\">Home<\/td>\n<td class=\"calibre21\">Index<\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\/Muppet<\/code><\/td>\n<td class=\"calibre21\">Muppet<\/td>\n<td class=\"calibre21\">Index<\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\/Muppet\/Kermit<\/code><\/td>\n<td class=\"calibre21\">Muppet<\/td>\n<td class=\"calibre21\">Kermit<\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\/Muppet\/Kermit\/Green<\/code><\/td>\n<td class=\"calibre21\">Muppet<\/td>\n<td class=\"calibre21\">Kermit<\/td>\n<td class=\"calibre21\">Green<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\/Products<\/code><\/td>\n<td class=\"calibre21\">Products<\/td>\n<td class=\"calibre21\">Index<\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\/Products\/Detail<\/code><\/td>\n<td class=\"calibre21\">Products<\/td>\n<td class=\"calibre21\">Detail<\/td>\n<td class=\"calibre21\"><\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">\/Products\/Detail\/3<\/code><\/td>\n<td class=\"calibre21\">Products<\/td>\n<td class=\"calibre21\">Detail<\/td>\n<td class=\"calibre21\">3<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 14.2: Example URLs mapped via the default route<br \/>\n<\/section>\n<section data-number=\"15.3.3\" id=\"calibre_link-750\">\n<h3 data-number=\"15.3.3\" class=\"calibre8\">Controllers and actions<\/h3>\n<p class=\"rights\">In MVC, the C stands for <em class=\"calibre10\">controller<\/em>. From the route and an incoming URL, ASP.NET Core knows the name of the controller, so it will then look for a class that is decorated with the <code class=\"calibre9\">[Controller]<\/code> attribute or derives from a class decorated with that attribute, for example, the Microsoft-provided class named <code class=\"calibre9\">ControllerBase<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Microsoft.AspNetCore.Mvc\n{\n  \/\/\n  \/\/ Summary:\n  \/\/ A base class for an MVC controller without view support.\n  [Controller]\n  public abstract class ControllerBase\n  {\n...<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"15.3.4\" id=\"calibre_link-751\">\n<h3 data-number=\"15.3.4\" class=\"calibre8\">The ControllerBase class<\/h3>\n<p class=\"rights\">As you can see in the XML comment, <code class=\"calibre9\">ControllerBase<\/code> does not support views. It is used for creating web services, as you will see in <em class=\"calibre10\">Chapter 15<\/em>, <em class=\"calibre10\">Building and Consuming Web Services<\/em>.<code class=\"calibre9\">ControllerBase<\/code> has many useful properties for working with the current HTTP context, as shown in <em class=\"calibre10\">Table 14.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Property<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Request<\/code><\/td>\n<td class=\"calibre21\">Just the HTTP request, for example, headers, query string parameters, the body of the request as a stream that you can read from, the content type and length, and cookies.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Response<\/code><\/td>\n<td class=\"calibre21\">Just the HTTP response, for example, headers, the body of the response as a stream that you can write to, the content type and length, status code, and cookies. There are also delegates like <code class=\"calibre9\">OnStarting<\/code> and <code class=\"calibre9\">OnCompleted<\/code> that you can hook a method up to.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">HttpContext<\/code><\/td>\n<td class=\"calibre21\">Everything about the current HTTP context including the request and response, information about the connection, a collection of features that have been enabled on the server with middleware, and a <code class=\"calibre9\">User<\/code> object for authentication and authorization.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 14.3: Useful properties for working with the current HTTP context<br \/>\n<\/section>\n<section data-number=\"15.3.5\" id=\"calibre_link-752\">\n<h3 data-number=\"15.3.5\" class=\"calibre8\">The Controller class<\/h3>\n<p class=\"rights\">Microsoft provides another class named <code class=\"calibre9\">Controller<\/code> that your classes can inherit from if they need view support, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Microsoft.AspNetCore.Mvc\n{\n  \/\/\n  \/\/ Summary:\n  \/\/ A base class for an MVC controller with view support.\n  public abstract class Controller : ControllerBase,\n    IActionFilter, IFilterMetadata, IAsyncActionFilter, IDisposable\n  {\n...<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><code class=\"calibre9\">Controller<\/code> has many useful properties for working with views, as shown in <em class=\"calibre10\">Table 14.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Property<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ViewData<\/code><\/td>\n<td class=\"calibre21\">A dictionary in which the controller can store key\/value pairs that is accessible in a view. The dictionary's lifetime is only for the current request\/response.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ViewBag<\/code><\/td>\n<td class=\"calibre21\">A dynamic object that wraps the <code class=\"calibre9\">ViewData<\/code> to provide a friendlier syntax for setting and getting dictionary values.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">TempData<\/code><\/td>\n<td class=\"calibre21\">A dictionary in which the controller can store key\/value pairs that is accessible in a view. The dictionary's lifetime is for the current request\/response and the next request\/response for the same visitor session. This is useful for storing a value during an initial request, responding with a redirect, and then reading the stored value in the subsequent request.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 14.4: Useful properties for working with views<\/p>\n<p class=\"rights\"><code class=\"calibre9\">Controller<\/code> has many useful methods for working with views, as shown in <em class=\"calibre10\">Table 14.5<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Method<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">View<\/code><\/td>\n<td class=\"calibre21\">Returns a <code class=\"calibre9\">ViewResult<\/code> after executing a view that renders a full response, for example, a dynamically generated web page. The view can be selected using a convention or be specified with a string name. A model can be passed to the view.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">PartialView<\/code><\/td>\n<td class=\"calibre21\">Returns a <code class=\"calibre9\">PartialViewResult<\/code> after executing a view that is part of a full response, for example, a dynamically generated chunk of HTML. The view can be selected using a convention or be specified with a string name. A model can be passed to the view.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ViewComponent<\/code><\/td>\n<td class=\"calibre21\">Returns a <code class=\"calibre9\">ViewComponentResult<\/code> after executing a component that dynamically generates HTML. The component must be selected by specifying its type or its name. An object can be passed as an argument.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Json<\/code><\/td>\n<td class=\"calibre21\">Returns a <code class=\"calibre9\">JsonResult<\/code> containing a JSON-serialized object. This can be useful for implementing a simple Web API as part of an MVC controller that primarily returns HTML for a human to view.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 14.5: Useful methods for working with views<br \/>\n<\/section>\n<section data-number=\"15.3.6\" id=\"calibre_link-753\">\n<h3 data-number=\"15.3.6\" class=\"calibre8\">The responsibilities of a controller<\/h3>\n<p class=\"rights\">The responsibilities of a controller are as follows:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Identify the services that the controller needs to be in a valid state and to function properly in their class constructor(s).<\/li>\n<li class=\"calibre3\">Use the action name to identify a method to execute.<\/li>\n<li class=\"calibre3\">Extract parameters from the HTTP request.<\/li>\n<li class=\"calibre3\">Use the parameters to fetch any additional data needed to construct a view model and pass it to the appropriate view for the client. For example, if the client is a web browser, then a view that renders HTML would be most appropriate. Other clients might prefer alternative renderings, like document formats such as a PDF file or an Excel file, or data formats, like JSON or XML.<\/li>\n<li class=\"calibre3\">Return the results from the view to the client as an HTTP response with an appropriate status code.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Controllers should be <em class=\"calibre10\">thin<\/em>, meaning they only perform the above-listed activities but do not implement any business logic. All business logic should be implemented in services that the controller calls when needed.<\/p>\n<\/blockquote>\n<p class=\"rights\">Let's review the controller used to generate the home, privacy, and error pages:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Expand the <code class=\"calibre9\">Controllers<\/code> folder.<\/li>\n<li class=\"calibre3\">Open the file named <code class=\"calibre9\">HomeController.cs<\/code>.<\/li>\n<li class=\"calibre3\">Note, as shown in the following code, that:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Extra namespaces are imported, which I have added comments for to show which types they are needed for.<\/li>\n<li class=\"calibre3\">A private read-only field is declared to store a reference to a logger for the <code class=\"calibre9\">HomeController<\/code> that is set in a constructor.<\/li>\n<li class=\"calibre3\">All three action methods call a method named <code class=\"calibre9\">View<\/code> and return the results as an <code class=\"calibre9\">IActionResult<\/code> interface to the client.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">Error<\/code> action method passes a view model into its view with a request ID used for tracing. The error response will not be cached:<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.AspNetCore.Mvc; \/\/ To use Controller, IActionResult.\nusing Northwind.Mvc.Models; \/\/ To use ErrorViewModel.\nusing System.Diagnostics; \/\/ To use Activity.\nnamespace Northwind.Mvc.Controllers;\npublic class HomeController : Controller\n{\n  private readonly ILogger&lt;HomeController&gt; _logger;\n  public HomeController(ILogger&lt;HomeController&gt; logger)\n  {\n    _logger = logger;\n  }\n  public IActionResult Index()\n  {\n    return View();\n  }\n  public IActionResult Privacy()\n  {\n    return View();\n  }\n  [ResponseCache(Duration = 0,\n    Location = ResponseCacheLocation.None, NoStore = true)]\n  public IActionResult Error()\n  {\n    return View(new ErrorViewModel { RequestId = \n      Activity.Current?.Id ?? HttpContext.TraceIdentifier });\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If the visitor navigates to a path of <code class=\"calibre9\">\/<\/code> or <code class=\"calibre9\">\/Home<\/code>, then it is the equivalent of <code class=\"calibre9\">\/Home\/Index<\/code> because those were the default names for the controller and action in the default route.<\/p>\n<\/section>\n<section data-number=\"15.3.7\" id=\"calibre_link-754\">\n<h3 data-number=\"15.3.7\" class=\"calibre8\">The view search path convention<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">Index<\/code> and <code class=\"calibre9\">Privacy<\/code> methods are identical in implementation, yet they return different web pages. This is because of <strong class=\"calibre2\">conventions<\/strong>. The call to the <code class=\"calibre9\">View<\/code> method looks in different paths for the Razor file to generate the web page.Let's deliberately break one of the page names so that we can see the paths searched by default:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Mvc<\/code> project, expand the <code class=\"calibre9\">Views<\/code> folder and then the <code class=\"calibre9\">Home<\/code> folder.<\/li>\n<li class=\"calibre3\">Rename the <code class=\"calibre9\">Privacy.cshtml<\/code> file to <code class=\"calibre9\">Privacy2.cshtml<\/code>.<\/li>\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Start Chrome, navigate to <code class=\"calibre9\">https:\/\/localhost:5141\/<\/code>, click <strong class=\"calibre2\">Privacy<\/strong>, and note the paths that are searched for a view to render the web page (including in <code class=\"calibre9\">Shared<\/code> folders for MVC views and Razor Pages) in the exception in both the browser and the command prompt or terminal output, as shown in <em class=\"calibre10\">Figure 14.3<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 14.3: An exception showing the default search path for views\" height=\"941\" src=\"\/images\/cs12\/000091.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 14.3: An exception showing the default search path for views<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<li class=\"calibre3\">Rename the <code class=\"calibre9\">Privacy2.cshtml<\/code> file back to <code class=\"calibre9\">Privacy.cshtml<\/code>.<\/li>\n<\/ol>\n<p class=\"rights\">You have now seen the view search path convention, as shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Specific Razor view: <code class=\"calibre9\">\/Views\/{controller}\/{action}.cshtml<\/code><\/li>\n<li class=\"calibre3\">Shared Razor view: <code class=\"calibre9\">\/Views\/Shared\/{action}.cshtml<\/code><\/li>\n<li class=\"calibre3\">Shared Razor Page: <code class=\"calibre9\">\/Pages\/Shared\/{action}.cshtml<\/code><\/li>\n<\/ul>\n<\/section>\n<section data-number=\"15.3.8\" id=\"calibre_link-755\">\n<h3 data-number=\"15.3.8\" class=\"calibre8\">Logging using the dependency service<\/h3>\n<p class=\"rights\">You have just seen that some errors are caught and written to the console. You can write your own messages to the console in the same way by using the logger.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Controllers<\/code> folder, in <code class=\"calibre9\">HomeController.cs<\/code>, in the <code class=\"calibre9\">Index<\/code> method, add statements before the <code class=\"calibre9\">return<\/code> statement to use the logger to write some messages of various levels to the console, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public IActionResult Index()\n{\n  _logger.LogError(\"This is a serious error (not really!)\");\n  _logger.LogWarning(\"This is your first warning!\");\n  _logger.LogWarning(\"Second warning!\");\n  _logger.LogInformation(\"I am in the Index method of the HomeController.\");\n  return View();\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Start Chrome and navigate to the home page for the website.<\/li>\n<li class=\"calibre3\">At the command prompt or terminal, note the messages, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">fail: Northwind.Mvc.Controllers.HomeController[0]\n      This is a serious error (not really!)\nwarn: Northwind.Mvc.Controllers.HomeController[0]\n      This is your first warning!\nwarn: Northwind.Mvc.Controllers.HomeController[0]\n      Second warning!\ninfo: Northwind.Mvc.Controllers.HomeController[0]\n      I am in the Index method of the HomeController.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn a lot more about ASP.NET Core logging at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/logging\/\">https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/logging\/<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"15.3.9\" id=\"calibre_link-756\">\n<h3 data-number=\"15.3.9\" class=\"calibre8\">Using entity and view models<\/h3>\n<p class=\"rights\">In MVC, the M stands for <em class=\"calibre10\">model<\/em>. Models represent the data required to respond to a request. There are two types of models commonly used: entity models and view models.<strong class=\"calibre2\">Entity models<\/strong> represent entities in a database like SQL Server or SQLite. Based on the request, one or more entities might need to be retrieved from data storage. Entity models are defined using classes, since they might need to change and then be used to update the underlying data store.All the data that we want to show in response to a request is the <strong class=\"calibre2\">MVC model<\/strong>, sometimes called a <strong class=\"calibre2\">view model<\/strong>, because it is a model that is passed into a view for rendering into a response format like HTML or JSON. View models should be immutable, so they are commonly defined using records.For example, the following HTTP <code class=\"calibre9\">GET<\/code> request might mean that the browser is asking for the product details page for product number 3: <a href=\"http:\/\/www.example.com\/products\/details\/3\">http:\/\/www.example.com\/products\/details\/3<\/a>.The controller would need to use the ID route value 3 to retrieve the entity for that product and pass it to a view that can then turn the model into HTML for display in a browser.Imagine that when a user comes to our website, we want to show them a carousel of categories, a list of products, and a count of the number of visitors we have had this month.We will reference the Entity Framework Core entity data model for the Northwind database that you created in <em class=\"calibre10\">Chapter 12<\/em>, <em class=\"calibre10\">Introducing Web Development Using ASP.NET Core<\/em>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Mvc<\/code> project, add a project reference to <code class=\"calibre9\">Northwind.DataContext<\/code> for either SQLite or SQL Server, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;!-- change Sqlite to SqlServer if you prefer --&gt;\n  &lt;ProjectReference Include=\n\"..\\Northwind.DataContext.Sqlite\\Northwind.DataContext.Sqlite.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you are using SQL Server, then add a package reference for ADO.NET for SQL Server, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PackageReference\n  Include=\"Microsoft.Data.SqlClient\" Version=\"5.1.1\" \/&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.Mvc<\/code> project to compile its dependencies.<\/li>\n<li class=\"calibre3\">If you are using SQL Server, or if you might want to switch to SQL Server from SQLite, then in <code class=\"calibre9\">appsettings.json<\/code>, add a connection string for the Northwind database using SQL Server, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Server=(localdb)\\\\mssqllocaldb;Database=aspnet-Northwind.Mvc-DC9C4FAF-DD84-4FC9-B925-69A61240EDA7;Trusted_Connection=True;MultipleActiveResultSets=true\",\n    \"NorthwindConnection\": \"Server=.;Database=Northwind;Integrated Security=True;MultipleActiveResultSets=true;TrustServerCertificate=true;\"\n  },<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Modify the connection string to match wherever your Northwind database is, for example, in Azure SQL Database in the cloud or Azure SQL Edge in Docker, for example. If you have to use SQL Server authentication, do not store the user and password in this file! You will set them from environment variables in code.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, import the namespace to work with your entity model types, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.EntityModels; \/\/ To use AddNorthwindContext method.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Before the <code class=\"calibre9\">builder.Build<\/code> method call, add statements to load the appropriate connection string and then to register the <code class=\"calibre9\">Northwind<\/code> database context, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ If you are using SQLite, default is \"..\\Northwind.db\".\nbuilder.Services.AddNorthwindContext();\n\/*\n\/\/ If you are using SQL Server.\nstring? sqlServerConnection = builder.Configuration\n  .GetConnectionString(\"NorthwindConnection\");\nif (sqlServerConnection is null)\n{\n  Console.WriteLine(\"SQL Server database connection string is missing!\");\n}\nelse\n{\n  \/\/ If you are using SQL Server authentication then disable\n  \/\/ Windows Integrated authentication and set user and password.\n  Microsoft.Data.SqlClient.SqlConnectionStringBuilder sql = \n    new(sqlServerConnection);\n  sql.IntegratedSecurity = false;\n  sql.UserID = Environment.GetEnvironmentVariable(\"MY_SQL_USR\");\n  sql.Password = Environment.GetEnvironmentVariable(\"MY_SQL_PWD\");\n  builder.Services.AddNorthwindContext(sql.ConnectionString);\n}\n*\/<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">In the <code class=\"calibre9\">Models<\/code> folder, add a class file named <code class=\"calibre9\">HomeIndexViewModel.cs<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Although the <code class=\"calibre9\">ErrorViewModel<\/code> class created by the MVC project template does not follow this convention, I recommend that you use the naming convention <code class=\"calibre9\">{Controller}{Action}ViewModel<\/code> for your view model classes.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">HomeIndexViewModel.cs<\/code>, add statements to define a record that has three properties for a count of the number of visitors, and lists of categories and products, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.EntityModels; \/\/ To use Category, Product.\nnamespace Northwind.Mvc.Models;\npublic record HomeIndexViewModel(int VisitorCount,\n  IList&lt;Category&gt; Categories, IList&lt;Product&gt; Products);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">HomeController.cs<\/code>, import the <code class=\"calibre9\">Northwind.EntityModels<\/code> namespace, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.EntityModels; \/\/ To use NorthwindContext.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add a field to store a reference to a <code class=\"calibre9\">Northwind<\/code> instance and initialize it in the constructor, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class HomeController : Controller\n{\n  private readonly ILogger&lt;HomeController&gt; _logger;\n  private readonly NorthwindContext _db;\n  public HomeController(ILogger&lt;HomeController&gt; logger,\n    NorthwindContext db)\n  {\n    _logger = logger;\n    _db = db;\n  }<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">ASP.NET Core will use constructor parameter injection to pass an instance of the <code class=\"calibre9\">NorthwindContext<\/code> database context using the connection string you specified in <code class=\"calibre9\">Program.cs<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Index<\/code> action method, create an instance of the view model for this method, simulating a visitor count using the <code class=\"calibre9\">Random<\/code> class to generate a number between 1 and 1,000, and using the <code class=\"calibre9\">Northwind<\/code> database to get lists of categories and products and then pass the model to the view, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">  HomeIndexViewModel model = new\n  (\n    VisitorCount: Random.Shared.Next(1, 1001),\n    Categories: _db.Categories.ToList(),\n    Products: _db.Products.ToList()\n  );\n  return View(model); \/\/ Pass the model to the view.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Remember the view search convention: when the <code class=\"calibre9\">View<\/code> method is called in a controller's action method, ASP.NET Core MVC looks in the <code class=\"calibre9\">Views<\/code> folder for a subfolder with the same name as the current controller, that is, <code class=\"calibre9\">Home<\/code>. It then looks for a file with the same name as the current action, that is, <code class=\"calibre9\">Index.cshtml<\/code>. It will also search for views that match the action method name in the <code class=\"calibre9\">Shared<\/code> folder and for Razor Pages in the <code class=\"calibre9\">Pages<\/code> folder.<\/p>\n<\/section>\n<section data-number=\"15.3.10\" id=\"calibre_link-757\">\n<h3 data-number=\"15.3.10\" class=\"calibre8\">Implementing views<\/h3>\n<p class=\"rights\">In MVC, the V stands for <em class=\"calibre10\">view<\/em>. The responsibility of a view is to transform a model into HTML or other formats.There are multiple <strong class=\"calibre2\">view engines<\/strong> that could be used to do this. The default view engine is called <strong class=\"calibre2\">Razor<\/strong>, and it uses the <code class=\"calibre9\">@<\/code> symbol to indicate server-side code execution. The Razor Pages feature introduced with ASP.NET Core 2 uses the same view engine and so can use the same Razor syntax.Let's modify the home page view to render the lists of categories and products:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Expand the <code class=\"calibre9\">Views<\/code> folder, and then expand the <code class=\"calibre9\">Home<\/code> folder.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Index.cshtml<\/code>, note the block of C# code wrapped in <code class=\"calibre9\">@{ }<\/code>. This will execute first and can be used to store data that needs to be passed into a shared layout file, like the title of the web page, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@{\n  ViewData[\"Title\"] = \"Home Page\";\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the static HTML content in the <code class=\"calibre9\">&lt;div&gt;<\/code> element that uses Bootstrap for styling.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: As well as defining your own styles, base your styles on a common library, such as Bootstrap, that implements responsive design.<\/p>\n<\/blockquote>\n<p class=\"rights\">Just as with Razor Pages, there is a file named <code class=\"calibre9\">_ViewStart.cshtml<\/code> that gets executed by the <code class=\"calibre9\">View<\/code> method. It is used to set defaults that apply to all views.For example, it sets the <code class=\"calibre9\">Layout<\/code> property of all views to a shared layout file, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@{\n  Layout = \"_Layout\";\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Views<\/code> folder, in <code class=\"calibre9\">_ViewImports.cshtml<\/code>, note that it imports some namespaces and then adds the ASP.NET Core tag helpers, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@using Northwind.Mvc \n@using Northwind.Mvc.Models\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Shared<\/code> folder, open the <code class=\"calibre9\">_Layout.cshtml<\/code> file.<\/li>\n<li class=\"calibre3\">Note that the title is being read from the <code class=\"calibre9\">ViewData<\/code> dictionary that was set earlier in the <code class=\"calibre9\">Index.cshtml<\/code> view, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;title&gt;@ViewData[\"Title\"] &ndash; Northwind.Mvc&lt;\/title&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the rendering of links to support Bootstrap and a site stylesheet, where <code class=\"calibre9\">~<\/code> means the <code class=\"calibre9\">wwwroot<\/code> folder, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;link rel=\"stylesheet\" \n  href=\"~\/lib\/bootstrap\/dist\/css\/bootstrap.css\" \/&gt;\n&lt;link rel=\"stylesheet\" href=\"~\/css\/site.css\" \/&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In <em class=\"calibre10\">Chapter 13<\/em>, <em class=\"calibre10\">Building Websites Using ASP.NET Core Razor Pages<\/em>, we used the public link to the Bootstrap website to reference version 5.3. The MVC project template uses a local copy of Bootstrap version 5.1. This might have been updated to a later version by the time you read this.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the rendering of a navigation bar in the header, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;body&gt;\n  &lt;header&gt;\n    &lt;nav class=\"navbar ...\"&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the rendering of a collapsible <code class=\"calibre9\">&lt;div&gt;<\/code> containing a partial view for logging in, and hyperlinks to allow users to navigate between pages using ASP.NET Core tag helpers with attributes like <code class=\"calibre9\">asp-controller<\/code> and <code class=\"calibre9\">asp-action<\/code>, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;div class=\n  \"navbar-collapse collapse d-sm-inline-flex justify-content-between\"&gt;\n  &lt;ul class=\"navbar-nav flex-grow-1\"&gt;\n    &lt;li class=\"nav-item\"&gt;\n      &lt;a class=\"nav-link text-dark\" asp-area=\"\"\n        asp-controller=\"Home\" asp-action=\"Index\"&gt;Home&lt;\/a&gt;\n    &lt;\/li&gt;\n    &lt;li class=\"nav-item\"&gt;\n      &lt;a class=\"nav-link text-dark\"\n        asp-area=\"\" asp-controller=\"Home\" \n        asp-action=\"Privacy\"&gt;Privacy&lt;\/a&gt;\n    &lt;\/li&gt;\n  &lt;\/ul&gt;\n  &lt;partial name=\"_LoginPartial\" \/&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">&lt;a&gt;<\/code> elements use tag helper attributes named <code class=\"calibre9\">asp-controller<\/code> and <code class=\"calibre9\">asp-action<\/code> to specify the controller name and action name that will execute when the link is clicked on. If you want to navigate to a feature in a Razor Class Library, like the <code class=\"calibre9\">employees<\/code> component that you created in the previous chapter, then you use <code class=\"calibre9\">asp-area<\/code> to specify the feature name.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the rendering of the body inside the <code class=\"calibre9\">&lt;main&gt;<\/code> element, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;div class=\"container\"&gt;\n  &lt;main role=\"main\" class=\"pb-3\"&gt;\n    @RenderBody()\n  &lt;\/main&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">RenderBody<\/code> method injects the contents of a specific Razor view for a page like the <code class=\"calibre9\">Index.cshtml<\/code> file at that point in the shared layout.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note the rendering of <code class=\"calibre9\">&lt;script&gt;<\/code> elements at the bottom of the page so that it does not slow down the display of the page, and that you can add your own script blocks into an optional defined section named <code class=\"calibre9\">scripts<\/code>, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;script src=\"~\/lib\/jquery\/dist\/jquery.min.js\"&gt;&lt;\/script&gt;\n&lt;script src=\"~\/lib\/bootstrap\/dist\/js\/bootstrap.bundle.min.js\"&gt;\n&lt;\/script&gt;\n&lt;script src=\"~\/js\/site.js\" asp-append-version=\"true\"&gt;&lt;\/script&gt; \n@await RenderSectionAsync(\"Scripts\", required: false)<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">_LoginPartial.cshtml<\/code>, note the log-in functionality is implemented using the ASP.NET Core Identity system as Razor Pages using an <code class=\"calibre9\">asp-area<\/code> named <code class=\"calibre9\">Identity<\/code>, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@using Microsoft.AspNetCore.Identity\n@inject SignInManager&lt;IdentityUser&gt; SignInManager\n@inject UserManager&lt;IdentityUser&gt; UserManager\n&lt;ul class=\"navbar-nav\"&gt;\n  @if (SignInManager.IsSignedIn(User))\n  {\n    &lt;li class=\"nav-item\"&gt;\n      &lt;a class=\"nav-link text-dark\" asp-area=\"Identity\" \n         asp-page=\"\/Account\/Manage\/Index\" title=\"Manage\"&gt;\n      Hello @User.Identity?.Name!&lt;\/a&gt;\n    &lt;\/li&gt;\n    &lt;li class=\"nav-item\"&gt;\n      &lt;form class=\"form-inline\" asp-area=\"Identity\" \n            asp-page=\"\/Account\/Logout\" \n            asp-route-returnUrl=\"@Url.Action(\"Index\", \"Home\", \n            new { area = \"\" })\"&gt;\n        &lt;button type=\"submit\" class=\"nav-link btn \n                btn-link text-dark\"&gt;Logout&lt;\/button&gt;\n      &lt;\/form&gt;\n    &lt;\/li&gt;\n  }\n  else\n  {\n    &lt;li class=\"nav-item\"&gt;\n      &lt;a class=\"nav-link text-dark\" asp-area=\"Identity\" \n         asp-page=\"\/Account\/Register\"&gt;Register&lt;\/a&gt;\n    &lt;\/li&gt;\n    &lt;li class=\"nav-item\"&gt;\n      &lt;a class=\"nav-link text-dark\" asp-area=\"Identity\" \n         asp-page=\"\/Account\/Login\"&gt;Login&lt;\/a&gt;\n    &lt;\/li&gt;\n  }\n&lt;\/ul&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">_ValidationScriptsPartial.cshtml<\/code>, note this partial view has references to a pair of jQuery scripts for performing validation, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;script src=\"~\/lib\/jquery-validation\/dist\/jquery.validate.min.js\"&gt;&lt;\/script&gt;\n&lt;script src=\"~\/lib\/jquery-validation-unobtrusive\/jquery.validate.unobtrusive.min.js\"&gt;&lt;\/script&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If you create a Razor View that uses a model with validation attributes like <code class=\"calibre9\">[Required]<\/code> and <code class=\"calibre9\">[StringLength]<\/code>, then add this partial view to the <code class=\"calibre9\">Scripts<\/code> block to enable validation on the client side by the browser, as shown in the following markup:<\/p>\n<\/blockquote>\n<pre class=\"calibre22\"><code class=\"calibre23\">@section Scripts {\n  &lt;partial name=\"_ValidationScriptsPartial\" \/&gt;\n}<\/code><\/pre>\n<\/section>\n<section data-number=\"15.3.11\" id=\"calibre_link-758\">\n<h3 data-number=\"15.3.11\" class=\"calibre8\">How cache busting with Tag Helpers works<\/h3>\n<p class=\"rights\">When <code class=\"calibre9\">asp-append-version<\/code> is specified with a <code class=\"calibre9\">true<\/code> value in a <code class=\"calibre9\">&lt;link&gt;<\/code>, <code class=\"calibre9\">&lt;img&gt;<\/code>, or <code class=\"calibre9\">&lt;script&gt;<\/code> element, the Tag Helper for that tag type is invoked.They work by automatically appending a query string value named <code class=\"calibre9\">v<\/code> that is generated from a SHA256 hash of the referenced source file, as shown in the following example generated output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;script src=\"~\/js\/site.js? v=Kl_dqr9NVtnMdsM2MUg4qthUnWZm5T1fCEimBPWDNgM\"&gt;&lt;\/script&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can see this for yourself in the current project because the <code class=\"calibre9\">_Layout.cshtml<\/code> file has the <code class=\"calibre9\">&lt;script src=\"~\/js\/site.js\" asp-append-version=\"true\"&gt;&lt;\/script&gt;<\/code> element.<\/p>\n<\/blockquote>\n<p class=\"rights\">If even a single byte within the <code class=\"calibre9\">site.js<\/code> file changes, then its hash value will be different, and therefore if a browser or CDN is caching the script file, then it will bust the cached copy and replace it with the new version.The <code class=\"calibre9\">src<\/code> attribute must be set to a static file stored on the local web server, usually in the <code class=\"calibre9\">wwwroot<\/code> folder, but you can configure additional locations. Remote references are not supported.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"15.4\" id=\"calibre_link-759\">\n<h2 data-number=\"15.4\" class=\"calibre5\">Customizing an ASP.NET Core MVC website<\/h2>\n<p class=\"rights\">Now that you've reviewed the structure of a basic MVC website, you will customize and extend it. You have already registered an EF Core model for the <code class=\"calibre9\">Northwind<\/code> database, so the next task is to output some of that data on the home page.<\/p>\n<section data-number=\"15.4.1\" id=\"calibre_link-760\">\n<h3 data-number=\"15.4.1\" class=\"calibre8\">Defining a custom style<\/h3>\n<p class=\"rights\">The home page will show a list of the 77 products in the Northwind database. To make efficient use of space, we want to show the list in three columns. To do this, we need to customize the stylesheet for the website:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">wwwroot\\css<\/code> folder, open the <code class=\"calibre9\">site.css<\/code> file.<\/li>\n<li class=\"calibre3\">At the bottom of the file, add a new style that will apply to an element with the <code class=\"calibre9\">product-columns<\/code> ID, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">#product-columns\n{\n  column-count: 3;\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"15.4.2\" id=\"calibre_link-761\">\n<h3 data-number=\"15.4.2\" class=\"calibre8\">Setting up the category images<\/h3>\n<p class=\"rights\">The Northwind database includes a table of eight categories, but they do not have images, and websites look better with some colorful pictures:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">wwwroot<\/code> folder, create a folder named <code class=\"calibre9\">images<\/code>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">images<\/code> folder, add eight image files named <code class=\"calibre9\">category1.jpeg<\/code>, <code class=\"calibre9\">category2.jpeg<\/code>, and so on, up to <code class=\"calibre9\">category8.jpeg<\/code>.<\/li>\n<\/ol>\n<p class=\"rights\">You can download images from the GitHub repository for this book at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/images\/cs12\/Categories\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/images\/cs12\/Categories<\/a><\/p>\n<\/section>\n<section data-number=\"15.4.3\" id=\"calibre_link-762\">\n<h3 data-number=\"15.4.3\" class=\"calibre8\">Razor syntax and expressions<\/h3>\n<p class=\"rights\">Before we customize the home page view, let's review an example Razor file. The file has an initial Razor code block that instantiates an order with the price and quantity, and then outputs information about the order on the web page, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@{\n  Order order = new()\n  {\n    OrderId = 123,\n    Product = \"Sushi\",\n    Price = 8.49M,\n    Quantity = 3\n  };\n}\n&lt;div&gt;Your order for @order.Quantity of @order.Product has a total cost of $@ order.Price * @order.Quantity&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The preceding Razor file would result in the following incorrect output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Your order for 3 of Sushi has a total cost of $8.49 * 3<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Although Razor markup can include the value of any single property using the <code class=\"calibre9\">@object.property<\/code> syntax, you should wrap expressions in parentheses, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;div&gt;Your order for @order.Quantity of @order.Product has a total cost of $@ (order.Price * order.Quantity)&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The preceding Razor expression results in the following correct output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Your order for 3 of Sushi has a total cost of $25.47<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"15.4.4\" id=\"calibre_link-763\">\n<h3 data-number=\"15.4.4\" class=\"calibre8\">Defining a typed view<\/h3>\n<p class=\"rights\">To improve the IntelliSense when writing a view, you can define what type the view can expect using an <code class=\"calibre9\">@model<\/code> directive at the top:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Views\\Home<\/code> folder, open <code class=\"calibre9\">Index.cshtml<\/code>.<\/li>\n<li class=\"calibre3\">At the top of the file, add statements to import the namespace for Northwind entities and set the model type to use the <code class=\"calibre9\">HomeIndexViewModel<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@using Northwind.EntityModels\n@model HomeIndexViewModel<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Now, whenever we type <code class=\"calibre9\">Model<\/code> in this view, your code editor will know the correct type for the model and will provide IntelliSense for it.While entering code in a view, remember the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Declare the type for the model using <code class=\"calibre9\">@model<\/code> (with a lowercase m).<\/li>\n<li class=\"calibre3\">Interact with the instance of the model using <code class=\"calibre9\">@Model<\/code> (with an uppercase M).<\/li>\n<\/ul>\n<p class=\"rights\">Let's continue customizing the view for the home page.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the initial Razor code block, add a statement to declare a <code class=\"calibre9\">string<\/code> variable for the current item, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@{\n  ViewData[\"Title\"] = \"Home Page\";\n  string currentItem = \"\";\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Under the existing <code class=\"calibre9\">&lt;div&gt;<\/code> element, after its closing <code class=\"calibre9\">&lt;\/div&gt;<\/code>, add new markup to output categories in a carousel and products as an unordered list, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@if (Model is not null)\n{\n&lt;div id=\"categories\" class=\"carousel slide\" data-bs-ride=\"carousel\" \n     data-bs-interval=\"3000\" data-keyboard=\"true\"&gt;\n  &lt;ol class=\"carousel-indicators\"&gt;\n  @for (int c = 0; c &lt; Model.Categories.Count; c++)\n  {\n    if (c == 0)\n    {\n      currentItem = \"active\";\n    }\n    else\n    {\n      currentItem = \"\";\n    }\n    &lt;li data-bs-target=\"#categories\" data-bs-slide-to=\"@c\"  \n        class=\"@currentItem\"&gt;&lt;\/li&gt;\n  }\n  &lt;\/ol&gt;\n  &lt;div class=\"carousel-inner\"&gt;\n  @for (int c = 0; c &lt; Model.Categories.Count; c++)\n  {\n    if (c == 0)\n    {\n      currentItem = \"active\";\n    }\n    else\n    {\n      currentItem = \"\";\n    }\n    &lt;div class=\"carousel-item @currentItem\"&gt;\n      &lt;img class=\"d-block w-100\" src=   \n        \"~\/images\/cs12\/category@(Model.Categories.CategoryId).jpeg\"  \n        alt=\"@Model.Categories.CategoryName\" \/&gt;\n      &lt;div class=\"carousel-caption d-none d-md-block\"&gt;\n        &lt;h2&gt;@Model.Categories.CategoryName&lt;\/h2&gt;\n        &lt;h3&gt;@Model.Categories.Description&lt;\/h3&gt;\n        &lt;p&gt;\n          &lt;a class=\"btn btn-primary\" href=\"\/home\/categorydetail\/\n@Model.Categories.CategoryId\"&gt;View&lt;\/a&gt;\n        &lt;\/p&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n  }\n  &lt;\/div&gt;\n  &lt;a class=\"carousel-control-prev\" href=\"#categories\" \n    role=\"button\" data-bs-slide=\"prev\"&gt;\n    &lt;span class=\"carousel-control-prev-icon\" \n      aria-hidden=\"true\"&gt;&lt;\/span&gt;\n    &lt;span class=\"sr-only\"&gt;Previous&lt;\/span&gt;\n  &lt;\/a&gt;\n  &lt;a class=\"carousel-control-next\" href=\"#categories\" \n    role=\"button\" data-bs-slide=\"next\"&gt;\n    &lt;span class=\"carousel-control-next-icon\" aria-hidden=\"true\"&gt;&lt;\/span&gt;\n    &lt;span class=\"sr-only\"&gt;Next&lt;\/span&gt;\n  &lt;\/a&gt;\n&lt;\/div&gt;\n}\n&lt;div class=\"row\"&gt;\n  &lt;div class=\"col-md-12\"&gt;\n    &lt;h1&gt;Northwind&lt;\/h1&gt;\n    &lt;p class=\"lead\"&gt;\n      We have had @Model?.VisitorCount visitors this month.\n    &lt;\/p&gt;\n    @if (Model is not null)\n    {\n    &lt;h2&gt;Products&lt;\/h2&gt;\n    &lt;div id=\"product-columns\"&gt;\n      &lt;ul class=\"list-group\"&gt;\n      @foreach (Product p in @Model.Products)\n      {\n        &lt;li class=\"list-group-item d-flex justify-content-between align-items-start\"&gt;\n          &lt;a asp-controller=\"Home\" asp-action=\"ProductDetail\"\n             asp-route-id=\"@p.ProductId\" class=\"btn btn-outline-primary\"&gt;\n            &lt;div class=\"ms-2 me-auto\"&gt;@p.ProductName&lt;\/div&gt;\n            &lt;span class=\"badge bg-primary rounded-pill\"&gt;\n              @(p.UnitPrice is null ? \"zero\" : p.UnitPrice.Value.ToString(\"C\"))\n            &lt;\/span&gt;\n          &lt;\/a&gt;\n        &lt;\/li&gt;\n      }\n      &lt;\/ul&gt;\n    &lt;\/div&gt;\n    }\n  &lt;\/div&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">While reviewing the preceding Razor markup, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">JetBrains Rider might tell you that <code class=\"calibre9\">Model<\/code> is never <code class=\"calibre9\">null<\/code>, so you do not need to check for <code class=\"calibre9\">null<\/code>. Visual Studio 2022 will warn you the opposite, which is why I put in the <code class=\"calibre9\">null<\/code> check. Unfortunately, it is a common programmer error to pass an object for the model that is <code class=\"calibre9\">null<\/code>.<\/li>\n<li class=\"calibre3\">It is easy to mix static HTML elements such as <code class=\"calibre9\">&lt;ul&gt;<\/code> and <code class=\"calibre9\">&lt;li&gt;<\/code> with C# code to output the carousel of categories and the list of product names.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">&lt;div&gt;<\/code> element with the <code class=\"calibre9\">id<\/code> attribute of <code class=\"calibre9\">product-columns<\/code> will use the custom style that we defined earlier, so all the content in that element will display in three columns.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">&lt;img&gt;<\/code> element for each category uses parentheses around a Razor expression to ensure that the compiler does not include the <code class=\"calibre9\">.jpeg<\/code> as part of the expression, as shown in the following markup: <code class=\"calibre9\">\"~\/images\/cs12\/category@(Model.Categories.CategoryID).jpeg\"<\/code>.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">&lt;a&gt;<\/code> elements for the product links use tag helpers to generate URL paths. Clicks on these hyperlinks will be handled by the <code class=\"calibre9\">HomeController<\/code> and its <code class=\"calibre9\">ProductDetail<\/code> action method. This action method does not exist yet, but you will add it later in this chapter. The ID of the product is passed as a route segment named <code class=\"calibre9\">id<\/code>, as shown in the following URL path for Ipoh Coffee: <code class=\"calibre9\">https:\/\/localhost:5141\/Home\/ProductDetail\/43<\/code>.<\/li>\n<\/ul>\n<p class=\"rights\">Let's see the result of our customized home page:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Note the home page has a rotating carousel showing categories, a random number of visitors, and a list of products in three columns, as shown in <em class=\"calibre10\">Figure 14.4<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 14.4: The updated Northwind MVC website home page\" height=\"761\" src=\"\/images\/cs12\/000170.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 14.4: The updated Northwind MVC website home page<\/figcaption><\/figure>\n<p class=\"rights\">For now, clicking on any of the categories or product links gives <strong class=\"calibre2\">404 Not Found<\/strong> errors, so let's see how we can implement pages that use the parameters passed to them to see the details of a product or category.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"15.4.5\" id=\"calibre_link-764\">\n<h3 data-number=\"15.4.5\" class=\"calibre8\">Passing parameters using a route value<\/h3>\n<p class=\"rights\">One way to pass a simple parameter is to use the <code class=\"calibre9\">id<\/code> segment defined in the default route:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">HomeController<\/code>, import the namespace for calling the <code class=\"calibre9\">Include<\/code> extension method so that we can get related entities, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.EntityFrameworkCore; \/\/ To use Include method.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Add an action method named <code class=\"calibre9\">ProductDetail<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public IActionResult ProductDetail(int? id)\n{\n  if (!id.HasValue)\n  {\n    return BadRequest(\"You must pass a product ID in the route, for example, \/Home\/ProductDetail\/21\");\n  }\n  Product? model = _db.Products.Include(p =&gt; p.Category)\n    .SingleOrDefault(p =&gt; p.ProductId == id);\n  if (model is null)\n  {\n    return NotFound($\"ProductId {id} not found.\");\n  }\n  return View(model); \/\/ Pass model to view and then return result.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">This method uses a feature of ASP.NET Core called <strong class=\"calibre2\">model binding<\/strong> to automatically match the <code class=\"calibre9\">id<\/code> passed in the route to the parameter named <code class=\"calibre9\">id<\/code> in the method.<\/li>\n<li class=\"calibre3\">Inside the method, we check to see whether <code class=\"calibre9\">id<\/code> does not have a value, and if so, we call the <code class=\"calibre9\">BadRequest<\/code> method to return a <code class=\"calibre9\">400<\/code> status code with a custom message explaining the correct URL path format.<\/li>\n<li class=\"calibre3\">Otherwise, we can connect to the database and try to retrieve a product using the <code class=\"calibre9\">id<\/code> value and include the related category information so we can see its name.<\/li>\n<li class=\"calibre3\">If we find a product, we pass it to a view; otherwise, we call the <code class=\"calibre9\">NotFound<\/code> method to return a <code class=\"calibre9\">404<\/code> status code and a custom message explaining that a product with that ID was not found in the database.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">In the <code class=\"calibre9\">Views\/Home<\/code> folder, add a new Razor View file named <code class=\"calibre9\">ProductDetail.cshtml<\/code>. (In Visual Studio, the item template is named <strong class=\"calibre2\">Razor View - Empty<\/strong>. In Visual Studio Code, at the command prompt or terminal, enter <code class=\"calibre9\">dotnet new view -n ProductDetail<\/code>.)<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Be careful not to add a Razor Page. If you do, then the file will have an <code class=\"calibre9\">@page<\/code> directive at the top, which will prevent the model from being passed from the controller to the view and you will get a <code class=\"calibre9\">NullReferenceException<\/code>!<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Modify the contents, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@model Northwind.EntityModels.Product \n@{\n  ViewData[\"Title\"] = $\"Product Detail - {Model.ProductName}\";\n}\n&lt;h2&gt;Product Detail&lt;\/h2&gt;\n&lt;hr \/&gt;\n&lt;div&gt;\n  &lt;dl class=\"dl-horizontal\"&gt;\n    &lt;dt&gt;Product Id&lt;\/dt&gt;\n    &lt;dd&gt;@Model.ProductId&lt;\/dd&gt;\n    &lt;dt&gt;Product Name&lt;\/dt&gt;\n    &lt;dd&gt;@Model.ProductName&lt;\/dd&gt;\n    &lt;dt&gt;Category&lt;\/dt&gt;\n    &lt;dd&gt;@Model.CategoryId - @Model.Category?.CategoryName&lt;\/dd&gt;\n    &lt;dt&gt;Unit Price&lt;\/dt&gt;\n    &lt;dd&gt;@(Model.UnitPrice is null ? \"zero\" : \n          Model.UnitPrice.Value.ToString(\"C\"))&lt;\/dd&gt;\n    &lt;dt&gt;Units In Stock&lt;\/dt&gt;\n    &lt;dd&gt;@Model.UnitsInStock&lt;\/dd&gt;\n  &lt;\/dl&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">When the home page appears with the list of products, click on one of them, for example, the second product, <strong class=\"calibre2\">Chang<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Note the URL path in the browser's address bar, the page title shown in the browser tab, and the product details page, as shown in <em class=\"calibre10\">Figure 14.5<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 14.5: The product details page for Schoggi Schokolade\" height=\"523\" src=\"\/images\/cs12\/000082.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 14.5: The product details page for Schoggi Schokolade<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">View <strong class=\"calibre2\">Developer Tools<\/strong>.<\/li>\n<li class=\"calibre3\">Edit the URL in the address box of Chrome to request a product ID that does not exist, like 99, and note the <strong class=\"calibre2\">404 Not Found<\/strong> status code and custom error response.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"15.4.6\" id=\"calibre_link-765\">\n<h3 data-number=\"15.4.6\" class=\"calibre8\">Disambiguating action methods<\/h3>\n<p class=\"rights\">Although the C# compiler can differentiate between the two methods by noting that the signatures are different, from the point of view of routing an HTTP request, both methods are potential matches. We need an HTTP-specific way to disambiguate the action methods.We could do this by creating different names for the actions or by specifying that one method should be used for a specific HTTP verb, like <code class=\"calibre9\">GET<\/code>, <code class=\"calibre9\">POST<\/code>, or <code class=\"calibre9\">DELETE<\/code>. You do this by decorating the action method with one of the following attributes: <code class=\"calibre9\">[HttpPost]<\/code>, <code class=\"calibre9\">[HttpPut]<\/code>, and so on.<\/p>\n<\/section>\n<section data-number=\"15.4.7\" id=\"calibre_link-766\">\n<h3 data-number=\"15.4.7\" class=\"calibre8\">Model binders in detail<\/h3>\n<p class=\"rights\">Model binders are a powerful yet easy way to set parameters of action methods based on values passed in an HTTP request, and the default one does a lot for you. After the default route identifies a controller class to instantiate and an action method to call, if that method has parameters, then those parameters need to have values set.Model binders do this by looking for parameter values passed in the HTTP request as any of the following types of parameters:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Route parameter<\/strong>, like <code class=\"calibre9\">id<\/code> as we used in the previous section, as shown in the following URL path: <code class=\"calibre9\">\/Home\/ProductDetail\/2<\/code><\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Query string parameter<\/strong>, as shown in the following URL path: <code class=\"calibre9\">\/Home\/ProductDetail?id=2<\/code><\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Form parameter<\/strong>, as shown in the following markup:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;form action=\"post\" action=\"\/Home\/ProductDetail\"&gt;\n  &lt;input type=\"text\" name=\"id\" value=\"2\" \/&gt;\n  &lt;input type=\"submit\" \/&gt;\n&lt;\/form&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Model binders can populate almost any type:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Simple types, like <code class=\"calibre9\">int<\/code>, <code class=\"calibre9\">string<\/code>, <code class=\"calibre9\">DateTime<\/code>, and <code class=\"calibre9\">bool<\/code><\/li>\n<li class=\"calibre3\">Complex types defined by <code class=\"calibre9\">class<\/code>, <code class=\"calibre9\">record<\/code>, or <code class=\"calibre9\">struct<\/code><\/li>\n<li class=\"calibre3\">Collection types, like arrays and lists<\/li>\n<\/ul>\n<p class=\"rights\">The process of model binding can cause errors, for example, data type conversions or validation errors if the model has been decorated with validation rules. What data has been bound and any binding or validation errors are stored in <code class=\"calibre9\">ControllerBase.ModelState<\/code>.Let's create a somewhat artificial example to illustrate what can be achieved using the default model binder and what we can do with the model state by applying some validation rules to the bound model and showing invalid data messages in the view:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Models<\/code> folder, add a new file named <code class=\"calibre9\">Thing.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify the contents to define a record with three properties; a nullable integer named <code class=\"calibre9\">Id<\/code>, a <code class=\"calibre9\">string<\/code> named <code class=\"calibre9\">Color<\/code>, and a <code class=\"calibre9\">string<\/code> named <code class=\"calibre9\">Email<\/code>, each with appropriate validation attributes, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ To use [Range], [Required], [EmailAddress].\nusing System.ComponentModel.DataAnnotations;\nnamespace Northwind.Mvc.Models;\npublic record Thing(\n  [Range(1, 10)] int? Id, \n  [Required] string? Color,\n  [EmailAddress] string? Email\n);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Models<\/code> folder, add a new class file named <code class=\"calibre9\">HomeModelBindingViewModel.cs<\/code>.<\/li>\n<li class=\"calibre3\">Modify its contents to define a record with properties to store the bound model, a flag to indicate that there are errors, and a sequence of error messages, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace Northwind.Mvc.Models;\npublic record HomeModelBindingViewModel(Thing Thing, bool HasErrors, \n  IEnumerable&lt;string&gt; ValidationErrors);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">HomeController<\/code>, add two new action methods, one to show a page with a form and one to display a <code class=\"calibre9\">thing <\/code>with a parameter using your new model type, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ This action method will handle GET and other requests except POST.\npublic IActionResult ModelBinding()\n{\n  return View(); \/\/ The page with a form to submit.\n}\n[HttpPost] \/\/ This action method will handle POST requests.\npublic IActionResult ModelBinding(Thing thing)\n{\n  HomeModelBindingViewModel model = new(\n    Thing: thing, HasErrors: !ModelState.IsValid, \n    ValidationErrors: ModelState.Values\n      .SelectMany(state =&gt; state.Errors)\n      .Select(error =&gt; error.ErrorMessage)\n  );\n  return View(model); \/\/ Show the model bound thing.\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The first <code class=\"calibre9\">ModelBinding<\/code> action method will implicitly be used for all other types of HTTP requests, like <code class=\"calibre9\">GET<\/code>, <code class=\"calibre9\">PUT<\/code>, <code class=\"calibre9\">DELETE<\/code>, and so on, because the second <code class=\"calibre9\">ModelBinding<\/code> action method is decorated with <code class=\"calibre9\">[HttpPost]<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Views\\Home<\/code> folder, add a new file named <code class=\"calibre9\">ModelBinding.cshtml<\/code>.<\/li>\n<li class=\"calibre3\">Modify its contents, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@model HomeModelBindingViewModel \n@{\n  ViewData[\"Title\"] = \"Model Binding Demo\";\n}\n&lt;h1&gt;@ViewData[\"Title\"]&lt;\/h1&gt;\n&lt;div&gt;\n  Enter values for your thing in the following form:\n&lt;\/div&gt;\n&lt;form method=\"POST\" action=\"\/home\/modelbinding?id=3\"&gt;\n  &lt;input name=\"color\" value=\"Red\" \/&gt;\n  &lt;input name=\"email\" value=\"test@example.com\" \/&gt;\n  &lt;input type=\"submit\" \/&gt;\n&lt;\/form&gt;\n@if (Model is not null)\n{\n&lt;h2&gt;Submitted Thing&lt;\/h2&gt;\n&lt;hr \/&gt;\n&lt;div&gt;\n  &lt;dl class=\"dl-horizontal\"&gt;\n    &lt;dt&gt;Model.Thing.Id&lt;\/dt&gt;\n    &lt;dd&gt;@Model.Thing.Id&lt;\/dd&gt;\n    &lt;dt&gt;Model.Thing.Color&lt;\/dt&gt;\n    &lt;dd&gt;@Model.Thing.Color&lt;\/dd&gt;\n    &lt;dt&gt;Model.Thing.Email&lt;\/dt&gt;\n    &lt;dd&gt;@Model.Thing.Email&lt;\/dd&gt;\n  &lt;\/dl&gt;\n&lt;\/div&gt;\n  @if (Model.HasErrors)\n  {\n  &lt;div&gt;\n    @foreach(string errorMessage in Model.ValidationErrors)\n    {\n      &lt;div class=\"alert alert-danger\" role=\"alert\"&gt;@errorMessage&lt;\/div&gt;\n    }\n  &lt;\/div&gt;\n  }\n}\n@section Scripts {\n  &lt;partial name=\"_ValidationScriptsPartial\" \/&gt;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Views\/Home<\/code>, in <code class=\"calibre9\">Index.cshtml<\/code>, in the first <code class=\"calibre9\">&lt;div&gt;<\/code>, after rendering the heading, add a new paragraph with a link to the model binding page, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;p&gt;&lt;a asp-action=\"ModelBinding\" asp-controller=\"Home\"&gt;Binding&lt;\/a&gt;&lt;\/p&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">On the home page, click <strong class=\"calibre2\">Binding<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Click the <strong class=\"calibre2\">Submit<\/strong> button and note the value for the <code class=\"calibre9\">Id<\/code> property is set from the query string parameter in the <code class=\"calibre9\">action<\/code> of the form, and the values for the color and email properties are set from the form elements, as shown in <em class=\"calibre10\">Figure 14.6<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 14.6: The Model Binding Demo page\" height=\"691\" src=\"\/images\/cs12\/000065.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 14.6: The Model Binding Demo page<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"15.4.8\" id=\"calibre_link-767\">\n<h3 data-number=\"15.4.8\" class=\"calibre8\">Passing a route parameter<\/h3>\n<p class=\"rights\">Now we will set the property using a route parameter:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Views\\Home<\/code> folder, in <code class=\"calibre9\">ModelBinding.cshtml<\/code>, modify the action for the form to pass the value <code class=\"calibre9\">2<\/code> as an MVC route parameter, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;form method=\"POST\" action=\"\/home\/modelbinding\/2?id=3\"&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">On the home page, click <strong class=\"calibre2\">Binding<\/strong>.<\/li>\n<li class=\"calibre3\">Click the <strong class=\"calibre2\">Submit<\/strong> button and note the value for the <code class=\"calibre9\">Id<\/code> property is set from the route parameter.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"15.4.9\" id=\"calibre_link-768\">\n<h3 data-number=\"15.4.9\" class=\"calibre8\">Passing a form parameter<\/h3>\n<p class=\"rights\">Now we will set the property using a form parameter:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Views\\Home<\/code> folder, in <code class=\"calibre9\">ModelBinding.cshtml<\/code>, modify the action for the form to pass the value 1 as a form element parameter, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;form method=\"POST\" action=\"\/home\/modelbinding\/2?id=3\"&gt;\n  &lt;input name=\"id\" value=\"1\" \/&gt;\n  &lt;input name=\"color\" value=\"Red\" \/&gt;\n  &lt;input type=\"submit\" \/&gt;\n&lt;\/form&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">On the home page, click <strong class=\"calibre2\">Binding<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Click the <strong class=\"calibre2\">Submit<\/strong> button and note the values for all the properties are both set from the form element parameters.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: If you have multiple parameters with the same name, then remember that form parameters have the highest priority and query string parameters have the lowest priority for automatic model binding.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Enter an <code class=\"calibre9\">Id<\/code> of <code class=\"calibre9\">13<\/code>, clear the color textbox, delete the <code class=\"calibre9\">@<\/code> from the email address, click the <strong class=\"calibre2\">Submit<\/strong> button, and note the error messages, as shown in <em class=\"calibre10\">Figure 14.7<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 14.7: The Model Binding Demo page with field validations\" height=\"629\" src=\"\/images\/cs12\/000115.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 14.7: The Model Binding Demo page with field validations<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: What regular expression does Microsoft use for the implementation of the <code class=\"calibre9\">EmailAddress<\/code> validation attribute? Find out at the following link: <a href=\"https:\/\/github.com\/microsoft\/referencesource\/blob\/5697c29004a34d80acdaf5742d7e699022c64ecd\/System.ComponentModel.DataAnnotations\/DataAnnotations\/EmailAddressAttribute.cs#L54\">https:\/\/github.com\/microsoft\/referencesource\/blob\/5697c29004a34d80acdaf5742d7e699022c64ecd\/System.ComponentModel.DataAnnotations\/DataAnnotations\/EmailAddressAttribute.cs#L54<\/a><\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"15.4.10\" id=\"calibre_link-769\">\n<h3 data-number=\"15.4.10\" class=\"calibre8\">Defining views with HTML Helper methods<\/h3>\n<p class=\"rights\">While creating a view for ASP.NET Core MVC, you can use the <code class=\"calibre9\">Html<\/code> object and its methods to generate markup. When Microsoft first introduced ASP.NET MVC in 2009, these HTML Helper methods were the way to programmatically render HTML. Modern ASP.NET Core retains these HTML Helper methods for backward compatibility and provides Tag Helpers that are usually easier to read and write in most scenarios. But there are notable situations where Tag Helpers cannot be used, like in Razor components.Some useful methods include the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">ActionLink<\/code>: Use this to generate an anchor <code class=\"calibre9\">&lt;a&gt;<\/code> element that contains a URL path to the specified controller and action. For example, <code class=\"calibre9\">Html.ActionLink(linkText: \"Binding\", actionName: \"ModelBinding\", controllerName: \"Home\")<\/code> would generate <code class=\"calibre9\">&lt;a href=\"\/home\/modelbinding\"&gt;Binding&lt;\/a&gt;<\/code>. You can achieve the same result using the anchor tag helper <code class=\"calibre9\">&lt;a asp-action=\"ModelBinding\" asp-controller=\"Home\"&gt;Binding&lt;\/a&gt;<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">AntiForgeryToken<\/code>: Use this inside a <code class=\"calibre9\">&lt;form&gt;<\/code> to insert a <code class=\"calibre9\">&lt;hidden&gt;<\/code> element containing an anti-forgery token that will be validated when the form is submitted.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Display<\/code> and <code class=\"calibre9\">DisplayFor<\/code>: Use this to generate HTML markup for the expression relative to the current model using a display template. There are built-in display templates for .NET types and custom templates can be created in the <code class=\"calibre9\">DisplayTemplates<\/code> folder. The folder name is case-sensitive on case-sensitive filesystems.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">DisplayForModel<\/code>: Use this to generate HTML markup for an entire model instead of a single expression.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Editor<\/code> and <code class=\"calibre9\">EditorFor<\/code>: Use this to generate HTML markup for the expression relative to the current model using an editor template. There are built-in editor templates for .NET types that use <code class=\"calibre9\">&lt;label&gt;<\/code> and <code class=\"calibre9\">&lt;input&gt;<\/code> elements, and custom templates can be created in the <code class=\"calibre9\">EditorTemplates<\/code> folder. The folder name is case-sensitive on case-sensitive filesystems.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">EditorForModel<\/code>: Use this to generate HTML markup for an entire model instead of a single expression.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Encode<\/code>: Use this to safely encode an object or string into HTML. For example, the string value <code class=\"calibre9\">\"&lt;script&gt;\"<\/code> would be encoded as <code class=\"calibre9\">\"&lt;script&gt;\"<\/code>. This is not normally necessary since the Razor <code class=\"calibre9\">@<\/code> symbol encodes string values by default.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Raw<\/code>: Use this to render a string value <em class=\"calibre10\">without<\/em> encoding as HTML.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">PartialAsync<\/code> and <code class=\"calibre9\">RenderPartialAsync<\/code>: Use these to generate HTML markup for a partial view. You can optionally pass a model and view data.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"15.4.11\" id=\"calibre_link-770\">\n<h3 data-number=\"15.4.11\" class=\"calibre8\">Defining views with Tag Helpers<\/h3>\n<p class=\"rights\">Tag Helpers make it easier to make static HTML elements dynamic. The markup is cleaner and easier to read, edit, and maintain than if you use HTML Helpers. However, Tag Helpers do not replace HTML Helpers because there are some things that can only be achieved with HTML Helpers, like rendering output that contains multiple nested tags. Tag Helpers also cannot be used in Razor components. So, you must learn how to use HTML Helpers and treat Tag Helpers as an optional choice that is better in some scenarios.Tag Helpers are especially useful for <strong class=\"calibre2\">Front End<\/strong> (<strong class=\"calibre2\">FE<\/strong>) developers who primarily work with HTML, CSS, and JavaScript because the FE developer does not have to learn C# syntax. Tag Helpers just use what look like normal HTML attributes on elements. The attribute names and values can also be selected from IntelliSense if your code editor supports that; both Visual Studio 2022 and Visual Studio Code do.For example, to render a linkable hyperlink to a controller action, you could use an HTML Helper method, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@Html.ActionLink(\"View our privacy policy.\", \"Privacy\", \"Index\")<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To make it clearer how it works, you could use named parameters:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@Html.ActionLink(linkText: \"View our privacy policy.\", \n  action: \"Privacy\", controller: \"Index\")<\/code><\/pre>\n<\/div>\n<p class=\"rights\">But using a Tag Helper would be even clearer and cleaner for someone who works a lot with HTML:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;a asp-action=\"Privacy\" asp-controller=\"Home\"&gt;View our privacy policy.&lt;\/a&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">All three examples above generate the following rendered HTML element:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;a href=\"\/home\/privacy\"&gt;View our privacy policy.&lt;\/a&gt;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"15.4.12\" id=\"calibre_link-771\">\n<h3 data-number=\"15.4.12\" class=\"calibre8\">Cross-functional filters<\/h3>\n<p class=\"rights\">When you need to add some functionality to multiple controllers and actions, you can use or define your own filters that are implemented as an attribute class.Filters can be applied at the following levels:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">At the action level, by decorating an action method with the attribute. This will only affect that one action method.<\/li>\n<li class=\"calibre3\">At the controller level, by decorating the controller class with the attribute. This will affect all methods of the controller.<\/li>\n<li class=\"calibre3\">At the global level, by adding the attribute type to the <code class=\"calibre9\">Filters<\/code> collection of the <code class=\"calibre9\">MvcOptions<\/code> instance, which can be used to configure MVC when calling the <code class=\"calibre9\">AddControllersWithViews<\/code> method, as shown in the following code:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddControllersWithViews(options =&gt;\n  {\n    options.Filters.Add(typeof(MyCustomFilter));\n  });<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"15.4.13\" id=\"calibre_link-772\">\n<h3 data-number=\"15.4.13\" class=\"calibre8\">Using a filter to define a custom route<\/h3>\n<p class=\"rights\">You might want to define a simplified route for an action method instead of using the default route.For example, showing the privacy page currently requires the following URL path, which specifies both the controller and action:<code class=\"calibre9\">https:\/\/localhost:5141\/home\/privacy<\/code>We could make the route simpler, as shown in the following link:<code class=\"calibre9\">https:\/\/localhost:5141\/private<\/code>Let's see how to do that:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">HomeController.cs<\/code>, add an attribute to the <code class=\"calibre9\">Privacy<\/code> method to define a simplified route, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[Route(\"private\")]\npublic IActionResult Privacy()<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">In the address bar, enter the following URL path, and note that the simplified path shows the <strong class=\"calibre2\">Privacy<\/strong> page:<\/li>\n<\/ol>\n<p class=\"rights\"><code class=\"calibre9\">https:\/\/localhost:5141\/private<\/code><\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<\/section>\n<section data-number=\"15.5\" id=\"calibre_link-773\">\n<h2 data-number=\"15.5\" class=\"calibre5\">Improving performance and scalability using caching<\/h2>\n<p class=\"rights\"><em class=\"calibre10\">Figure 14.8<\/em> is a summary diagram of types and locations of caching:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 14.8: Types and locations for caching\" height=\"1366\" src=\"\/images\/cs12\/000108.png\" width=\"2350\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 14.8: Types and locations for caching<\/figcaption><\/figure>\n<p class=\"rights\">Let's review a scenario. The numbered bullets match the numbered labels in <em class=\"calibre10\">Figure 14.8<\/em>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">A web browser requests the product detail page for the product with an ID of 34.<\/li>\n<li class=\"calibre3\">On the web server, the output caching system looks in the output cache to see if that web page already exists with a match on its route. If not, the request is mapped to the appropriate controller action method and the <code class=\"calibre9\">id <\/code>value <code class=\"calibre9\">34 <\/code>is passed in.<\/li>\n<li class=\"calibre3\">The action method implementation looks in the object cache to see if that entity already exists.<\/li>\n<li class=\"calibre3\">If not, it is retrieved from the database and stored in the object cache. Using an object cache is covered in <em class=\"calibre10\">Chapter 15<\/em>, <em class=\"calibre10\">Building and Consuming Web Services<\/em>.<\/li>\n<li class=\"calibre3\">The action method passes the product entity to the appropriate Razor view, which renders it into an HTML page and stores it in the output cache.<\/li>\n<li class=\"calibre3\">The action method adds response caching headers to the response before returning it.<\/li>\n<li class=\"calibre3\">Any intermediaries as well as the web browser can read the HTTP response headers and cache it if allowed.<\/li>\n<\/ol>\n<p class=\"rights\">On the next request, caching at various levels could improve matters:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">The web browser might have the page in its local cache due to response caching. No further action is required. If not, a request is made to the web server. If intermediaries like a content delivery network (CDN) were allowed to cache the response, then they could return it to the browser without needing to forward the request to the web server.<\/li>\n<li class=\"calibre3\">If a request arrives at the web server, and the page is in the output cache, the action method processing can be bypassed, and, 6. the page is immediately returned with new response headers set.<\/li>\n<\/ol>\n<section data-number=\"15.5.1\" id=\"calibre_link-774\">\n<h3 data-number=\"15.5.1\" class=\"calibre8\">Caching HTTP responses<\/h3>\n<p class=\"rights\">To improve response times and scalability, you might want to try to cache the HTTP response that is generated by an action method by decorating the method with the <code class=\"calibre9\">[ResponseCache]<\/code> attribute. This tells intermediaries like CDNs and the web browser itself how long they should cache the response for by adding HTTP headers to the response.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Response caching is only advisory. You cannot force other systems to cache if you do not control them. Keep in mind that any response caching you configure could be ignored.<\/p>\n<\/blockquote>\n<p class=\"rights\">You indicate where the response should be cached and for how long by setting parameters in the <code class=\"calibre9\">[ResponseCache]<\/code> attribute, as shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Duration<\/code>: In seconds. This sets the <code class=\"calibre9\">max-age<\/code> HTTP response header measured in seconds. Common choices are one hour (3,600 seconds) and one day (86,400 seconds).<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Location<\/code>: One of the <code class=\"calibre9\">ResponseCacheLocation<\/code> values, <code class=\"calibre9\">Any<\/code>, <code class=\"calibre9\">Client<\/code>, or <code class=\"calibre9\">None<\/code>. This sets the <code class=\"calibre9\">cache-control<\/code> HTTP response header.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">NoStore<\/code>: If <code class=\"calibre9\">true<\/code>, this ignores <code class=\"calibre9\">Duration<\/code> and <code class=\"calibre9\">Location<\/code> and sets the cache-control HTTP response header to <code class=\"calibre9\">no-store<\/code>.<\/li>\n<\/ul>\n<p class=\"rights\">Let's see an example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">HomeController.cs<\/code>, add an attribute to the <code class=\"calibre9\">Index<\/code> method to cache the response for 10 seconds on the browser or any proxies between the server and browser, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[ResponseCache(Duration = 10 \/* seconds *\/,\n  Location = ResponseCacheLocation.Any)]\npublic IActionResult Index()<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Views<\/code>, in <code class=\"calibre9\">Home<\/code>, open <code class=\"calibre9\">Index.cshtml<\/code>, and after the <strong class=\"calibre2\">Welcome<\/strong> heading, add a paragraph to output the current time in long format to include seconds, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;p class=\"alert alert-primary\"&gt;@DateTime.Now.ToLongTimeString()&lt;\/p&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Note the time on the home page.<\/li>\n<li class=\"calibre3\">View <strong class=\"calibre2\">Developer Tools<\/strong>, select the <strong class=\"calibre2\">Network<\/strong> tab, select the <strong class=\"calibre2\">localhost<\/strong> request, refresh the page, and note the <code class=\"calibre9\">Cache-Control<\/code> response header, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Cache-Control: public,max-age=10<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Click <strong class=\"calibre2\">Register<\/strong> so that you leave the home page.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Do <em class=\"calibre10\">not<\/em> click the <strong class=\"calibre2\">Reload the page<\/strong> button as this will override the cache and refresh the page with a new request to the web server.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Home<\/strong> and note the time on the home page is the same because a cached version of the page is used.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Register<\/strong>. Wait at least 10 seconds.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Home<\/strong> and note the time has now updated.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Log in<\/strong>, enter your email and password, and then click <strong class=\"calibre2\">Log in<\/strong>.<\/li>\n<li class=\"calibre3\">Note the time on the home page.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Privacy<\/strong>.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Home<\/strong> and note the page is not cached.<\/li>\n<li class=\"calibre3\">View the console and note the warning message explaining that your caching has been overridden because the visitor is logged in and, in this scenario, ASP.NET Core uses anti-forgery tokens and they should not be cached, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">warn: Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery[8]\n      The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache, no-store' and 'no-cache' respectively to prevent caching of this response. Any response that uses antiforgery should not be cached.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"15.5.2\" id=\"calibre_link-775\">\n<h3 data-number=\"15.5.2\" class=\"calibre8\">Output caching endpoints<\/h3>\n<p class=\"rights\">Output caching stores dynamically generated responses on the server so that they do not have to be regenerated again for another request. This can improve performance.Let's see it in action with examples of applying output caching to some endpoints:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Mvc<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, add statements after the call to <code class=\"calibre9\">AddNorthwindContext<\/code> to add the output cache middleware and override the default expiration timespan to make it only 10 seconds, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddNorthwindContext();\nbuilder.Services.AddOutputCache(options =&gt;\n{\n  options.DefaultExpirationTimeSpan = TimeSpan.FromSeconds(10);\n});<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: The default expiration timespan is one minute. Think carefully about what the duration should be based on your website's typical visitor behavior.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements before the call to map controllers to use the output cache, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.UseOutputCache();\napp.MapControllerRoute(\n    name: \u201cdefault\u201d,\n    pattern: \u201c{controller=Home}\/{action=Index}\/{id?}\u201d);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add statements after the call to map Razor Pages to create two endpoints that respond with plain text, one that is not cached and one that uses the output cache, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.MapRazorPages();\napp.MapGet(\u201c\/notcached\u201d, () =&gt; DateTime.Now.ToString());\napp.MapGet(\u201c\/cached\u201d, () =&gt; DateTime.Now.ToString()).CacheOutput();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">appsettings.Development.json<\/code>, add a log level of <code class=\"calibre9\">Information<\/code> for the output caching middleware, as shown highlighted in the following configuration:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \u201cLogging\u201d: {\n    \u201cLogLevel\u201d: {\n      \u201cDefault\u201d: \u201cInformation\u201d,\n      \u201cMicrosoft.AspNetCore\u201d: \u201cWarning\u201d,\n      \u201cMicrosoft.AspNetCore.OutputCaching\u201d: \u201cInformation\u201d\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Arrange the browser and command prompt or terminal window so that you can see both.<\/li>\n<li class=\"calibre3\">In the browser, make sure that you are not logged in to the MVC website because that would disable caching, then navigate to <a href=\"https:\/\/localhost:5141\/notcached\">https:\/\/localhost:5141\/notcached<\/a>, and note nothing is written to the command prompt or terminal.<\/li>\n<li class=\"calibre3\">In the browser, click the <strong class=\"calibre2\">Refresh<\/strong> button several times and note that the time is always updated because it is not served from the output cache.<\/li>\n<li class=\"calibre3\">In the browser, navigate to <code class=\"calibre9\">https:\/\/localhost:5141\/cached<\/code>, and note that messages are written to the console or terminal to tell you that you have made a request for a cached resource, but it does not have anything in the output cache, so it has now cached the output, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">info: Microsoft.AspNetCore.OutputCaching.OutputCacheMiddleware[7]\n      No cached response available for this request.\ninfo: Microsoft.AspNetCore.OutputCaching.OutputCacheMiddleware[9]\n      The response has been cached.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the browser, click the <strong class=\"calibre2\">Refresh<\/strong> button several times and note that the time is not updated, and an output caching message tells you that the value was served from the cache, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">info: Microsoft.AspNetCore.OutputCaching.OutputCacheMiddleware[5]\n      Serving response from cache.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Continue refreshing until 10 seconds have passed and note that messages are written to the command prompt or terminal to tell you that the cached output has been updated.<\/li>\n<li class=\"calibre3\">Close the browser and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"15.5.3\" id=\"calibre_link-776\">\n<h3 data-number=\"15.5.3\" class=\"calibre8\">Output caching MVC views<\/h3>\n<p class=\"rights\">Now let's see how we can output cache an MVC view:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Views\\Home<\/code> folder, in <code class=\"calibre9\">ProductDetail.cshtml<\/code>, add a paragraph <code class=\"calibre9\">&lt;p&gt;<\/code> to show the current time, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;h2&gt;Product Detail&lt;\/h2&gt;\n&lt;p class=\"alert alert-success\"&gt;@DateTime.Now.ToLongTimeString()&lt;\/p&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Arrange the browser and command prompt or terminal window so that you can see both.<\/li>\n<li class=\"calibre3\">On the home page, scroll down and then select one of the products.<\/li>\n<li class=\"calibre3\">On the product detail page, note the current time, and then refresh the page and note that the time updates every second.<\/li>\n<li class=\"calibre3\">Close the browser and shut down the web server.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, at the end of the call to map controllers, add a call to the <code class=\"calibre9\">CacheOutput<\/code> method, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.MapControllerRoute(\n    name: \"default\",\n    pattern: \"{controller=Home}\/{action=Index}\/{id?}\")\n  .CacheOutput();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile and arrange the browser window and command prompt or terminal window so that you can see both.<\/li>\n<li class=\"calibre3\">On the home page, scroll down, select one of the products, and note that the product detail page is not in the output cache, so SQL commands are executed to get the data. Then, once the Razor view generates the page, it is stored in the cache, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">info: Microsoft.AspNetCore.OutputCaching.OutputCacheMiddleware[7]\n      No cached response available for this request.\ndbug: 20\/09\/2022 17:23:02.402 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)\n      Executing DbCommand [Parameters=[@__id_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"QuantityPerUnit\", \"p\".\"ReorderLevel\", \"p\".\"SupplierId\", \"p\".\"UnitPrice\", \"p\".\"UnitsInStock\", \"p\".\"UnitsOnOrder\", \"c\".\"CategoryId\", \"c\".\"CategoryName\", \"c\".\"Description\", \"c\".\"Picture\"\n      FROM \"Products\" AS \"p\"\n      LEFT JOIN \"Categories\" AS \"c\" ON \"p\".\"CategoryId\" = \"c\".\"CategoryId\"\n      WHERE \"p\".\"ProductId\" = @__id_0\n      LIMIT 2\ninfo: Microsoft.EntityFrameworkCore.Database.Command[20101]\n      Executed DbCommand (7ms) [Parameters=[@__id_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']\n      SELECT \"p\".\"ProductId\", \"p\".\"CategoryId\", \"p\".\"Discontinued\", \"p\".\"ProductName\", \"p\".\"QuantityPerUnit\", \"p\".\"ReorderLevel\", \"p\".\"SupplierId\", \"p\".\"UnitPrice\", \"p\".\"UnitsInStock\", \"p\".\"UnitsOnOrder\", \"c\".\"CategoryId\", \"c\".\"CategoryName\", \"c\".\"Description\", \"c\".\"Picture\"\n      FROM \"Products\" AS \"p\"\n      LEFT JOIN \"Categories\" AS \"c\" ON \"p\".\"CategoryId\" = \"c\".\"CategoryId\"\n      WHERE \"p\".\"ProductId\" = @__id_0\n      LIMIT 2\ninfo: Microsoft.AspNetCore.OutputCaching.OutputCacheMiddleware[9]\n      The response has been cached.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">On the product detail page, note the current time, and then refresh the page and note that the whole page, including the time and product detail data, is served from the output cache, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">info: Microsoft.AspNetCore.OutputCaching.OutputCacheMiddleware[5]\n      Serving response from cache.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Keep refreshing until 10 seconds have passed and note that the page is then regenerated from the database and the current time is shown.<\/li>\n<li class=\"calibre3\">In the browser address bar, change the product ID number to a value between 1 and 77 to request a different product, and note that the time is current, and therefore a new cached version has been created for that product ID, because the ID is part of the relative path.<\/li>\n<li class=\"calibre3\">Refresh the browser and note the time is cached (and therefore the whole page is).<\/li>\n<li class=\"calibre3\">In the browser address bar, change the product ID number to a value between 1 and 77 to request a different product, and note that the time is current, and therefore a new cached version has been created for that product ID, because the ID is part of the relative path.<\/li>\n<li class=\"calibre3\">In the browser address bar, change the product ID number back to the previous ID and note the page is still cached with the time that the previous page was first added to the output cache.<\/li>\n<li class=\"calibre3\">Close the browser and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"15.5.4\" id=\"calibre_link-777\">\n<h3 data-number=\"15.5.4\" class=\"calibre8\">Varying cached data by query string<\/h3>\n<p class=\"rights\">If a value is different in the relative path, then output caching automatically treats the request as a different resource and so caches different copies for each, including differences in any query string parameters. Consider the following URLs:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">https:\/\/localhost:5141\/Home\/ProductDetail\/12<\/code><\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">https:\/\/localhost:5141\/Home\/ProductDetail\/29<\/code><\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">https:\/\/localhost:5141\/Home\/ProductDetail\/12?color=red<\/code><\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">https:\/\/localhost:5141\/Home\/ProductDetail\/12?color=blue<\/code><\/li>\n<\/ul>\n<p class=\"rights\">All four requests will have their own cached copy of their own page. If the query string parameters have no effect on the generated page, then that is a waste.Let's see how we can fix this problem. We will start by disabling varying the cache by query string parameter values, and then implement some page functionality that uses a query string parameter:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, in the call to <code class=\"calibre9\">AddOutputCache<\/code>, increase the default expiration to 20 seconds (or set a larger value to give yourself more time later) and add a statement to define a named policy to disable varying by query string parameters, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddOutputCache(options =&gt;\n{\n  options.DefaultExpirationTimeSpan = TimeSpan.FromSeconds(20);\n  options.AddPolicy(\"views\", p =&gt; p.SetVaryByQuery(\"\"));\n});<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, in the call to <code class=\"calibre9\">CacheOutput<\/code> for MVC, specify the named policy, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.MapControllerRoute(\n    name: \"default\",\n    pattern: \"{controller=Home}\/{action=Index}\/{id?}\")\n  .CacheOutput(policyName: \"views\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">ProductDetail.cshtml<\/code>, modify the <code class=\"calibre9\">&lt;p&gt;<\/code> that outputs the current time to set its alert style based on a value stored in the <code class=\"calibre9\">ViewData<\/code> dictionary, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;p class=\"alert alert-@ViewData[\"alertstyle\"]\"&gt;\n  @DateTime.Now.ToLongTimeString()&lt;\/p&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Controllers<\/code> folder, in <code class=\"calibre9\">HomeController.cs<\/code>, in the <code class=\"calibre9\">ProductDetail<\/code> action method, store a query string value in the <code class=\"calibre9\">ViewData<\/code> dictionary, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public IActionResult ProductDetail(int? id, \n  string alertstyle = \"success\")\n{\n  ViewData[\"alertstyle\"] = alertstyle;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Arrange the browser and command prompt or terminal window so that you can see both.<\/li>\n<li class=\"calibre3\">On the home page, scroll down, select one of the products, and note the color of the alert is green because the <code class=\"calibre9\">alertstyle<\/code> defaults to <code class=\"calibre9\">success<\/code>.<\/li>\n<li class=\"calibre3\">In the browser address bar, append a query string parameter, <code class=\"calibre9\">?alertstyle=warning<\/code>, and note that it is ignored, because the same cached page is returned.<\/li>\n<li class=\"calibre3\">In the browser address bar, change the product ID number to a value between 1 and 77 to request a different product and append a query string parameter, <code class=\"calibre9\">?alertstyle=warning<\/code>. Note that the alert is yellow because it is treated as a new request.<\/li>\n<li class=\"calibre3\">In the browser address bar, append a query string parameter, <code class=\"calibre9\">?alertstyle=info<\/code>, and note that it is ignored, because the same cached page is returned.<\/li>\n<li class=\"calibre3\">Close the browser and shut down the web server.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, in the call to <code class=\"calibre9\">AddOutputCache<\/code>, in the call to <code class=\"calibre9\">AddPolicy<\/code>, set <code class=\"calibre9\">alertstyle<\/code> as the only named parameter to vary by for query string parameters, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddOutputCache(options =&gt;\n{\n  options.DefaultExpirationTimeSpan = TimeSpan.FromSeconds(20);\n  options.AddPolicy(\"views\", p =&gt; p.SetVaryByQuery(\"alertstyle\"));\n});<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Repeat the steps above to confirm that requests for different <code class=\"calibre9\">alertstyle<\/code> values do have their own cached copies but any other query string parameter would be ignored.<\/li>\n<li class=\"calibre3\">Close the browser and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"15.5.5\" id=\"calibre_link-778\">\n<h3 data-number=\"15.5.5\" class=\"calibre8\">Disabling caching to avoid confusion<\/h3>\n<p class=\"rights\">Before we continue, let's disable view output caching otherwise you are likely to be confused by the website behavior if or when you forget caching is enabled!<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, disable the output caching by commenting out the call to <code class=\"calibre9\">CacheOutput<\/code>, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.MapControllerRoute(\n    name: \"default\",\n    pattern: \"{controller=Home}\/{action=Index}\/{id?}\");\n\/\/  .CacheOutput(policyName: \"views\");<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Save the changes.<\/li>\n<\/ol>\n<\/section>\n<\/section>\n<section data-number=\"15.6\" id=\"calibre_link-779\">\n<h2 data-number=\"15.6\" class=\"calibre5\">Querying a database and using display templates<\/h2>\n<p class=\"rights\">Let's create a new action method that can have a query string parameter passed to it and use that to query the Northwind database for products that cost more than a specified price.In previous examples, we defined a view model that contained properties for every value that needed to be rendered in the view. In this example, there will be two values: a list of products and the price the visitor entered. To avoid having to define a class or record for the view model, we will pass the list of products as the model and store the maximum price in the <code class=\"calibre9\">ViewData<\/code> collection.Let's implement this feature:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">HomeController.cs<\/code>, add a new action method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public IActionResult ProductsThatCostMoreThan(decimal? price)\n{\n  if (!price.HasValue)\n  {\n    return BadRequest(\"You must pass a product price in the query string, for example, \/Home\/ProductsThatCostMoreThan?price=50\");\n  }\n  IEnumerable&lt;Product&gt; model = _db.Products\n    .Include(p =&gt; p.Category)\n    .Include(p =&gt; p.Supplier)\n    .Where(p =&gt; p.UnitPrice &gt; price);\n  if (!model.Any())\n  {\n    return NotFound(\n      $\"No products cost more than {price:C}.\");\n  }\n  ViewData[\"MaxPrice\"] = price.Value.ToString(\"C\");\n  return View(model);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Views<\/strong>\/<strong class=\"calibre2\">Home<\/strong> folder, add a new file named <code class=\"calibre9\">ProductsThatCostMoreThan.cshtml<\/code>.<\/li>\n<li class=\"calibre3\">Modify the contents, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@using Northwind.EntityModels\n@model IEnumerable&lt;Product&gt; \n@{\n  string title =\n    $\"Products That Cost More Than {ViewData[\"MaxPrice\"]}\"; \n  ViewData[\"Title\"] = title;\n}\n&lt;h2&gt;@title&lt;\/h2&gt;\n@if (Model is null)\n{\n  &lt;div&gt;No products found.&lt;\/div&gt;\n}\nelse\n{\n  &lt;table class=\"table\"&gt;\n    &lt;thead&gt;\n      &lt;tr&gt;\n        &lt;th&gt;Category Name&lt;\/th&gt;\n        &lt;th&gt;Supplier's Company Name&lt;\/th&gt;\n        &lt;th&gt;Product Name&lt;\/th&gt;\n        &lt;th&gt;Unit Price&lt;\/th&gt;\n        &lt;th&gt;Units In Stock&lt;\/th&gt;\n      &lt;\/tr&gt;\n    &lt;\/thead&gt;\n    &lt;tbody&gt;\n    @foreach (Product p in Model)\n    {\n      &lt;tr&gt;\n        &lt;td&gt;\n          @Html.DisplayFor(modelItem =&gt; p.Category.CategoryName)\n        &lt;\/td&gt;\n        &lt;td&gt;\n          @Html.DisplayFor(modelItem =&gt; p.Supplier.CompanyName)\n        &lt;\/td&gt;\n        &lt;td&gt;\n          @Html.DisplayFor(modelItem =&gt; p.ProductName)\n        &lt;\/td&gt;\n        &lt;td&gt;\n          @Html.DisplayFor(modelItem =&gt; p.UnitPrice)\n        &lt;\/td&gt;\n        &lt;td&gt;\n          @Html.DisplayFor(modelItem =&gt; p.UnitsInStock)\n        &lt;\/td&gt;\n      &lt;\/tr&gt;\n    }\n    &lt;tbody&gt;\n  &lt;\/table&gt;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Views\/Home<\/code> folder, open <code class=\"calibre9\">Index.cshtml<\/code>.<\/li>\n<li class=\"calibre3\">Add the following form element below the visitor count and above the <strong class=\"calibre2\">Products<\/strong> heading and its listing of products. This will provide a form for the user to enter a price. The user can then click <strong class=\"calibre2\">Submit<\/strong> to call the action method that shows only products that cost more than the entered price:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;h3&gt;Query products by price&lt;\/h3&gt;\n&lt;form asp-action=\"ProductsThatCostMoreThan\" method=\"GET\"&gt;\n  &lt;input name=\"price\" placeholder=\"Enter a product price\" \/&gt;\n  &lt;input type=\"submit\" \/&gt;\n&lt;\/form&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">On the home page, enter a price in the form, for example, <code class=\"calibre9\">50<\/code>, and then click on <strong class=\"calibre2\">Submit<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Note the table of the products that cost more than the price that you entered, as shown in <em class=\"calibre10\">Figure 14.9<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 14.9: A filtered list of products that cost more than \u00a350\" height=\"436\" src=\"\/images\/cs12\/000126.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 14.9: A filtered list of products that cost more than \u00a350<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<section data-number=\"15.6.1\" id=\"calibre_link-780\">\n<h3 data-number=\"15.6.1\" class=\"calibre8\">Improving scalability using asynchronous tasks<\/h3>\n<p class=\"rights\">When building a desktop or mobile app, multiple tasks (and their underlying threads) can be used to improve responsiveness, because while one thread is busy with the task, another can handle interactions with the user.Tasks and their threads can be useful on the server side too, especially with websites that work with files, or request data from a store or a web service that could take a while to respond. But they are detrimental to complex calculations that are CPU-bound, so leave these to be processed synchronously as normal.When an HTTP request arrives at the web server, a thread from its pool is allocated to handle the request. But if that thread must wait for a resource, then it is blocked from handling any more incoming requests. If a website receives more simultaneous requests than it has threads in its pool, then some of those requests will respond with a server timeout error, <strong class=\"calibre2\">503 Service Unavailable<\/strong>.The threads that are locked are not doing useful work. They <em class=\"calibre10\">could<\/em> handle one of those other requests, but only if we implement asynchronous code for our websites.Whenever a thread is waiting for a resource it needs, it can return to the thread pool and handle a different incoming request, improving the scalability of the website, that is, increasing the number of simultaneous requests it can handle.Why not just have a larger thread pool? In modern operating systems, every thread in the pool has a 1 MB stack. An asynchronous method uses a smaller amount of memory. It also removes the need to create new threads in the pool, which takes time. The rate at which new threads are added to the pool is typically one every two seconds, which is a <em class=\"calibre10\">loooooong<\/em> time compared to switching between asynchronous threads.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Make your controller action methods asynchronous.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Localization and globalization for .NET and ASP.NET Core projects are covered in multiple chapters in the companion book, <em class=\"calibre10\">Apps and Services with .NET 8<\/em>.<\/p>\n<\/blockquote>\n<\/blockquote>\n<\/section>\n<section data-number=\"15.6.2\" id=\"calibre_link-781\">\n<h3 data-number=\"15.6.2\" class=\"calibre8\">Making controller action methods asynchronous<\/h3>\n<p class=\"rights\">In an earlier task, you imported the <code class=\"calibre9\">Microsoft.EntityFrameworkCore<\/code> namespace so that you could use the <code class=\"calibre9\">Include<\/code> extension method. You are about to use another extension method that requires that namespace to be imported.It is easy to make an existing action method asynchronous:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of <code class=\"calibre9\">HomeController.cs<\/code>, make sure the namespace for adding EF Core extension methods is imported, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ To use the Include and ToListAsync extension methods.\nusing Microsoft.EntityFrameworkCore;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">HomeController.cs<\/code>, modify the <code class=\"calibre9\">Index<\/code> action method to be asynchronous and await the calls to asynchronous methods to get the categories and products, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[ResponseCache(Duration = 10 \/* seconds *\/,\n  Location = ResponseCacheLocation.Any)]\npublic async Task&lt;IActionResult&gt; Index()\n{\n  _logger.LogError(\"This is a serious error (not really!)\");\n  _logger.LogWarning(\"This is your first warning!\");\n  _logger.LogWarning(\"Second warning!\");\n  _logger.LogInformation(\"I am in the Index method of the HomeController.\");\n  HomeIndexViewModel model = new\n  (\n    VisitorCount: Random.Shared.Next(1, 1001),\n    Categories: await _db.Categories.ToListAsync(),\n    Products: await _db.Products.ToListAsync()\n  );\n  return View(model); \/\/ Pass the model to the view.\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Modify the <code class=\"calibre9\">ProductDetail<\/code> action method in a similar way, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public async Task&lt;IActionResult&gt; ProductDetail(int? id,<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">ProductDetail<\/code> action method, await the calls to asynchronous methods to get the product, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Product? model = await _db.Products.Include(p =&gt; p.Category)\n  .SingleOrDefaultAsync(p =&gt; p.ProductId == id);<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> website project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Note that the functionality of the website is the same, but trust that it will now scale better.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<\/section>\n<section data-number=\"15.7\" id=\"calibre_link-782\">\n<h2 data-number=\"15.7\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring this chapter's topics with deeper research.<\/p>\n<section data-number=\"15.7.1\" id=\"calibre_link-783\">\n<h3 data-number=\"15.7.1\" class=\"calibre8\">Exercise 14.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What do the files with the special names <code class=\"calibre9\">_ViewStart<\/code> and <code class=\"calibre9\">_ViewImports<\/code> do when created in the <code class=\"calibre9\">Views<\/code> folder?<\/li>\n<li class=\"calibre3\">What are the names of the three segments defined in the default ASP.NET Core MVC route, what do they represent, and which are optional?<\/li>\n<li class=\"calibre3\">What does the default model binder do, and what data types can it handle?<\/li>\n<li class=\"calibre3\">In a shared layout file like <code class=\"calibre9\">_Layout.cshtml<\/code>, how do you output the content of the current view?<\/li>\n<li class=\"calibre3\">In a shared layout file like <code class=\"calibre9\">_Layout.cshtml<\/code>, how do you output a section that the current view can supply content for, and how does the view supply the contents for that section?<\/li>\n<li class=\"calibre3\">When calling the <code class=\"calibre9\">View<\/code> method inside a controller's action method, what paths are searched for the view by convention?<\/li>\n<li class=\"calibre3\">How can you instruct the visitor's browser to cache the response for 24 hours?<\/li>\n<li class=\"calibre3\">Why might you enable Razor Pages even if you are not creating any yourself?<\/li>\n<li class=\"calibre3\">How does ASP.NET Core MVC identify classes that can act as controllers?<\/li>\n<li class=\"calibre3\">In what ways does ASP.NET Core MVC make it easier to test a website?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"15.7.2\" id=\"calibre_link-784\">\n<h3 data-number=\"15.7.2\" class=\"calibre8\">Exercise 14.2 &ndash; Practice implementing MVC by implementing a category detail page<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">Northwind.Mvc<\/code> project has a home page that shows categories, but when the <code class=\"calibre9\">View<\/code> button is clicked, the website returns a <code class=\"calibre9\">404 Not Found<\/code> error, for example, for the following URL:<code class=\"calibre9\">https:\/\/localhost:5141\/home\/categorydetail\/1<\/code>Extend the <code class=\"calibre9\">Northwind.Mvc<\/code> project by adding the ability to show a detail page for a category.For example, add an action method to the <code class=\"calibre9\">HomeController<\/code> class, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public async Task&lt;IActionResult&gt; CategoryDetail(int? id)\n{\n  if (!id.HasValue)\n  {\n    return BadRequest(\"You must pass a category ID in the route, for example, \/Home\/CategoryDetail\/6\");\n  }\n  Category? model = await db.Categories.Include(p =&gt; p.Products)\n    .SingleOrDefaultAsync(p =&gt; p.CategoryId == id);\n  if (model is null)\n  {\n    return NotFound($\"CategoryId {id} not found.\");\n  }\n  return View(model); \/\/ Pass model to view and then return result.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">And create a view that matches the name <code class=\"calibre9\">CategoryDetail.cshtml<\/code>, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@model Northwind.EntityModels.Category\n@{\n  ViewData[\"Title\"] = \"Category Detail - \" + Model.CategoryName;\n}\n&lt;h2&gt;Category Detail&lt;\/h2&gt;\n&lt;div&gt;\n  &lt;dl class=\"dl-horizontal\"&gt;\n    &lt;dt&gt;Category Id&lt;\/dt&gt;\n    &lt;dd&gt;@Model.CategoryId&lt;\/dd&gt;\n    &lt;dt&gt;Product Name&lt;\/dt&gt;\n    &lt;dd&gt;@Model.CategoryName&lt;\/dd&gt;\n    &lt;dt&gt;Products&lt;\/dt&gt;\n    &lt;dd&gt;@Model.Products.Count&lt;\/dd&gt;\n    &lt;dt&gt;Description&lt;\/dt&gt;\n    &lt;dd&gt;@Model.Description&lt;\/dd&gt;\n  &lt;\/dl&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"15.7.3\" id=\"calibre_link-785\">\n<h3 data-number=\"15.7.3\" class=\"calibre8\">Exercise 14.3 &ndash; Practice improving scalability by understanding and implementing async action methods<\/h3>\n<p class=\"rights\">Almost a decade ago, Stephen Cleary wrote an excellent article for MSDN Magazine explaining the scalability benefits of implementing async action methods for ASP.NET. The same principles apply to ASP.NET Core, but even more so, because unlike the old ASP.NET as described in the article, ASP.NET Core supports asynchronous filters and other components.Read the article at the following link:<a href=\"https:\/\/learn.microsoft.com\/en-us\/archive\/msdn-magazine\/2014\/october\/async-programming-introduction-to-async-await-on-asp-net\">https:\/\/learn.microsoft.com\/en-us\/archive\/msdn-magazine\/2014\/october\/async-programming-introduction-to-async-await-on-asp-net<\/a><\/p>\n<\/section>\n<section data-number=\"15.7.4\" id=\"calibre_link-786\">\n<h3 data-number=\"15.7.4\" class=\"calibre8\">Exercise 14.4 &ndash; Practice unit testing MVC controllers<\/h3>\n<p class=\"rights\">Controllers are where the business logic of your website runs, so it is important to test the correctness of that logic using unit tests, as you learned in <em class=\"calibre10\">Chapter 4<\/em>, <em class=\"calibre10\">Writing, Debugging, and Testing Functions<\/em>.Write some unit tests for <code class=\"calibre9\">HomeController<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: You can read more about how to unit test controllers at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/testing\">https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/testing<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"15.7.5\" id=\"calibre_link-787\">\n<h3 data-number=\"15.7.5\" class=\"calibre8\">Exercise 14.5 &ndash; Using a filter to control authorization<\/h3>\n<p class=\"rights\">In this chapter, you learned about cross-functional filters like <code class=\"calibre9\">[Route]<\/code> and <code class=\"calibre9\">[ResponseCache]<\/code>. To learn how to secure parts of a website using the <code class=\"calibre9\">[Authorize]<\/code> attribute, you can read an optional online-only section at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch14-authorization.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch14-authorization.md<\/a><\/p>\n<\/section>\n<section data-number=\"15.7.6\" id=\"calibre_link-788\">\n<h3 data-number=\"15.7.6\" class=\"calibre8\">Exercise 14.6 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more about the topics covered in this chapter:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-14---building-websites-using-the-model-view-controller-pattern\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-14---building-websites-using-the-model-view-controller-pattern<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"15.8\" id=\"calibre_link-789\">\n<h2 data-number=\"15.8\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned how to build large, complex websites in a way that is easy to unit test by registering and injecting dependency services like database contexts and loggers. You learned about:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Configuration<\/li>\n<li class=\"calibre3\">Routes<\/li>\n<li class=\"calibre3\">Models<\/li>\n<li class=\"calibre3\">Views<\/li>\n<li class=\"calibre3\">Controllers<\/li>\n<li class=\"calibre3\">Caching<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will learn how to build and consume services that use HTTP as the communication layer, aka web services.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-5\">\n<div id=\"calibre_link-1941\" class=\"calibre1\">\n<section data-number=\"16\" id=\"calibre_link-790\">\n<h1 data-number=\"16\" class=\"title\">15 Building and Consuming Web Services<\/h1>\n<section data-number=\"16.1\" id=\"calibre_link-791\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"16.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000006.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about learning how to build web services (aka HTTP or <strong class=\"calibre2\">Representational State Transfer<\/strong> (<strong class=\"calibre2\">REST<\/strong>) services) using the ASP.NET Core Web API. You will then learn how to consume web services using HTTP clients, which could be any other type of .NET app, including a website or a mobile or desktop app.This chapter requires the knowledge and skills that you learned in <em class=\"calibre10\">Chapter 10<\/em>, <em class=\"calibre10\">Working with Data Using Entity Framework Core<\/em>, and <em class=\"calibre10\">Chapters 12<\/em> to <em class=\"calibre10\">14<\/em>, about building websites using ASP.NET Core.In this chapter, we will cover the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Building web services using the ASP.NET Core Web API<\/li>\n<li class=\"calibre3\">Creating a web service for the Northwind database<\/li>\n<li class=\"calibre3\">Documenting and testing web services<\/li>\n<li class=\"calibre3\">Consuming web services using HTTP clients<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"16.2\" id=\"calibre_link-792\">\n<h2 data-number=\"16.2\" class=\"calibre5\">Building web services using the ASP.NET Core Web API<\/h2>\n<p class=\"rights\">Before we build a modern web service, we need to cover some background to set the context for this chapter.<\/p>\n<section data-number=\"16.2.1\" id=\"calibre_link-793\">\n<h3 data-number=\"16.2.1\" class=\"calibre8\">Understanding web service acronyms<\/h3>\n<p class=\"rights\">Although HTTP was originally designed to request and respond with HTML and other resources for humans to look at, it is also good for building services.Roy Fielding stated in his doctoral dissertation, describing the REST architectural style, that the HTTP standard would be good for building services because it defines the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">URIs to uniquely identify resources, like <a href=\"https:\/\/localhost:5151\/api\/products\/23\">https:\/\/localhost:5151\/api\/products\/23<\/a>.<\/li>\n<li class=\"calibre3\">Methods for performing common tasks on those resources, like <code class=\"calibre9\">GET<\/code>, <code class=\"calibre9\">POST<\/code>, <code class=\"calibre9\">PUT<\/code>, and <code class=\"calibre9\">DELETE<\/code>.<\/li>\n<li class=\"calibre3\">The ability to negotiate the media type of content exchanged in requests and responses, such as XML and JSON. Content negotiation happens when the client specifies a request header like <code class=\"calibre9\">Accept: application\/xml,*\/*;q=0.8<\/code>. The default response format used by the ASP.NET Core Web API is JSON, which means one of the response headers would be <code class=\"calibre9\">Content-Type: application\/json; charset=utf-8<\/code>.<\/li>\n<\/ul>\n<p class=\"rights\"><strong class=\"calibre2\">Web services<\/strong>, aka Web APIs, use the HTTP communication standard, so they are sometimes called HTTP or RESTful services. HTTP or RESTful services are what this chapter is about.<\/p>\n<\/section>\n<section data-number=\"16.2.2\" id=\"calibre_link-794\">\n<h3 data-number=\"16.2.2\" class=\"calibre8\">Understanding HTTP requests and responses for Web APIs<\/h3>\n<p class=\"rights\">HTTP defines standard types of requests and standard codes to indicate a type of response. Most of them can be used to implement Web API services.The most common type of request is <code class=\"calibre9\">GET<\/code>, to retrieve a resource identified by a unique path, with additional options like what media type is acceptable set as a request header, like <code class=\"calibre9\">Accept<\/code>, as shown in the following example:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">GET \/path\/to\/resource\nAccept: application\/json<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Common responses include success and multiple types of failure, as shown in <em class=\"calibre10\">Table 15.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre19\"><\/col>\n<col class=\"calibre19\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Status code<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">101 Switching Protocols<\/code><\/td>\n<td class=\"calibre21\">The requester has asked the server to switch protocols and the server has agreed to do so. For example, it is common to switch from HTTP to <strong class=\"calibre2\">WebSockets<\/strong> ( <strong class=\"calibre2\">WS<\/strong> )for more efficient communication.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">103 Early Hints<\/code><\/td>\n<td class=\"calibre21\">\n<p class=\"rights\">Used to convey hints that help a client make preparations to process the final response. For example, the server might send the following response before then sending a normal <code class=\"calibre9\">200 OK<\/code> response for a web page that uses a stylesheet and JavaScript file:<\/p>\n<p class=\"rights\">HTTP\/1.1 103 Early Hints<\/p>\n<p class=\"rights\">Link: &lt;\/style.css&gt;; rel=preload; as=style<\/p>\n<p class=\"rights\">Link: &lt;\/script.js&gt;; rel=preload; as=script<\/p>\n<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">200 OK<\/code><\/td>\n<td class=\"calibre21\">The path was correctly formed, the resource was successfully found, serialized into an acceptable media type, and then returned in the response body. The response headers specify the <code class=\"calibre9\">Content-Type<\/code> , <code class=\"calibre9\">Content-Length<\/code> , and <code class=\"calibre9\">Content-Encoding<\/code> , for example, <code class=\"calibre9\">GZIP<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">301 Moved Permanently<\/code><\/td>\n<td class=\"calibre21\">Over time, a web service may change its resource model, including the path used to identify an existing resource. The web service can indicate the new path by returning this status code and a response header named <code class=\"calibre9\">Location<\/code> that has the new path.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">302 Found<\/code><\/td>\n<td class=\"calibre21\">Like <code class=\"calibre9\">301<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">304 Not Modified<\/code><\/td>\n<td class=\"calibre21\">If the request includes the <code class=\"calibre9\">If-Modified-Since<\/code> header, then the web service can respond with this status code. The response body is empty because the client should use its cached copy of the resource.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">307 Temporary Redirect<\/code><\/td>\n<td class=\"calibre21\">The requested resource has been temporarily moved to the URL in the <code class=\"calibre9\">Location<\/code> header. The browser should make a new request using that URL. For example, this is what happens if you enable <code class=\"calibre9\">UseHttpsRedirection<\/code> and a client makes an HTTP request.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">400 Bad Request<\/code><\/td>\n<td class=\"calibre21\">The request was invalid, for example, it used a path for a product using an integer ID where the ID value is missing.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">401 Unauthorized<\/code><\/td>\n<td class=\"calibre21\">The request was valid and the resource was found, but the client did not supply credentials or is not authorized to access that resource. Re-authenticating may enable access, for example, by adding or changing the <code class=\"calibre9\">Authorization<\/code> request header.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">403 Forbidden<\/code><\/td>\n<td class=\"calibre21\">The request was valid and the resource was found, but the client is not authorized to access that resource. Re-authenticating will not fix the issue.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">404 Not Found<\/code><\/td>\n<td class=\"calibre21\">The request was valid, but the resource was not found. The resource may be found if the request is repeated later. To indicate that a resource will never be found, return <code class=\"calibre9\">410 Gone<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">406 Not Acceptable<\/code><\/td>\n<td class=\"calibre21\">If the request has an <code class=\"calibre9\">Accept<\/code> header that only lists media types that the web service does not support. For example, if the client requests JSON but the web service can only return XML.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">451 Unavailable for Legal Reasons<\/code><\/td>\n<td class=\"calibre21\">A website hosted in the USA might return this for requests coming from Europe to avoid having to comply with the <strong class=\"calibre2\">General Data Protection Regulation<\/strong> ( <strong class=\"calibre2\">GDPR<\/strong> ). The number was chosen as a reference to the novel Fahrenheit 451, in which books are banned and burned.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">500 Server Error<\/code><\/td>\n<td class=\"calibre21\">The request was valid, but something went wrong on the server side while processing the request. Retrying again later might work.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">503 Service Unavailable<\/code><\/td>\n<td class=\"calibre21\">The web service is busy and cannot handle the request. Trying again later might work.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 15.1: Common HTTP status code responses to the GET method<\/p>\n<p class=\"rights\">Other common types of HTTP requests include <code class=\"calibre9\">POST<\/code>, <code class=\"calibre9\">PUT<\/code>, <code class=\"calibre9\">PATCH<\/code>, or <code class=\"calibre9\">DELETE<\/code>, which create, modify, or delete resources.To create a new resource, you might make a <code class=\"calibre9\">POST<\/code> request with a body that contains the new resource, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">POST \/path\/to\/resource\nContent-Length: 123\nContent-Type: application\/json<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To create a new resource or update an existing resource, you might make a <code class=\"calibre9\">PUT<\/code> request with a body that contains a whole new version of the existing resource, and if the resource does not exist, it is created, or if it does exist, it is replaced (sometimes called an <strong class=\"calibre2\">upsert<\/strong> operation), as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">PUT \/path\/to\/resource\nContent-Length: 123\nContent-Type: application\/json<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To update an existing resource more efficiently, you might make a <code class=\"calibre9\">PATCH<\/code> request with a body that contains an object with only the properties that need changing, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">PATCH \/path\/to\/resource\nContent-Length: 123\nContent-Type: application\/json<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To delete an existing resource, you might make a <code class=\"calibre9\">DELETE<\/code> request, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">DELETE \/path\/to\/resource<\/code><\/pre>\n<\/div>\n<p class=\"rights\">As well as the responses shown in the table above for a <code class=\"calibre9\">GET<\/code> request, all the types of requests that create, modify, or delete a resource have additional possible common responses, as shown in <em class=\"calibre10\">Table 15.2<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Status code<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">201 Created<\/code><\/td>\n<td class=\"calibre21\">The new resource was created successfully, the response header named <code class=\"calibre9\">Location<\/code> contains its path, and the response body contains the newly created resource. Immediately <code class=\"calibre9\">GET<\/code> -ing the resource should return <code class=\"calibre9\">200<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">202 Accepted<\/code><\/td>\n<td class=\"calibre21\">The new resource cannot be created immediately so the request is queued for later processing and immediately <code class=\"calibre9\">GET<\/code> -ing the resource might return <code class=\"calibre9\">404<\/code> . The body can contain a resource that points to some form of status checker or an estimate of when the resource will become available.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">204 No Content<\/code><\/td>\n<td class=\"calibre21\">Commonly used in response to a <code class=\"calibre9\">DELETE<\/code> request since returning the resource in the body after deleting it does not usually make sense! Sometimes used in response to <code class=\"calibre9\">POST<\/code> , <code class=\"calibre9\">PUT<\/code> , or <code class=\"calibre9\">PATCH<\/code> requests if the client does not need to confirm that the request was processed correctly.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">405 Method Not Allowed<\/code><\/td>\n<td class=\"calibre21\">Returned when the request used a method that is not supported. For example, a web service designed to be read-only may explicitly disallow <code class=\"calibre9\">PUT<\/code> , <code class=\"calibre9\">DELETE<\/code> , and so on.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">415 Unsupported Media Type<\/code><\/td>\n<td class=\"calibre21\">Returned when the resource in the request body uses a media type that the web service cannot handle. For example, if the body contains a resource in XML format but the web service can only process JSON.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 15.2: Common HTTP status code responses to other methods like POST and PUT<br \/>\n<\/section>\n<section data-number=\"16.2.3\" id=\"calibre_link-795\">\n<h3 data-number=\"16.2.3\" class=\"calibre8\">Creating an ASP.NET Core Web API project<\/h3>\n<p class=\"rights\">We will build a web service that provides a way to work with data in the Northwind database using ASP.NET Core so that the data can be used by any client application on any platform that can make HTTP requests and receive HTTP responses.Traditionally, you use the <strong class=\"calibre2\">ASP.NET Core Web API<\/strong> \/ <code class=\"calibre9\">dotnet new webapi<\/code> project template. This allows the creation of a web service implemented using either controllers like MVC or the newer Minimal APIs. Those are what we will use in this chapter because they provide maximum flexibility.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> With .NET 6 and .NET 7, the <code class=\"calibre9\">dotnet new webapi<\/code> command creates a service implemented using controllers. To implement the service using Minimal APIs, you need to add the <code class=\"calibre9\">--use-minimal-apis<\/code> switch to the command. Using .NET 8, the <code class=\"calibre9\">dotnet new webapi<\/code> command creates a service implemented using Minimal APIs. To implement the service using controllers, you need to add the <code class=\"calibre9\">--use-controllers<\/code> switch.<\/p>\n<\/blockquote>\n<p class=\"rights\">.NET 8 introduces the <strong class=\"calibre2\">ASP.NET Core API<\/strong> \/ <code class=\"calibre9\">dotnet new api<\/code> project template, which only uses Minimal APIs and supports native AOT publishing. If you would like to see this in action, then there is an optional online-only section that you can complete at the end of this chapter.For the print chapter, we will build on your experience with MVC by creating a Web API service using controllers. Let's go:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred code editor to open the <code class=\"calibre9\">PracticalApps<\/code> solution and then add a new project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">ASP.NET Core Web API<\/strong> \/ <code class=\"calibre9\">webapi &ndash;use-controllers<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">PracticalApps<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">Northwind.WebApi<\/code><\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">If you are using Visual Studio 2022, then confirm the following defaults have been chosen:<\/p>\n<ul class=\"calibre16\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Authentication type<\/strong>: None<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Configure for HTTPS<\/strong>: Selected<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Enable Docker<\/strong>: Cleared<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Enable OpenAPI support<\/strong>: Selected<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Do not use top-level statements<\/strong>: Cleared<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Use controllers<\/strong>: Selected<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Make sure to select the <strong class=\"calibre2\">Use controllers<\/strong> check box or your code will look very different!<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">If you are using Visual Studio Code or JetBrains Rider, then in the <code class=\"calibre9\">PracticalApps<\/code> directory, at the command prompt or terminal, enter the following:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new webapi &ndash;use-controllers -o Northwind.WebApi<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The JetBrains Rider new project dialog box does not provide an option to select the equivalent of <strong class=\"calibre2\">Use controllers<\/strong> \/ <code class=\"calibre9\">--use-controllers<\/code> or <code class=\"calibre9\">-controllers<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.WebApi<\/code> project.<\/li>\n<li class=\"calibre3\">In the project file, change invariant globalization to <code class=\"calibre9\">false<\/code> in the <code class=\"calibre9\">&lt;PropertyGroup&gt;<\/code>, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;InvariantGlobalization&gt;false&lt;\/InvariantGlobalization&gt;<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Explicitly setting invariant globalization to <code class=\"calibre9\">true<\/code> is new in the ASP.NET Core Web API project template with .NET 8. It is designed to make a web service non-culture-specific so it can be deployed anywhere in the world and have the same behavior. By setting this property to <code class=\"calibre9\">false<\/code>, the web service will default to the culture of the current computer it is hosted on. You can read more about invariant globalization mode at the following link: <a href=\"https:\/\/github.com\/dotnet\/runtime\/blob\/main\/docs\/design\/features\/globalization-invariant-mode.md\">https:\/\/github.com\/dotnet\/runtime\/blob\/main\/docs\/design\/features\/globalization-invariant-mode.md<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Controllers<\/code> folder, open and review <code class=\"calibre9\">WeatherForecastController.cs<\/code>, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.AspNetCore.Mvc;\nnamespace Northwind.WebApi.Controllers\n{\n  [ApiController]\n  [Route(\"[controller]\")]\n  public class WeatherForecastController : ControllerBase\n  {\n    private static readonly string[] Summaries = new[]\n    {\n      \"Freezing\", \"Bracing\", \"Chilly\", \"Cool\", \"Mild\",\n      \"Warm\", \"Balmy\", \"Hot\", \"Sweltering\", \"Scorching\"\n    };\n    private readonly ILogger&lt;WeatherForecastController&gt; _logger;\n    public WeatherForecastController(\n      ILogger&lt;WeatherForecastController&gt; logger)\n    {\n      _logger = logger;\n    }\n    [HttpGet(Name = \"GetWeatherForecast\")]\n    public IEnumerable&lt;WeatherForecast&gt; Get()\n    {\n      return Enumerable.Range(1, 5).Select(index =&gt; new WeatherForecast\n      {\n        Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),\n        TemperatureC = Random.Shared.Next(-20, 55),\n        Summary = Summaries[Random.Shared.Next(Summaries.Length)]\n      })\n      .ToArray();\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">While reviewing the preceding code, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The <code class=\"calibre9\">Controller<\/code> class inherits from <code class=\"calibre9\">ControllerBase<\/code>. This is simpler than the <code class=\"calibre9\">Controller<\/code> class used in MVC because it does not have methods like <code class=\"calibre9\">View<\/code> to generate HTML responses by passing a view model to a Razor file.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">The <code class=\"calibre9\">[Route]<\/code> attribute registers the <code class=\"calibre9\">\/weatherforecast<\/code> relative URL for clients to use to make HTTP requests that will be handled by this controller. For example, an HTTP request for <code class=\"calibre9\">https:\/\/localhost:5001\/weatherforecast\/<\/code> would be handled by this controller. Some developers like to prefix the controller name with <code class=\"calibre9\">api\/<\/code>, which is a convention to differentiate between MVCs and Web APIs in mixed projects. If you use <code class=\"calibre9\">[controller]<\/code> as shown, it uses the characters before <code class=\"calibre9\">Controller<\/code> in the class name, in this case, <code class=\"calibre9\">WeatherForecast<\/code>, or you can simply enter a different name without the square brackets, for example, <code class=\"calibre9\">[Route(\"api\/forecast\")]<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Specifying a route using a literal string like this is poor practice. I am only doing so here to keep the example simple. It would be better in practice to define a static class with string constant values and use those instead. Then, you have a central place to change routes if needed in the future.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">[ApiController]<\/code> attribute was introduced with ASP.NET Core 2.1 and it enables REST-specific behavior for controllers, like automatic HTTP <code class=\"calibre9\">400<\/code> responses for invalid models, as you will see later in this chapter.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">[HttpGet]<\/code> attribute registers the <code class=\"calibre9\">Get<\/code> method in the <code class=\"calibre9\">Controller<\/code> class to respond to HTTP <code class=\"calibre9\">GET<\/code> requests, and its implementation uses the shared <code class=\"calibre9\">Random<\/code> object to return an array of <code class=\"calibre9\">WeatherForecast<\/code> objects with random temperatures and summaries like <code class=\"calibre9\">Bracing<\/code> or <code class=\"calibre9\">Balmy<\/code> for the next five days of weather.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">WeatherForecastController.cs<\/code>, add a second <code class=\"calibre9\">Get<\/code> method that allows the call to specify how many days ahead the forecast should be by implementing the following:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Add a comment above the original method to show the action method and URL path that it responds to.<\/li>\n<li class=\"calibre3\">Add a new method with an integer parameter named <code class=\"calibre9\">days<\/code>.<\/li>\n<li class=\"calibre3\">Cut and paste the original <code class=\"calibre9\">Get<\/code> method implementation code statements into the new <code class=\"calibre9\">Get<\/code> method. We are cutting because we need to move the statements from the original method to the new method.<\/li>\n<li class=\"calibre3\">Modify the new method to create an <code class=\"calibre9\">IEnumerable<\/code> of integers up to the number of days requested.<\/li>\n<li class=\"calibre3\">Modify the original <code class=\"calibre9\">Get<\/code> method to call the new <code class=\"calibre9\">Get<\/code> method and pass the value <code class=\"calibre9\">5<\/code>.<\/li>\n<li class=\"calibre3\">Modify the registered name of the original <code class=\"calibre9\">Get<\/code> method to <code class=\"calibre9\">GetWeatherForecastFiveDays<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p class=\"rights\">Your modifications and additions should be as shown highlighted in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ GET \/weatherforecast\n[HttpGet(Name = \"GetWeatherForecastFiveDays\")]\npublic IEnumerable&lt;WeatherForecast&gt; Get()\n{\n  return Get(days: 5); \/\/ Five-day forecast.\n}\n\/\/ GET \/weatherforecast\/7\n[HttpGet(template: \"{days:int}\", Name = \"GetWeatherForecast\")]\npublic IEnumerable&lt;WeatherForecast&gt; Get(int days)\n{\n  return Enumerable.Range(1, days).Select(index =&gt; new WeatherForecast\n    {\n      Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),\n      TemperatureC = Random.Shared.Next(-20, 55),\n      Summary = Summaries[Random.Shared.Next(Summaries.Length)]\n    })\n    .ToArray();\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">In the <code class=\"calibre9\">[HttpGet]<\/code> attribute, note the route template pattern <code class=\"calibre9\">{days:int}<\/code> constrains the <code class=\"calibre9\">days<\/code> parameter to <code class=\"calibre9\">int<\/code> values.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"16.2.4\" id=\"calibre_link-796\">\n<h3 data-number=\"16.2.4\" class=\"calibre8\">Reviewing the web service's functionality<\/h3>\n<p class=\"rights\">Now, we will test the web service's functionality:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Properties<\/code> folder, in <code class=\"calibre9\">launchSettings.json<\/code>, note that by default, if you are using Visual Studio 2022, the <code class=\"calibre9\">https<\/code> profile will launch the browser and navigate to the <code class=\"calibre9\">\/swagger<\/code> relative URL path, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\"https\": {\n  \"commandName\": \"Project\",\n  \"dotnetRunMessages\": true,\n  \"launchBrowser\": true,\n  \"launchUrl\": \"swagger\",<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">For the <code class=\"calibre9\">https<\/code> profile, for its <code class=\"calibre9\">applicationUrl<\/code>, change the random port number for HTTPS to <code class=\"calibre9\">5151<\/code> and for HTTP to <code class=\"calibre9\">5150<\/code>, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\"applicationUrl\": \"https:\/\/localhost:5151;http:\/\/localhost:5150\",<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Save changes to all modified files.<\/li>\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.WebApi<\/code> web service project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">On Windows, if you see a <strong class=\"calibre2\">Windows Security Alert<\/strong> dialog box saying <strong class=\"calibre2\">Windows Defender Firewall has blocked some features of this app<\/strong>, then click the <strong class=\"calibre2\">Allow access<\/strong> button.<\/li>\n<li class=\"calibre3\">Start Chrome, navigate to <code class=\"calibre9\">https:\/\/localhost:5151\/<\/code>, and note you will get a <code class=\"calibre9\">404<\/code> status code response because we have not enabled static files and there is not an <code class=\"calibre9\">index.xhtml<\/code>, nor is there an MVC controller with a route configured. Remember that this project is not designed for a human to view and interact with, so this is expected behavior for a web service.<\/li>\n<li class=\"calibre3\">In Chrome, show <strong class=\"calibre2\">Developer Tools<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Navigate to <code class=\"calibre9\">https:\/\/localhost:5151\/weatherforecast<\/code> and note the Web API service should return a JSON document with five random weather forecast objects in an array, as shown in <em class=\"calibre10\">Figure 15.1<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.1: A request and response from a weather forecast web service\" height=\"937\" src=\"\/images\/cs12\/000014.png\" width=\"2161\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.1: A request and response from a weather forecast web service<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Note that browsers like Chrome will attempt to request a <code class=\"calibre9\">favicon.ico<\/code> file to show in the browser tab. If the 404 errors annoy you, then you could create one, but we are only using the browser for basic web service testing at this time.<\/li>\n<li class=\"calibre3\">Close <strong class=\"calibre2\">Developer Tools<\/strong>.<\/li>\n<li class=\"calibre3\">Navigate to <code class=\"calibre9\">https:\/\/localhost:5151\/weatherforecast\/14<\/code> and note that the response when requesting a two-week weather forecast contains 14 forecasts.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<\/section>\n<section data-number=\"16.3\" id=\"calibre_link-797\">\n<h2 data-number=\"16.3\" class=\"calibre5\">Creating a web service for the Northwind database<\/h2>\n<p class=\"rights\">Unlike MVC controllers, Web API controllers do not call Razor views to return HTML responses for website visitors to see in browsers. Instead, they use <strong class=\"calibre2\">content negotiation<\/strong> with the client application that made the HTTP request to return data in formats such as XML, JSON, or X-WWW-FORM-URLENCODED in their HTTP response, which looks like the following:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">firstName=Mark&amp;lastName=Price&amp;jobtitle=Author<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The client application must then deserialize the data from the negotiated format. The most used format for modern web services is <strong class=\"calibre2\">JavaScript Object Notation<\/strong> (<strong class=\"calibre2\">JSON<\/strong>) because it is compact and works natively with JavaScript in a browser when building <strong class=\"calibre2\">Single-Page Applications<\/strong> (<strong class=\"calibre2\">SPAs<\/strong>) with client-side technologies like Angular, React, and Vue.We will reference the Entity Framework Core entity data model for the Northwind database that you created in <em class=\"calibre10\">Chapter 12<\/em>, <em class=\"calibre10\">Introducing Web Development Using ASP.NET Core<\/em>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.WebApi<\/code> project, add a project reference to the Northwind data context class library for either SQLite or SQL Server, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;!-- change Sqlite to SqlServer if you prefer --&gt;\n  &lt;ProjectReference Include=\n\"..\\Northwind.DataContext.Sqlite\\Northwind.DataContext.Sqlite.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.WebApi<\/code> project, globally and statically import the <code class=\"calibre9\">System.Console<\/code> class.<\/li>\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.WebApi<\/code> project and fix any compile errors in your code.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, import namespaces for working with web media formatters and the shared Packt classes, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.AspNetCore.Mvc.Formatters; \/\/ To use IOutputFormatter.\nusing Northwind.EntityModels; \/\/ To use AddNorthwindContext method.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement before the call to <code class=\"calibre9\">AddControllers<\/code> to register the <code class=\"calibre9\">Northwind<\/code> database context class (it will use either SQLite or SQL Server depending on which database provider you referenced in the project file), as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddNorthwindContext();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the call to <code class=\"calibre9\">AddControllers<\/code>, add a lambda block with statements to write the names and supported media types of the default output formatters to the console, and then add XML serializer formatters, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddControllers(options =&gt;\n{\n  WriteLine(\"Default output formatters:\");\n  foreach (IOutputFormatter formatter in options.OutputFormatters)\n  {\n    OutputFormatter? mediaFormatter = formatter as OutputFormatter;\n    if (mediaFormatter is null)\n    {\n      WriteLine($\"  {formatter.GetType().Name}\");\n    }\n    else \/\/ OutputFormatter class has SupportedMediaTypes.\n    {\n      WriteLine(\"  {0}, Media types: {1}\",\n        arg0: mediaFormatter.GetType().Name,\n        arg1: string.Join(\", \",\n          mediaFormatter.SupportedMediaTypes));\n    }\n  }\n})\n.AddXmlDataContractSerializerFormatters()\n.AddXmlSerializerFormatters();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.WebApi<\/code> web service project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">In the command prompt or terminal, note that there are four default output formatters, including ones that convert <code class=\"calibre9\">null<\/code> values into <code class=\"calibre9\">204 No Content<\/code> and ones to support responses that are plain text, byte streams, and JSON, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Default output formatters: \n  HttpNoContentOutputFormatter\n  StringOutputFormatter, Media types: text\/plain\n  StreamOutputFormatter\n  SystemTextJsonOutputFormatter, Media types: application\/json, text\/json, application\/*+json<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Shut down the web server.<\/li>\n<\/ol>\n<section data-number=\"16.3.1\" id=\"calibre_link-798\">\n<h3 data-number=\"16.3.1\" class=\"calibre8\">Registering dependency services<\/h3>\n<p class=\"rights\">You can register dependency services with different lifetimes, as shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Transient<\/strong>: These services are created each time they're requested. Transient services should be lightweight and stateless.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Scoped<\/strong>: These services are created once per client request and are disposed of then the response returns to the client.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Singleton<\/strong>: These services are usually created the first time they are requested and then shared, although you can provide an instance at the time of registration too.<\/li>\n<\/ul>\n<p class=\"rights\">Introduced in .NET 8 is the ability to set a key for a dependency service. This allows multiple services to be registered with different keys and then retrieved later using that key.<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddKeyedsingleton&lt;IMemoryCache, BigCache&gt;(\"big\");\nbuilder.Services.AddKeyedSingleton&lt;IMemoryCache, SmallCache&gt;(\"small\");\nclass BigCacheConsumer([FromKeyedServices(\"big\")] IMemoryCache cache)\n{\n  public object? GetData() =&gt; cache.Get(\"data\");\n}\nclass SmallCacheConsumer(IKeyedServiceProvider keyedServiceProvider)\n{\n  public object? GetData() =&gt; keyedServiceProvider\n    .GetRequiredKeyedService&lt;IMemoryCache&gt;(\"small\");\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">In this book, you will use all three types of lifetime but we will not need to use keyed services.<\/p>\n<\/section>\n<section data-number=\"16.3.2\" id=\"calibre_link-799\">\n<h3 data-number=\"16.3.2\" class=\"calibre8\">Creating data repositories with caching for entities<\/h3>\n<p class=\"rights\">Defining and implementing a data repository to provide CRUD operations is good practice. We will create a data repository for the <code class=\"calibre9\">Customers<\/code> table in Northwind. There are only 91 customers in this table, so we will cache a copy of the whole table in memory to improve scalability and performance when reading customer records.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: In a real web service, you should use a distributed cache like Redis, an open-source data structure store that can be used as a high-performance, high-availability database, cache, or message broker. You can learn about this at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/performance\/caching\/distributed\">https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/performance\/caching\/distributed<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">We will follow a modern good practice and make the repository API asynchronous. It will be instantiated by a <code class=\"calibre9\">Controller<\/code> class using constructor parameter injection, so a new instance is created to handle every HTTP request. It will use a singleton instance of an in-memory cache. Let's go:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.WebApi<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, import the namespace for working with an in-memory cache, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.Extensions.Caching.Memory; \/\/ To use IMemoryCache and so on.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, after the call to <code class=\"calibre9\">CreateBuilder<\/code>, in the section for configuring services, register an implementation for the in-memory cache as a singleton instance that is constructed immediately, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddSingleton&lt;IMemoryCache&gt;(\n  new MemoryCache(new MemoryCacheOptions()));<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.WebApi<\/code> project, create a folder named <code class=\"calibre9\">Repositories<\/code>.<\/li>\n<li class=\"calibre3\">Add a new interface file and a class file to the <code class=\"calibre9\">Repositories<\/code> folder named <code class=\"calibre9\">ICustomerRepository.cs<\/code> and <code class=\"calibre9\">CustomerRepository.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">ICustomerRepository.cs<\/code>, define an interface with five CRUD methods, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.EntityModels; \/\/ To use Customer.\nnamespace Northwind.WebApi.Repositories;\npublic interface ICustomerRepository\n{\n  Task&lt;Customer?&gt; CreateAsync(Customer c);\n  Task&lt;Customer[]&gt; RetrieveAllAsync();\n  Task&lt;Customer?&gt; RetrieveAsync(string id);\n  Task&lt;Customer?&gt; UpdateAsync(Customer c);\n  Task&lt;bool?&gt; DeleteAsync(string id);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">CustomerRepository.cs<\/code>, define a class that will implement the interface and uses the singleton in-memory cache with a 30-minute sliding expiration for its cache entries (its methods will be implemented over the next few steps), as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.EntityFrameworkCore.ChangeTracking; \/\/ To use EntityEntry&lt;T&gt;.\nusing Northwind.EntityModels; \/\/ To use Customer.\nusing Microsoft.Extensions.Caching.Memory; \/\/ To use IMemoryCache.\nusing Microsoft.EntityFrameworkCore; \/\/ To use ToArrayAsync.\nnamespace Northwind.WebApi.Repositories;\npublic class CustomerRepository : ICustomerRepository\n{\n  private readonly IMemoryCache _memoryCache;\n  private readonly MemoryCacheEntryOptions _cacheEntryOptions = new()\n  {\n    SlidingExpiration = TimeSpan.FromMinutes(30)\n  };\n  \/\/ Use an instance data context field because it should not be\n  \/\/ cached due to the data context having internal caching.\n  private NorthwindContext _db;\n  public CustomerRepository(NorthwindContext db,\n    IMemoryCache memoryCache)\n  {\n    _db = db;\n    _memoryCache = memoryCache;\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> Make sure you use <code class=\"calibre9\">MemoryCacheEntryOptions<\/code> and not <code class=\"calibre9\">MemoryCacheOptions<\/code>!<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Implement the create method, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public async Task&lt;Customer?&gt; CreateAsync(Customer c)\n{\n  c.CustomerId = c.CustomerId.ToUpper(); \/\/ Normalize to uppercase.\n  \/\/ Add to database using EF Core.\n  EntityEntry&lt;Customer&gt; added = await _db.Customers.AddAsync(c);\n  int affected = await _db.SaveChangesAsync();\n  if (affected == 1)\n  {\n    \/\/ If saved to database then store in cache.\n    _memoryCache.Set(c.CustomerId, c, _cacheEntryOptions);\n    return c;\n  }\n  return null;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Implement the retrieve all method to always read the latest customers from the database, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public Task&lt;Customer[]&gt; RetrieveAllAsync()\n{\n  return _db.Customers.ToArrayAsync();.\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Implement the retrieve method to use the in-memory cache if possible, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public Task&lt;Customer?&gt; RetrieveAsync(string id)\n{\n  id = id.ToUpper(); \/\/ Normalize to uppercase.\n  \/\/ Try to get from the cache first.\n  if (_memoryCache.TryGetValue(id, out Customer? fromCache))\n    return Task.FromResult(fromCache);\n  \/\/ If not in the cache, then try to get it from the database.\n  Customer? fromDb = _db.Customers.FirstOrDefault(c =&gt; c.CustomerId == id);\n  \/\/ If not -in database then return null result.\n  if (fromDb is null) return Task.FromResult(fromDb);\n  \/\/ If in the database, then store in the cache and return customer.\n  _memoryCache.Set(fromDb.CustomerId, fromDb, _cacheEntryOptions);\n  return Task.FromResult(fromDb)!;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Implement the update method to update the database and if successful then update the cached customer as well, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public async Task&lt;Customer?&gt; UpdateAsync(Customer c)\n{\n  c.CustomerId = c.CustomerId.ToUpper();\n  _db.Customers.Update(c);\n  int affected = await _db.SaveChangesAsync();\n  if (affected == 1)\n  {\n    _memoryCache.Set(c.CustomerId, c, _cacheEntryOptions);\n    return c;\n  }\n  return null;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Implement the delete method to delete the customer from the database and if successful then remove the cached customer as well, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public async Task&lt;bool?&gt; DeleteAsync(string id)\n{\n  id = id.ToUpper();\n  Customer? c = await _db.Customers.FindAsync(id);\n  if (c is null) return null;\n  _db.Customers.Remove(c);\n  int affected = await _db.SaveChangesAsync();\n  if (affected == 1)\n  {\n    _memoryCache.Remove(c.CustomerId);\n    return true;\n  }\n  return null;\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"16.3.3\" id=\"calibre_link-800\">\n<h3 data-number=\"16.3.3\" class=\"calibre8\">Routing web services<\/h3>\n<p class=\"rights\">With MVC controllers, a route like <code class=\"calibre9\">\/home\/index<\/code> tells us the controller class name and the action method name, for example, the <code class=\"calibre9\">HomeController<\/code> class and the <code class=\"calibre9\">Index<\/code> action method.With Web API controllers, a route like <code class=\"calibre9\">\/weatherforecast<\/code> only tells us the controller class name, for example, <code class=\"calibre9\">WeatherForecastController<\/code>. To determine the action method name to execute, we must map HTTP methods like <code class=\"calibre9\">GET<\/code> and <code class=\"calibre9\">POST<\/code> to methods in the controller class.You should decorate controller methods with the following attributes to indicate the HTTP method that they will respond to:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">[HttpGet]<\/code> and <code class=\"calibre9\">[HttpHead]<\/code>: These action methods respond to <code class=\"calibre9\">GET<\/code> or <code class=\"calibre9\">HEAD<\/code> requests to retrieve a resource and return either the resource and its response headers or just the response headers.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">[HttpPost]<\/code>: This action method responds to <code class=\"calibre9\">POST<\/code> requests to create a new resource or perform some other action defined by the service.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">[HttpPut]<\/code> and <code class=\"calibre9\">[HttpPatch]<\/code>: These action methods respond to <code class=\"calibre9\">PUT<\/code> or <code class=\"calibre9\">PATCH<\/code> requests to update an existing resource either by replacing it or updating a subset of its properties.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">[HttpDelete]<\/code>: This action method responds to <code class=\"calibre9\">DELETE<\/code> requests to remove a resource.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">[HttpOptions]<\/code>: This action method responds to <code class=\"calibre9\">OPTIONS<\/code> requests.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"16.3.4\" id=\"calibre_link-801\">\n<h3 data-number=\"16.3.4\" class=\"calibre8\">Route constraints<\/h3>\n<p class=\"rights\">Route constraints allow us to control matches based on data types and other validation. They are summarized in <em class=\"calibre10\">Table 15.3<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Constraint<\/td>\n<td class=\"calibre21\">Example<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">required<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">{id:required}<\/code><\/td>\n<td class=\"calibre21\">The parameter has been provided.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">int<\/code> and <code class=\"calibre9\">long<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">{id:int}<\/code><\/td>\n<td class=\"calibre21\">Any integer of the correct size.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">decimal<\/code> , <code class=\"calibre9\">double<\/code> , and <code class=\"calibre9\">float<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">{unitprice:decimal}<\/code><\/td>\n<td class=\"calibre21\">Any real number of the correct size.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">bool<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">{discontinued:bool}<\/code><\/td>\n<td class=\"calibre21\">Case-insensitive match on <code class=\"calibre9\">true<\/code> or <code class=\"calibre9\">false<\/code> .<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">datetime<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">{hired:datetime}<\/code><\/td>\n<td class=\"calibre21\">An invariant culture date\/time.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">guid<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">{id:guid}<\/code><\/td>\n<td class=\"calibre21\">A GUID value.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">minlength(n)<\/code> , <code class=\"calibre9\">maxlength(n)<\/code> , <code class=\"calibre9\">length(n)<\/code> , and <code class=\"calibre9\">length(n, m)<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">{title:minlength(5)}<\/code> , <code class=\"calibre9\">{title:length(5, 25)}<\/code><\/td>\n<td class=\"calibre21\">The text must have the defined minimum and\/or maximum length.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">min(n)<\/code> , <code class=\"calibre9\">max(n)<\/code> , and <code class=\"calibre9\">range(n, m)<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">{age:range(18, 65)}<\/code><\/td>\n<td class=\"calibre21\">The integer must be within the defined minimum and\/or maximum range.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">alpha<\/code> , <code class=\"calibre9\">regex<\/code><\/td>\n<td class=\"calibre21\"><code class=\"calibre9\">{firstname:alpha}<\/code> , <code class=\"calibre9\">{id:regex(^[A-Z]{{5}}$)}<\/code><\/td>\n<td class=\"calibre21\">The parameter must match one or more alphabetic characters or the regular expression.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 15.3: Route constraints with examples and descriptions<\/p>\n<p class=\"rights\">Use colons to separate multiple constraints, as shown in the following example:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[Route(\"employees\/{years:int:minlength(3)}\")]\npublic Employees[] GetLoyalEmployees(int years)<\/code><\/pre>\n<\/div>\n<p class=\"rights\">For regular expressions, <code class=\"calibre9\">RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant<\/code> is added automatically. Regular expression tokens must be escaped (replace <code class=\"calibre9\">\\<\/code> with <code class=\"calibre9\">\\\\<\/code>, <code class=\"calibre9\">{<\/code> with <code class=\"calibre9\">{{<\/code>, and <code class=\"calibre9\">}<\/code> with <code class=\"calibre9\">}}<\/code>) or use verbatim string literals.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can create custom route constraints by defining a class that implements <code class=\"calibre9\">IRouteConstraint<\/code>. This is beyond the scope of this book and you can read about it at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/routing#custom-route-constraints\">https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/routing#custom-route-constraints<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"16.3.5\" id=\"calibre_link-802\">\n<h3 data-number=\"16.3.5\" class=\"calibre8\">Short-circuit routes in ASP.NET Core 8<\/h3>\n<p class=\"rights\">When routing matches a request to an endpoint, it lets the rest of the middleware pipeline run before invoking the endpoint logic. That takes time, so in ASP.NET Core 8, you can invoke the endpoint immediately and return the response.You do this by calling the <code class=\"calibre9\">ShortCircuit<\/code> method on a mapped endpoint route, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.MapGet(\"\/\", () =&gt; \"Hello World\").ShortCircuit();<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Alternatively, you can call the <code class=\"calibre9\">MapShortCircuit<\/code> method to respond with a <code class=\"calibre9\">404 Missing Resource<\/code> or other status code for resources that don\u2019t need further processing, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.MapShortCircuit(404, \"robots.txt\", \"favicon.ico\");<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"16.3.6\" id=\"calibre_link-803\">\n<h3 data-number=\"16.3.6\" class=\"calibre8\">Improved route tooling in ASP.NET Core 8<\/h3>\n<p class=\"rights\">For .NET 8, Microsoft has improved the tooling for working with routes for all ASP.NET Core technologies including Minimal APIs, Web APIs, and Blazor. The features include the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Route syntax highlighting<\/strong>: Different parts of routes are now highlighted in your code editor.<\/li>\n<li class=\"calibre3\">Autocompletion of parameter and route names, and route constraints.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Route analyzers and fixers<\/strong>: These address the common problems that developers have when implementing their routes.<\/li>\n<\/ul>\n<p class=\"rights\">You can read about them in the blog article <em class=\"calibre10\">ASP.NET Core Route Tooling Enhancements in .NET 8<\/em>, found at the following link: <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/aspnet-core-route-tooling-dotnet-8\/\">https:\/\/devblogs.microsoft.com\/dotnet\/aspnet-core-route-tooling-dotnet-8\/<\/a>.<\/p>\n<\/section>\n<section data-number=\"16.3.7\" id=\"calibre_link-804\">\n<h3 data-number=\"16.3.7\" class=\"calibre8\">Understanding action method return types<\/h3>\n<p class=\"rights\">An action method can return .NET types like a single <code class=\"calibre9\">string<\/code> value; complex objects defined by a <code class=\"calibre9\">class<\/code>, <code class=\"calibre9\">record<\/code>, or <code class=\"calibre9\">struct<\/code>; or collections of complex objects. The ASP.NET Core will serialize them into the requested data format set in the HTTP request <code class=\"calibre9\">Accept<\/code> header, for example, JSON, if a suitable serializer has been registered.For more control over the response, there are helper methods that return an <code class=\"calibre9\">ActionResult<\/code> wrapper around the .NET type.Declare the action method's return type to be <code class=\"calibre9\">IActionResult<\/code> if it could return different return types based on the input or other variables. Declare the action method's return type to be <code class=\"calibre9\">ActionResult&lt;T&gt;<\/code> if it will only return a single type but with different status codes.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Decorate action methods with the <code class=\"calibre9\">[ProducesResponseType]<\/code> attribute to indicate all the known types and HTTP status codes that the client should expect in a response. This information can then be publicly exposed to document how a client should interact with your web service. Think of it as part of your formal documentation. Later in this chapter, you will learn how you can install a code analyzer to give you warnings when you do not decorate your action methods like this.<\/p>\n<\/blockquote>\n<p class=\"rights\">For example, an action method that gets a product based on an <code class=\"calibre9\">id<\/code> parameter will be decorated with three attributes&mdash;one to indicate that it responds to <code class=\"calibre9\">GET<\/code> requests and has an <code class=\"calibre9\">id<\/code> parameter and two to indicate what happens when it succeeds and when the client has supplied an invalid product ID, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[HttpGet(\"{id}\")]\n[ProducesResponseType(200, Type = typeof(Product))] \n[ProducesResponseType(404)]\npublic IActionResult Get(string id)<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">ControllerBase<\/code> class has methods to make it easy to return different responses, as shown in <em class=\"calibre10\">Table 15.4<\/em>:<\/p>\n<table class=\"calibre17\">\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Method<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Ok<\/code><\/td>\n<td class=\"calibre21\">Returns a <code class=\"calibre9\">200<\/code> status code and a resource converted into the client's preferred format, like JSON or XML. Commonly used in response to a <code class=\"calibre9\">GET<\/code> request.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">CreatedAtRoute<\/code><\/td>\n<td class=\"calibre21\">Returns a <code class=\"calibre9\">201<\/code> status code and the path to the new resource. Commonly used in response to a <code class=\"calibre9\">POST<\/code> request to create a resource that can be performed quickly.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">Accepted<\/code><\/td>\n<td class=\"calibre21\">Returns a <code class=\"calibre9\">202<\/code> status code to indicate the request is being processed but has not been completed. Commonly used in response to a <code class=\"calibre9\">POST<\/code> , <code class=\"calibre9\">PUT<\/code> , <code class=\"calibre9\">PATCH<\/code> , or <code class=\"calibre9\">DELETE<\/code> request that triggers a background process that takes a long time to complete.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">NoContentResult<\/code><\/td>\n<td class=\"calibre21\">Returns a <code class=\"calibre9\">204<\/code> status code and an empty response body. Commonly used in response to a <code class=\"calibre9\">PUT<\/code> , <code class=\"calibre9\">PATCH<\/code> , or <code class=\"calibre9\">DELETE<\/code> request when the response does not need to contain the affected resource.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">BadRequest<\/code><\/td>\n<td class=\"calibre21\">Returns a <code class=\"calibre9\">400<\/code> status code and an optional message string with more details.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">NotFound<\/code><\/td>\n<td class=\"calibre21\">Returns an <code class=\"calibre9\">e<\/code> status code and an automatically populates the <code class=\"calibre9\">ProblemDetails<\/code> body (requires a compatibility version of 2.2 or later).<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 15.4: ControllerBase helper methods that return a response<br \/>\n<\/section>\n<section data-number=\"16.3.8\" id=\"calibre_link-805\">\n<h3 data-number=\"16.3.8\" class=\"calibre8\">Configuring the customer repository and Web API controller<\/h3>\n<p class=\"rights\">Now that you've learned enough theory, you will put it into practice to configure the repository so that it can be called from within a Web API controller.You will register a scoped dependency service implementation for the repository when the web service starts up, and then use constructor parameter injection to get it in a new Web API controller for working with customers.It will have five action methods to perform CRUD operations on customers&mdash;two <code class=\"calibre9\">GET<\/code> methods (for all customers or one customer), <code class=\"calibre9\">POST<\/code> (create), <code class=\"calibre9\">PUT<\/code> (update), and <code class=\"calibre9\">DELETE<\/code>.To show an example of differentiating between MVC and Web API controllers using routes, we will use the common <code class=\"calibre9\">\/api<\/code> URL prefix convention for the customer controller:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, import the namespace for working with our customer repository, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.WebApi.Repositories; \/\/ To use ICustomerRepository.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, add a statement before the call to the <code class=\"calibre9\">Build<\/code> method, which will register the <code class=\"calibre9\">CustomerRepository<\/code> for use at runtime as a scoped dependency, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddScoped&lt;ICustomerRepository, CustomerRepository&gt;();<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Our repository uses a database context that is registered as a scoped dependency. You can only use scoped dependencies inside other scoped dependencies, so we cannot register the repository as a singleton. You can read more about this at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/extensions\/dependency-injection#scoped\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/extensions\/dependency-injection#scoped<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Controllers<\/code> folder, add a new class named <code class=\"calibre9\">CustomersController.cs<\/code>. If you are using Visual Studio 2022, then you can choose the <strong class=\"calibre2\">MVC Controller - Empty<\/strong> project item template.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">CustomersController.cs<\/code>, add statements to define a Web API controller class to work with customers, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ To use [Route], [ApiController], ControllerBase and so on.\nusing Microsoft.AspNetCore.Mvc;\nusing Northwind.EntityModels; \/\/ To use Customer.\nusing Northwind.WebApi.Repositories; \/\/ To use ICustomerRepository.\nnamespace Northwind.WebApi.Controllers;\n\/\/ Base address: api\/customers\n[Route(\"api\/[controller]\")]\n[ApiController]\npublic class CustomersController : ControllerBase\n{\n  private readonly ICustomerRepository _repo;\n  \/\/ Constructor injects repository registered in Program.cs.\n  public CustomersController(ICustomerRepository repo)\n  {\n    _repo = repo;\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">Controller<\/code> class registers a route using the <code class=\"calibre9\">[Route]<\/code> attribute that starts with <code class=\"calibre9\">api\/<\/code> and includes the name of the controller, that is, <code class=\"calibre9\">api\/customers<\/code>. The <code class=\"calibre9\">[controller]<\/code> part is automatically replaced with the class name with the <code class=\"calibre9\">Controller<\/code> suffix removed. Therefore, the base address of the route to the <code class=\"calibre9\">CustomersController<\/code> is <code class=\"calibre9\">api\/customers<\/code>. The constructor uses dependency injection to get the registered repository for working with customers.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">CustomersController.cs<\/code>, add statements to define an action method that responds to HTTP <code class=\"calibre9\">GET<\/code> requests for all customers, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ GET: api\/customers\n\/\/ GET: api\/customers\/?country=[country]\n\/\/ this will always return a list of customers (but it might be empty)\n[HttpGet]\n[ProducesResponseType(200, Type = typeof(IEnumerable&lt;Customer&gt;))]\npublic async Task&lt;IEnumerable&lt;Customer&gt;&gt; GetCustomers(string? country)\n{\n  if (string.IsNullOrWhiteSpace(country))\n  {\n    return await _repo.RetrieveAllAsync();\n  }\n  else\n  {\n    return (await _repo.RetrieveAllAsync())\n      .Where(customer =&gt; customer.Country == country);\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">GetCustomers<\/code> method can have a <code class=\"calibre9\">string<\/code> parameter passed with a country name. If it is missing, all customers are returned. If it is present, it is used to filter customers by country.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">CustomersController.cs<\/code>, add statements to define an action method that responds to HTTP <code class=\"calibre9\">GET<\/code> requests for an individual customer, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ GET: api\/customers\/[id]\n[HttpGet(\"{id}\", Name = nameof(GetCustomer))] \/\/ Named route.\n[ProducesResponseType(200, Type = typeof(Customer))]\n[ProducesResponseType(404)]\npublic async Task&lt;IActionResult&gt; GetCustomer(string id)\n{\n  Customer? c = await _repo.RetrieveAsync(id);\n  if (c == null)\n  {\n    return NotFound(); \/\/ 404 Resource not found.\n  }\n  return Ok(c); \/\/ 200 OK with customer in body\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">GetCustomer<\/code> method has a route explicitly named <code class=\"calibre9\">GetCustomer<\/code> so that it can be used to generate a URL after inserting a new customer.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">CustomersController.cs<\/code>, add statements to define an action method that responds to HTTP <code class=\"calibre9\">POST<\/code> requests to insert a new customer entity, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ POST: api\/customers\n\/\/ BODY: Customer (JSON, XML)\n[HttpPost]\n[ProducesResponseType(201, Type = typeof(Customer))]\n[ProducesResponseType(400)]\npublic async Task&lt;IActionResult&gt; Create([FromBody] Customer c)\n{\n  if (c == null)\n  {\n    return BadRequest(); \/\/ 400 Bad request.\n  }\n  Customer? addedCustomer = await _repo.CreateAsync(c);\n  if (addedCustomer == null)\n  {\n    return BadRequest(\"Repository failed to create customer.\");\n  }\n  else\n  {\n    return CreatedAtRoute( \/\/ 201 Created.\n      routeName: nameof(GetCustomer),\n      routeValues: new { id = addedCustomer.CustomerId.ToLower() },\n      value: addedCustomer);\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">CustomersController.cs<\/code>, add statements to define an action method that responds to HTTP <code class=\"calibre9\">PUT<\/code> requests, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ PUT: api\/customers\/[id]\n\/\/ BODY: Customer (JSON, XML)\n[HttpPut(\"{id}\")]\n[ProducesResponseType(204)]\n[ProducesResponseType(400)]\n[ProducesResponseType(404)]\npublic async Task&lt;IActionResult&gt; Update(\n  string id, [FromBody] Customer c)\n{\n  id = id.ToUpper();\n  c.CustomerId = c.CustomerId.ToUpper();\n  if (c == null || c.CustomerId != id)\n  {\n    return BadRequest(); \/\/ 400 Bad request.\n  }\n  Customer? existing = await _repo.RetrieveAsync(id);\n  if (existing == null)\n  {\n    return NotFound(); \/\/ 404 Resource not found.\n  }\n  await _repo.UpdateAsync(c);\n  return new NoContentResult(); \/\/ 204 No content.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The <code class=\"calibre9\">Create<\/code> and <code class=\"calibre9\">Update<\/code> methods both decorate the <code class=\"calibre9\">customer<\/code> parameter with <code class=\"calibre9\">[FromBody]<\/code> to tell the model binder to populate it with values from the body of the <code class=\"calibre9\">POST<\/code> request.<\/li>\n<li class=\"calibre3\">The <code class=\"calibre9\">Create<\/code> method returns a response that uses the <code class=\"calibre9\">GetCustomer<\/code> route so that the client knows how to get the newly created resource in the future. We are matching up two methods to create and then get a customer.<\/li>\n<li class=\"calibre3\">In the past, the <code class=\"calibre9\">Create<\/code> and <code class=\"calibre9\">Update<\/code> methods would need to check the model state of the customer passed in the body of the HTTP request. If it is invalid, they should return a <code class=\"calibre9\">400 Bad Request<\/code> containing details of the model validation errors. This happens automatically now because the controller is decorated with <code class=\"calibre9\">[ApiController]<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">CustomersController.cs<\/code>, add statements to define an action method that responds to HTTP <code class=\"calibre9\">DELETE<\/code> requests, as shown in the following code:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ DELETE: api\/customers\/[id]\n[HttpDelete(\"{id}\")]\n[ProducesResponseType(204)]\n[ProducesResponseType(400)]\n[ProducesResponseType(404)]\npublic async Task&lt;IActionResult&gt; Delete(string id)\n{\n  Customer? existing = await _repo.RetrieveAsync(id);\n  if (existing == null)\n  {\n    return NotFound(); \/\/ 404 Resource not found.\n  }\n  bool? deleted = await _repo.DeleteAsync(id);\n  if (deleted.HasValue &amp;&amp; deleted.Value) \/\/ Short circuit AND.\n  {\n    return new NoContentResult(); \/\/ 204 No content.\n  }\n  else\n  {\n    return BadRequest( \/\/ 400 Bad request.\n      $\"Customer {id} was found but failed to delete.\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Save all the changes.<\/li>\n<\/ol>\n<p class=\"rights\">When an HTTP request is received by the service, it will create an instance of the <code class=\"calibre9\">Controller<\/code> class, call the appropriate action method, return the response in the format preferred by the client, and release the resources used by the controller, including the repository and its data context.<\/p>\n<\/section>\n<section data-number=\"16.3.9\" id=\"calibre_link-806\">\n<h3 data-number=\"16.3.9\" class=\"calibre8\">Specifying problem details<\/h3>\n<p class=\"rights\">A feature added in ASP.NET Core 2.1 and later is an implementation of a web standard for specifying problem details. In Web API controllers decorated with <code class=\"calibre9\">[ApiController]<\/code> in a project where compatibility with ASP.NET Core 2.2 or later is enabled, action methods that return <code class=\"calibre9\">IActionResult<\/code> and return a client error status code, that is, <code class=\"calibre9\">4xx<\/code>, will automatically include a serialized instance of the <code class=\"calibre9\">ProblemDetails<\/code> class in the response body.If you want to take control, then you can create a <code class=\"calibre9\">ProblemDetails<\/code> instance yourself and include additional information.Let's simulate a bad request that needs custom data returned to the client:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">At the top of the implementation of the <code class=\"calibre9\">Delete<\/code> action method, add statements to check if the <code class=\"calibre9\">id<\/code> matches the literal string value <code class=\"calibre9\">\"bad\"<\/code>, and if so, then return a custom <code class=\"calibre9\">ProblemDetails<\/code> object, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Take control of problem details.\nif (id == \"bad\")\n{\n  ProblemDetails problemDetails = new()\n  {\n    Status = StatusCodes.Status400BadRequest,\n    Type = \"https:\/\/localhost:5151\/customers\/failed-to-delete\",\n    Title = $\"Customer ID {id} found but failed to delete.\",\n    Detail = \"More details like Company Name, Country and so on.\",\n    Instance = HttpContext.Request.Path\n  };\n  return BadRequest(problemDetails); \/\/ 400 Bad Request\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">You will test this functionality later.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"16.3.10\" id=\"calibre_link-807\">\n<h3 data-number=\"16.3.10\" class=\"calibre8\">Controlling XML serialization<\/h3>\n<p class=\"rights\">In <code class=\"calibre9\">Program.cs<\/code>, we added the <code class=\"calibre9\">XmlSerializer<\/code> so that our Web API service can return XML as well as JSON if the client requests that.However, the <code class=\"calibre9\">XmlSerializer<\/code> cannot serialize interfaces, and our entity classes use <code class=\"calibre9\">ICollection&lt;T&gt;<\/code> to define related child entities. This causes a warning at runtime, for example, for the <code class=\"calibre9\">Customer<\/code> class and its <code class=\"calibre9\">Orders<\/code> property, as shown in the following output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">warn: Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter[1]\nAn error occurred while trying to create an XmlSerializer for the type 'Northwind.EntityModels.Customer'.\nSystem.InvalidOperationException: There was an error reflecting type 'Northwind.EntityModels.Customer'.\n---&gt; System.InvalidOperationException: Cannot serialize member 'Northwind.EntityModels.Customer.Orders' of type 'System.Collections.Generic.ICollection`1[[Northwind.EntityModels.Order, Northwind.EntityModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]', see inner exception for more details.<\/code><\/pre>\n<\/div>\n<p class=\"rights\">We can prevent this warning by excluding the <code class=\"calibre9\">Orders<\/code> property when serializing a <code class=\"calibre9\">Customer<\/code> into XML:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.EntityModels.Sqlite<\/code> and <code class=\"calibre9\">Northwind.EntityModels.SqlServer<\/code> projects (if you created both), open <code class=\"calibre9\">Customer.cs<\/code>.<\/li>\n<li class=\"calibre3\">Import the namespace so that we can use the <code class=\"calibre9\">[XmlIgnore]<\/code> attribute, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Xml.Serialization; \/\/ To use [XmlIgnore].<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Decorate the <code class=\"calibre9\">Orders<\/code> property with an attribute to ignore it when serializing, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[InverseProperty(nameof(Order.Customer))]\n[XmlIgnore]\npublic virtual ICollection&lt;Order&gt; Orders { get; set; } = new List&lt;Order&gt;();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.EntityModels.SqlServer<\/code> project, in <code class=\"calibre9\">Customer.cs<\/code>, decorate the <code class=\"calibre9\">CustomerTypes<\/code> property with <code class=\"calibre9\">[XmlIgnore]<\/code> too, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[ForeignKey(\"CustomerId\")]\n[InverseProperty(\"Customers\")]\n[XmlIgnore]\npublic virtual ICollection&lt;CustomerDemographic&gt; CustomerTypes \n  { get; set; } = new List&lt;CustomerDemographic&gt;();<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"16.4\" id=\"calibre_link-808\">\n<h2 data-number=\"16.4\" class=\"calibre5\">Documenting and testing web services<\/h2>\n<p class=\"rights\">You can easily test a web service by making HTTP <code class=\"calibre9\">GET<\/code> requests using a browser. To test other HTTP methods, we need a more advanced tool.<\/p>\n<section data-number=\"16.4.1\" id=\"calibre_link-809\">\n<h3 data-number=\"16.4.1\" class=\"calibre8\">Testing GET requests using a browser<\/h3>\n<p class=\"rights\">You will use Chrome to test the three implementations of a <code class=\"calibre9\">GET<\/code> request&mdash;for all customers, for customers in a specified country, and for a single customer using their unique customer ID:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.WebApi<\/code> web service project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Start Chrome, navigate to <code class=\"calibre9\">https:\/\/localhost:5151\/api\/customers<\/code>, and note the JSON document returned, containing all 91 customers in the Northwind database (unsorted), as shown in <em class=\"calibre10\">Figure 15.2<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.2: Customers from the Northwind database as a JSON document\" height=\"331\" src=\"\/images\/cs12\/000025.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.2: Customers from the Northwind database as a JSON document<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Navigate to <code class=\"calibre9\">https:\/\/localhost:5151\/api\/customers?country=Germany<\/code> and note the JSON document returned, containing only the customers in Germany.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">If you get an empty array returned, then make sure you have entered the country name using the correct casing, because the database query is case-sensitive. For example, compare the results of <code class=\"calibre9\">uk<\/code> and <code class=\"calibre9\">UK<\/code>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Navigate to <code class=\"calibre9\">https:\/\/localhost:5151\/api\/customers\/alfki<\/code> and note the JSON document returned containing only the customer named <strong class=\"calibre2\">Alfreds Futterkiste<\/strong>.<\/li>\n<\/ol>\n<p class=\"rights\">Unlike country names, we do not need to worry about casing for the customer <code class=\"calibre9\">id<\/code> value because, in the customer repository implementation, we normalized the <code class=\"calibre9\">string<\/code> value as uppercase.But how can we test the other HTTP methods, such as <code class=\"calibre9\">POST<\/code>, <code class=\"calibre9\">PUT<\/code>, and <code class=\"calibre9\">DELETE<\/code>? And how can we document our web service so it's easy for anyone to understand how to interact with it?<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">There are many tools for testing Web APIs, for example, <strong class=\"calibre2\">Postman<\/strong>. Although Postman is popular, I prefer tools like <strong class=\"calibre2\">HTTP Editor<\/strong> in Visual Studio 2022 or <strong class=\"calibre2\">REST Client<\/strong> in Visual Studio Code because they do not hide what is happening. I feel Postman is too GUI-y. But I encourage you to explore different tools and find the ones that fit your style. You can learn more about Postman at the following link: <a href=\"https:\/\/www.postman.com\/\">https:\/\/www.postman.com\/<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">To solve the first problem, we can use the <strong class=\"calibre2\">HTTP Editor<\/strong> tool built into Visual Studio 2022 and install a Visual Studio Code extension named <strong class=\"calibre2\">REST Client<\/strong>. JetBrains Rider has its own equivalent. These are tools that allow you to send any type of HTTP request and view the response in your code editor.To solve the second problem, we can use <strong class=\"calibre2\">Swagger<\/strong>, the world's most popular technology for documenting and testing HTTP APIs. But first, let's see what is possible with the code editor HTTP\/REST tools.<\/p>\n<\/section>\n<section data-number=\"16.4.2\" id=\"calibre_link-810\">\n<h3 data-number=\"16.4.2\" class=\"calibre8\">Making GET requests using HTTP\/REST tools<\/h3>\n<p class=\"rights\">We will start by creating a file for testing <code class=\"calibre9\">GET<\/code> requests:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">If you have not already installed REST Client by Huachao Mao (<code class=\"calibre9\">humao.rest-client<\/code>), then install it in Visual Studio Code now.<\/li>\n<li class=\"calibre3\">In your preferred code editor, open the <code class=\"calibre9\">PracticalApps<\/code> solution and then start the <code class=\"calibre9\">Northwind.WebApi<\/code> project web service.<\/li>\n<li class=\"calibre3\">In <strong class=\"calibre2\">File Explorer<\/strong>, <strong class=\"calibre2\">Finder<\/strong>, or your favorite Linux file tool, in the <code class=\"calibre9\">PracticalApps<\/code> folder, create a <code class=\"calibre9\">HttpRequests<\/code> folder.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">HttpRequests<\/code> folder, create a file named <code class=\"calibre9\">get-customers.http<\/code>, and open it in your preferred code editor.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">get-customers.http<\/code>, modify its contents to contain an HTTP <code class=\"calibre9\">GET<\/code> request to retrieve all customers, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">### Configure a variable for the web service base address.\n@base_address = https:\/\/localhost:5151\/api\/customers\/\n### Make a GET request to the base address.\nGET {{base_address}}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Above the HTTP <code class=\"calibre9\">GET<\/code> request, click <strong class=\"calibre2\">Send request<\/strong>, as shown in <em class=\"calibre10\">Figure 15.3<\/em>.<\/li>\n<li class=\"calibre3\">Note the response is shown in a new tabbed window.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">If you are using Visual Studio 2022, then click the <strong class=\"calibre2\">Raw<\/strong> tab, and note the JSON that was returned, as shown in <em class=\"calibre10\">Figure 15.3<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.3: Sending an HTTP GET request using Visual Studio 2022\" height=\"983\" src=\"\/images\/cs12\/000050.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.3: Sending an HTTP GET request using Visual Studio 2022<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">HTTP Editor in Visual Studio 2022 is a new feature designed to add REST Client-like capabilities and its user interface is likely to evolve rapidly as it catches up. You can read its official documentation at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/test\/http-files\">https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/test\/http-files<\/a>.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">get-customers.http<\/code>, add more <code class=\"calibre9\">GET<\/code> requests, each separated by three hash symbols, to test getting customers in various countries and getting a single customer using their ID, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">### Get customers in Germany\nGET {{base_address}}?country=Germany\n### Get customers in USA in XML format\nGET {{base_address}}?country=USA\nAccept: application\/xml\n### Get Alfreds Futterkiste\nGET {{base_address}}ALFKI\n### Get a non-existant customer\nGET {{base_address}}abcxy<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Click the <strong class=\"calibre2\">Send Request<\/strong> link above each request to send it; for example, the <code class=\"calibre9\">GET<\/code> that has a request header to request customers in the USA as XML instead of JSON using the Visual Studio Code extension REST Client, as shown in <em class=\"calibre10\">Figure 15.4<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.4: Sending a request for XML and getting a response using REST Client\" height=\"593\" src=\"\/images\/cs12\/000119.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.4: Sending a request for XML and getting a response using REST Client<\/figcaption><\/figure>\n<\/section>\n<section data-number=\"16.4.3\" id=\"calibre_link-811\">\n<h3 data-number=\"16.4.3\" class=\"calibre8\">Making other requests using HTTP\/REST tools<\/h3>\n<p class=\"rights\">Next, we will create a file for testing other requests like <code class=\"calibre9\">POST<\/code>:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">HttpRequests<\/code> folder, create a file named <code class=\"calibre9\">create-customer.http<\/code> and modify its contents to define a <code class=\"calibre9\">POST<\/code> request to create a new customer, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">### Configure a variable for the web service base address.\n@base_address = https:\/\/localhost:5151\/api\/customers\/\n### Make a POST request to the base address.\nPOST {{base_address}}\nContent-Type: application\/json\n{\n  \"customerID\": \"ABCXY\",\n  \"companyName\": \"ABC Corp\",\n  \"contactName\": \"John Smith\",\n  \"contactTitle\": \"Sir\",\n  \"address\": \"Main Street\",\n  \"city\": \"New York\",\n  \"region\": \"NY\",\n  \"postalCode\": \"90210\",\n  \"country\":  \"USA\",\n  \"phone\": \"(123) 555-1234\"\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Send the request and note the response is <code class=\"calibre9\">201 Created<\/code>. Also note the location (that is, the URL) of the newly created customer is <code class=\"calibre9\">https:\/\/localhost:5151\/api\/Customers\/abcxy<\/code> and includes the newly created customer in the response body, as shown in <em class=\"calibre10\">Figure 15.5<\/em>:<\/li>\n<\/ol>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.5: Adding a new customer by POSTing to the Web API service\" height=\"505\" src=\"\/images\/cs12\/000075.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.5: Adding a new customer by POSTing to the Web API service<\/figcaption><\/figure>\n<p class=\"rights\">I will leave you an optional challenge to create <code class=\"calibre9\">.http<\/code> files that test updating a customer (using <code class=\"calibre9\">PUT<\/code>) and deleting a customer (using <code class=\"calibre9\">DELETE<\/code>). Try them on customers that do exist as well as customers that do not. Solutions are in the GitHub repository for this book at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/PracticalApps\/HttpRequests\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/PracticalApps\/HttpRequests<\/a><\/p>\n<\/section>\n<section data-number=\"16.4.4\" id=\"calibre_link-812\">\n<h3 data-number=\"16.4.4\" class=\"calibre8\">Passing environment variables<\/h3>\n<p class=\"rights\">To get an environment variable, use <code class=\"calibre9\">$processenv<\/code>, as shown in the following command:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{{$processEnv [%]envVarName}}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">For example, if you have set an environment variable to store a secret value like a password to connect to a SQL Server database that must be kept out of any files committed to a GitHub repository, you can use the following command:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{{$processEnv MY_SQL_PWD}}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">More Information<\/strong>: You can learn more about using environment variables with REST Client at the following link: <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=humao.rest-client#environments\">https:\/\/marketplace.visualstudio.com\/items?itemName=humao.rest-client#environments<\/a>. You can learn more about using environment variables and Secret Manager with HTTP Editor at the following link: <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/safely-use-secrets-in-http-requests-in-visual-studio-2022\/\">https:\/\/devblogs.microsoft.com\/visualstudio\/safely-use-secrets-in-http-requests-in-visual-studio-2022\/<\/a>.<\/p>\n<\/blockquote>\n<p class=\"rights\">Now that we've seen a quick and easy way to test our service, which also happens to be a great way to learn HTTP, what about external developers? We want it to be as easy as possible for them to learn and then call our service. For that purpose, we will use Swagger.<\/p>\n<\/section>\n<section data-number=\"16.4.5\" id=\"calibre_link-813\">\n<h3 data-number=\"16.4.5\" class=\"calibre8\">Understanding Swagger<\/h3>\n<p class=\"rights\">The most important part of Swagger is the <strong class=\"calibre2\">OpenAPI Specification<\/strong>, which defines a REST-style contract for your API, detailing all its resources and operations in a human- and machine-readable format for easy development, discovery, and integration.Developers can use the OpenAPI Specification for a Web API to automatically generate strongly typed client-side code in their preferred language or library.For us, another useful feature is <strong class=\"calibre2\">Swagger UI<\/strong>, because it automatically generates documentation for your API with built-in visual testing capabilities.Let's review how Swagger is enabled for our web service using the <code class=\"calibre9\">Swashbuckle<\/code> package:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">If the web service is running, shut down the web server.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Northwind.WebApi.csproj<\/code>, note the package reference for <code class=\"calibre9\">Swashbuckle.AspNetCore<\/code> that was added by the project template, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;PackageReference Include=\"Swashbuckle.AspNetCore\" Version=\"6.4.0\" \/&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, import Swashbuckle's <code class=\"calibre9\">SwaggerUI<\/code> namespace, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Swashbuckle.AspNetCore.SwaggerUI; \/\/ To use SubmitMethod.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, in the section for adding services to the container, note the services registered by the project template to use Swagger and the endpoints API explorer, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Learn more about configuring Swagger\/OpenAPI at https:\/\/aka.ms\/aspnetcore\/swashbuckle\nbuilder.Services.AddEndpointsApiExplorer();\nbuilder.Services.AddSwaggerGen();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the section that configures the HTTP request pipeline, note the statements for using Swagger and Swagger UI when in development mode, and define an endpoint for the OpenAPI Specification JSON document. Add code to explicitly list the HTTP methods that we want to support in our web service and change the endpoint name, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Configure the HTTP request pipeline.\nif (builder.Environment.IsDevelopment())\n{\n  app.UseSwagger(); \n  app.UseSwaggerUI(c =&gt;\n  {\n    c.SwaggerEndpoint(\"\/swagger\/v1\/swagger.json\",\n      \"Northwind Service API Version 1\");\n    c.SupportedSubmitMethods(new[] { \n      SubmitMethod.Get, SubmitMethod.Post,\n      SubmitMethod.Put, SubmitMethod.Delete });\n  });\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"16.4.6\" id=\"calibre_link-814\">\n<h3 data-number=\"16.4.6\" class=\"calibre8\">Testing requests with Swagger UI<\/h3>\n<p class=\"rights\">You are now ready to test an HTTP request using Swagger:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.WebApi<\/code> web service project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In Chrome, navigate to <code class=\"calibre9\">https:\/\/localhost:5151\/swagger<\/code> and note that both the <strong class=\"calibre2\">Customers<\/strong> and <strong class=\"calibre2\">WeatherForecast<\/strong> Web API controllers have been discovered and documented, as shown in <em class=\"calibre10\">Figure 15.6<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.6: Swagger documentation for the Northwind Web API service endpoints\" height=\"1071\" src=\"\/images\/cs12\/000059.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.6: Swagger documentation for the Northwind Web API service endpoints<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">GET \/api\/Customers\/{id}<\/strong> to expand that endpoint and note the required parameter for the <strong class=\"calibre2\">id<\/strong> of a customer.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Click <strong class=\"calibre2\">Try it out<\/strong>, enter an <strong class=\"calibre2\">id<\/strong> of <code class=\"calibre9\">ALFKI<\/code>, and then click the wide blue <strong class=\"calibre2\">Execute<\/strong> button, as shown in <em class=\"calibre10\">Figure 15.7<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.7: Inputting a customer ID before clicking the Execute button\" height=\"436\" src=\"\/images\/cs12\/000086.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.7: Inputting a customer ID before clicking the Execute button<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Scroll down and note the <strong class=\"calibre2\">Request URL<\/strong>, <strong class=\"calibre2\">Server response<\/strong> with <strong class=\"calibre2\">Code<\/strong>, and <strong class=\"calibre2\">Details<\/strong>, including <strong class=\"calibre2\">Response body<\/strong> and <strong class=\"calibre2\">Response headers<\/strong>, as shown in <em class=\"calibre10\">Figure 15.8<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.8: Information on ALFKI in a successful Swagger request\" height=\"309\" src=\"\/images\/cs12\/000043.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.8: Information on ALFKI in a successful Swagger request<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Scroll back up to the top of the page, click <strong class=\"calibre2\">POST \/api\/Customers<\/strong> to expand that section, and then click <strong class=\"calibre2\">Try it out<\/strong>.<\/li>\n<li class=\"calibre3\">Click inside the <strong class=\"calibre2\">Request body<\/strong> box and modify the JSON to define a new customer, as shown in the following JSON:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"customerID\": \"SUPER\",\n  \"companyName\": \"Super Company\",\n  \"contactName\": \"Rasmus Ibensen\",\n  \"contactTitle\": \"Sales Leader\",\n  \"address\": \"Rotterslef 23\",\n  \"city\": \"Billund\",\n  \"region\": null,\n  \"postalCode\": \"4371\",\n  \"country\": \"Denmark\",\n  \"phone\": \"31 21 43 21\",\n  \"fax\": \"31 21 43 22\"\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Click <strong class=\"calibre2\">Execute<\/strong>, and note the <strong class=\"calibre2\">Request URL<\/strong>, <strong class=\"calibre2\">Server response<\/strong> with <strong class=\"calibre2\">Code<\/strong>, and <strong class=\"calibre2\">Details<\/strong>, including <strong class=\"calibre2\">Response body<\/strong> and <strong class=\"calibre2\">Response headers<\/strong>, noting that a response code of <code class=\"calibre9\">201<\/code> means the customer was successfully created.<\/li>\n<li class=\"calibre3\">Scroll back up to the top of the page, click <strong class=\"calibre2\">GET \/api\/Customers<\/strong>, click <strong class=\"calibre2\">Try it out<\/strong>, enter <code class=\"calibre9\">Denmark<\/code> for the country parameter, and click <strong class=\"calibre2\">Execute<\/strong> to confirm that the new customer was added to the database.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">DELETE \/api\/Customers\/{id}<\/strong>, click <strong class=\"calibre2\">Try it out<\/strong>, enter <code class=\"calibre9\">super<\/code> for the <strong class=\"calibre2\">id<\/strong>, click <strong class=\"calibre2\">Execute<\/strong>, and note that the <strong class=\"calibre2\">Server response Code<\/strong> is <code class=\"calibre9\">204<\/code>, indicating that it was successfully deleted.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Click <strong class=\"calibre2\">Execute<\/strong> again and note that the <strong class=\"calibre2\">Server response Code<\/strong> is <code class=\"calibre9\">404<\/code>, indicating that the customer does not exist anymore, and that the <strong class=\"calibre2\">Response body<\/strong> contains a problem details JSON document, as shown in <em class=\"calibre10\">Figure 15.9<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.9: The deleted customer does not exist anymore\" height=\"844\" src=\"\/images\/cs12\/000101.png\" width=\"2161\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.9: The deleted customer does not exist anymore<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Enter <code class=\"calibre9\">bad<\/code> for the <strong class=\"calibre2\">id<\/strong>, click <strong class=\"calibre2\">Execute<\/strong> again, and note that the <strong class=\"calibre2\">Server response Code<\/strong> is <code class=\"calibre9\">400<\/code>, indicating that the customer did exist but failed to be deleted (in this case, because the web service is simulating this error) and the <strong class=\"calibre2\">Response body<\/strong> contains a custom problem details JSON document, as shown in <em class=\"calibre10\">Figure 15.10<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.10: The customer did exist but failed to be deleted\" height=\"662\" src=\"\/images\/cs12\/000143.png\" width=\"2161\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.10: The customer did exist but failed to be deleted<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You added the code to implement this in the section titled <em class=\"calibre10\">Specifying problem details<\/em>, where you checked for an <code class=\"calibre9\">id<\/code> of <code class=\"calibre9\">bad<\/code> and then returned a bad request with problem details.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Use the <code class=\"calibre9\">GET<\/code> methods to confirm that the new customer has been deleted from the database (there were originally only two customers in Denmark).<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">I will leave testing updates to an existing customer by using <code class=\"calibre9\">PUT<\/code> to the reader.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"16.4.7\" id=\"calibre_link-815\">\n<h3 data-number=\"16.4.7\" class=\"calibre8\">Enabling HTTP logging<\/h3>\n<p class=\"rights\">HTTP logging is an optional middleware component that is useful when testing a web service. It logs information about HTTP requests and HTTP responses including the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Information about the HTTP request<\/li>\n<li class=\"calibre3\">Headers<\/li>\n<li class=\"calibre3\">Body<\/li>\n<li class=\"calibre3\">Information about the HTTP response<\/li>\n<\/ul>\n<p class=\"rights\">This is valuable in web services for auditing and debugging scenarios but beware because it can negatively impact performance. You might also log <strong class=\"calibre2\">Personally Identifiable Information<\/strong> (<strong class=\"calibre2\">PII<\/strong>), which can cause compliance issues in some jurisdictions.Log levels can be set to the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Error<\/code>: Only <code class=\"calibre9\">Error<\/code> level logs.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Warning<\/code>: <code class=\"calibre9\">Error<\/code> and <code class=\"calibre9\">Warning<\/code> level logs.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Information<\/code>: <code class=\"calibre9\">Error<\/code>, <code class=\"calibre9\">Warning<\/code>, and <code class=\"calibre9\">Information<\/code> level logs.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Verbose<\/code>: All level logs.<\/li>\n<\/ul>\n<p class=\"rights\">Log levels can be set for the namespace in which the functionality is defined. Nested namespaces allow us to control which functionality has logging enabled:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Microsoft<\/code>: Include all log types in the <code class=\"calibre9\">Microsoft<\/code> namespace.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Microsoft.AspNetCore<\/code>: Include all log types in the <code class=\"calibre9\">Microsoft.AspNetCore<\/code> namespace.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">Microsoft.AspNetCore.HttpLogging<\/code>: Include all log types in the <code class=\"calibre9\">Microsoft.AspNetCore. HttpLogging<\/code> namespace.<\/li>\n<\/ul>\n<p class=\"rights\">Let's see HTTP logging in action:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">appsettings.Development.json<\/code>, add an entry to set the HTTP logging middleware to <code class=\"calibre9\">Information<\/code> level, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\",\n      \"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware\": \"Information\"\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Although the <code class=\"calibre9\">Default<\/code> log level might be set to <code class=\"calibre9\">Information<\/code>, more specific configurations take priority. For example, any logging systems in the <code class=\"calibre9\">Microsoft.AspNetCore<\/code> namespace will use the <code class=\"calibre9\">Warning<\/code> level. By making the change we did, any logging systems in the <code class=\"calibre9\">Microsoft.AspNetCore.<\/code> <code class=\"calibre9\">HttpLogging.HttpLoggingMiddleware<\/code> namespace will now use <code class=\"calibre9\">Information<\/code>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, import the namespace for working with HTTP logging, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.AspNetCore.HttpLogging; \/\/ To use HttpLoggingFields.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the services configuration section, after the call to <code class=\"calibre9\">WebApplication.CreateBuilder<\/code>, add a statement to configure HTTP logging, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddHttpLogging(options =&gt;\n{\n  options.LoggingFields = HttpLoggingFields.All;\n  options.RequestBodyLogLimit = 4096; \/\/ Default is 32k.\n  options.ResponseBodyLogLimit = 4096; \/\/ Default is 32k.\n});<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the HTTP pipeline configuration section, after the call to <code class=\"calibre9\">builder.Build<\/code>, add a statement to add HTTP logging before the call to use routing, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.UseHttpLogging();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.WebApi<\/code> web service using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Start Chrome and navigate to <code class=\"calibre9\">https:\/\/localhost:5151\/api\/customers<\/code>.<\/li>\n<li class=\"calibre3\">In a command prompt or terminal, note the request and response have been logged, as shown in the following partial output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]\n      Request:\n      Protocol: HTTP\/2\n      Method: GET\n      Scheme: https\n      PathBase:\n      Path: \/api\/customers\n      Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,*\/*;q=0.8,application\/signed-exchange;v=b3;q=0.7\n      Host: localhost:5151\n      User-Agent: Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/115.0.0.0 Safari\/537.36\n      Accept-Encoding: gzip, deflate, br\n      Accept-Language: en-US,en-GB;q=0.9,en;q=0.8,fr-FR;q=0.7,fr;q=0.6\n      Upgrade-Insecure-Requests: [Redacted]\n...\ninfo: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]\n      Response:\n      StatusCode: 200\n      Content-Type: application\/json; charset=utf-8\ninfo: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[4]\n      ResponseBody: [{\"customerId\":\"ALFKI\",\"companyName\":\"Alfreds Futterkiste\",\"contactName\":\"Maria Anders\",\"contactTitle\":\"Sales Representative\",\"address\":\"Obere Str. 57\",\"city\":\"Berlin\",\"region\":null,\"postalCode\":\"12209\",\"country\":\"Germany\",\"phone\":\"030-0074321\",\"fax\":\"030-0076545\",\"orders\":[]},...<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"16.4.8\" id=\"calibre_link-816\">\n<h3 data-number=\"16.4.8\" class=\"calibre8\">Support for logging additional request headers in W3CLogger<\/h3>\n<p class=\"rights\">W3CLogger is a middleware that writes logs in the W3C standard format. You can:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Record details of HTTP requests and responses.<\/li>\n<li class=\"calibre3\">Filter which headers and parts of the request and response messages are logged.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Warning!<\/strong> W3CLogger can reduce the performance of an app.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">W3CLogger is like HTTP logging so I will not cover details of how to use it in this book. You can learn more about W3CLogger at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/w3c-logger\/\">https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/w3c-logger\/<\/a>.<\/p>\n<\/blockquote>\n<\/blockquote>\n<p class=\"rights\">In ASP.NET Core 7 or later, you can specify that you want to log additional request headers when using W3CLogger. Call the <code class=\"calibre9\">AdditionalRequestHeaders<\/code> method and pass the name of the header you want to log, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">services.AddW3CLogging(options =&gt;\n{\n    options.AdditionalRequestHeaders.Add(\"x-forwarded-for\");\n    options.AdditionalRequestHeaders.Add(\"x-client-ssl-protocol\");\n});<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You are now ready to build applications that consume your web service.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"16.5\" id=\"calibre_link-817\">\n<h2 data-number=\"16.5\" class=\"calibre5\">Consuming web services using HTTP clients<\/h2>\n<p class=\"rights\">Now that we have built and tested our Northwind service, we will learn how to call it from any .NET app using the <code class=\"calibre9\">HttpClient<\/code> class and its factory.<\/p>\n<section data-number=\"16.5.1\" id=\"calibre_link-818\">\n<h3 data-number=\"16.5.1\" class=\"calibre8\">Understanding HttpClient<\/h3>\n<p class=\"rights\">The easiest way to consume a web service is to use the <code class=\"calibre9\">HttpClient<\/code> class. However, many people use it wrongly because it implements <code class=\"calibre9\">IDisposable<\/code> and Microsoft's own documentation shows poor usage of it. See the book links in the GitHub repository for articles with more discussion of this.Usually, when a type implements <code class=\"calibre9\">IDisposable<\/code>, you should create it inside a <code class=\"calibre9\">using<\/code> statement to ensure that it is disposed of as soon as possible. <code class=\"calibre9\">HttpClient<\/code> is different because it is shared, reentrant, and partially thread-safe.The problem has to do with how the underlying network sockets must be managed. The bottom line is that you should use a single instance of it for each HTTP endpoint that you consume during the life of your application. This will allow each <code class=\"calibre9\">HttpClient<\/code> instance to have defaults set that are appropriate for the endpoint it works with while managing the underlying network sockets efficiently.<\/p>\n<\/section>\n<section data-number=\"16.5.2\" id=\"calibre_link-819\">\n<h3 data-number=\"16.5.2\" class=\"calibre8\">Configuring HTTP clients using HttpClientFactory<\/h3>\n<p class=\"rights\">Microsoft is aware of the issue of .NET developers misusing <code class=\"calibre9\">HttpClient<\/code>, and in ASP.NET Core 2.1, it introduced <code class=\"calibre9\">HttpClientFactory<\/code> to encourage best practices; that is the technique we will use.In the following example, we will use the Northwind MVC website as a client for the Northwind Web API service. Let's configure an HTTP client:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Mvc<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, import the namespace for setting a media type header value, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using System.Net.Http.Headers; \/\/ To use MediaTypeWithQualityHeaderValue.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Mvc<\/code> project, in <code class=\"calibre9\">Program.cs<\/code>, before calling the <code class=\"calibre9\">Build<\/code> method, add a statement to enable <code class=\"calibre9\">HttpClientFactory<\/code> with a named client to make calls to the Northwind Web API service using HTTPS on port <code class=\"calibre9\">5151<\/code> and request JSON as the default response format, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddHttpClient(name: \"Northwind.WebApi\",\n  configureClient: options =&gt;\n  {\n    options.BaseAddress = new Uri(\"https:\/\/localhost:5151\/\");\n    options.DefaultRequestHeaders.Accept.Add(\n      new MediaTypeWithQualityHeaderValue(\n      mediaType: \"application\/json\", quality: 1.0));\n  });<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"16.5.3\" id=\"calibre_link-820\">\n<h3 data-number=\"16.5.3\" class=\"calibre8\">Getting customers as JSON in the controller<\/h3>\n<p class=\"rights\">We can now create an MVC controller action method that:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Uses the factory to create an HTTP client.<\/li>\n<li class=\"calibre3\">Makes a <code class=\"calibre9\">GET<\/code> request for customers.<\/li>\n<li class=\"calibre3\">Deserializes the JSON response using convenient extension methods introduced with .NET 5 in the <code class=\"calibre9\">System.Net.Http.Json<\/code> assembly and namespace.<\/li>\n<\/ul>\n<p class=\"rights\">Let's go:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Mvc<\/code> project, in the <code class=\"calibre9\">Controllers<\/code> folder, in <code class=\"calibre9\">HomeController.cs<\/code>, declare a field for storing the HTTP client factory, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private readonly IHttpClientFactory _clientFactory;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Set the field in the constructor, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public HomeController(\n  ILogger&lt;HomeController&gt; logger,\n  NorthwindContext db,\n  IHttpClientFactory httpClientFactory)\n{\n  _logger = logger;\n  _db = db;\n  _clientFactory = httpClientFactory;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Create a new action method for calling the Northwind Web API service, fetching all customers, and passing them to a view, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public async Task&lt;IActionResult&gt; Customers(string country)\n{\n  string uri;\n  if (string.IsNullOrEmpty(country))\n  {\n    ViewData[\"Title\"] = \"All Customers Worldwide\";\n    uri = \"api\/customers\";\n  }\n  else\n  {\n    ViewData[\"Title\"] = $\"Customers in {country}\";\n    uri = $\"api\/customers\/?country={country}\";\n  }\n  HttpClient client = _clientFactory.CreateClient(\n    name: \"Northwind.WebApi\");\n  HttpRequestMessage request = new(\n    method: HttpMethod.Get, requestUri: uri);\n  HttpResponseMessage response = await client.SendAsync(request);\n  IEnumerable&lt;Customer&gt;? model = await response.Content\n    .ReadFromJsonAsync&lt;IEnumerable&lt;Customer&gt;&gt;();\n  return View(model);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Views\/Home<\/code> folder, create a Razor file named <code class=\"calibre9\">Customers.cshtml<\/code>.<\/li>\n<li class=\"calibre3\">Modify the Razor file to render the customers, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@using Northwind.EntityModels\n@model IEnumerable&lt;Customer&gt;\n&lt;h2&gt;@ViewData[\"Title\"]&lt;\/h2&gt;\n&lt;table class=\"table\"&gt;\n  &lt;thead&gt;\n    &lt;tr&gt;\n      &lt;th&gt;Company Name&lt;\/th&gt;\n      &lt;th&gt;Contact Name&lt;\/th&gt;\n      &lt;th&gt;Address&lt;\/th&gt;\n      &lt;th&gt;Phone&lt;\/th&gt;\n    &lt;\/tr&gt;\n  &lt;\/thead&gt;\n  &lt;tbody&gt;\n    @if (Model is not null)\n    {\n      @foreach (Customer c in Model)\n      {\n        &lt;tr&gt;\n          &lt;td&gt;\n            @Html.DisplayFor(modelItem =&gt; c.CompanyName)\n          &lt;\/td&gt;\n          &lt;td&gt;\n            @Html.DisplayFor(modelItem =&gt; c.ContactName)\n          &lt;\/td&gt;\n          &lt;td&gt;\n            @Html.DisplayFor(modelItem =&gt; c.Address) \n            @Html.DisplayFor(modelItem =&gt; c.City)\n            @Html.DisplayFor(modelItem =&gt; c.Region)\n            @Html.DisplayFor(modelItem =&gt; c.Country) \n            @Html.DisplayFor(modelItem =&gt; c.PostalCode)\n          &lt;\/td&gt;\n          &lt;td&gt;\n            @Html.DisplayFor(modelItem =&gt; c.Phone)\n          &lt;\/td&gt;\n        &lt;\/tr&gt;\n      }\n    }\n  &lt;\/tbody&gt;\n&lt;\/table&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Views\/Home<\/code> folder, in <code class=\"calibre9\">Index.cshtml<\/code>, add a form after rendering the visitor count to allow visitors to enter a country and see the customers, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;h3&gt;Query customers from a service&lt;\/h3&gt;\n&lt;form asp-action=\"Customers\" method=\"get\"&gt;\n  &lt;input name=\"country\" placeholder=\"Enter a country\" \/&gt;\n  &lt;input type=\"submit\" \/&gt;\n&lt;\/form&gt;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"16.5.4\" id=\"calibre_link-821\">\n<h3 data-number=\"16.5.4\" class=\"calibre8\">Starting multiple projects<\/h3>\n<p class=\"rights\">Up to this point, we have only started one project at a time. Now we have two projects that need to be started, a web service and an MVC client website. In the step-by-step instructions, I will only tell you to start individual projects one at a time, but you should use whatever technique you prefer to start them.<\/p>\n<section data-number=\"16.5.4.1\" id=\"calibre_link-1942\">\n<h4 data-number=\"16.5.4.1\" class=\"calibre15\">If you are using Visual Studio 2022<\/h4>\n<p class=\"rights\">Visual Studio 2022 can start multiple projects manually one by one if the debugger is not attached, as described in the following steps:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, right-click on the solution or any project and then select <strong class=\"calibre2\">Configure Startup Projects\u2026<\/strong>, or select the solution and navigate to <strong class=\"calibre2\">Project<\/strong> | <strong class=\"calibre2\">Configure Startup Projects\u2026<\/strong>.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Solution '&lt;name&gt;' Property Pages<\/strong> dialog box, select <strong class=\"calibre2\">Current selection<\/strong>.<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<li class=\"calibre3\">Select a project in <strong class=\"calibre2\">Solution Explorer<\/strong> so that its name becomes bold.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Without Debugging<\/strong> or press <span>Ctrl<\/span> + <span>F5<\/span>.<\/li>\n<li class=\"calibre3\">Repeat <em class=\"calibre10\">steps 2<\/em> and <em class=\"calibre10\">3<\/em> for as many projects as you need.<\/li>\n<\/ol>\n<p class=\"rights\">If you need to debug the projects, then you must start multiple instances of Visual Studio 2022. Each instance can start a single project with debugging.You can also configure multiple projects to start up at the same time using the following steps:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <strong class=\"calibre2\">Solution Explorer<\/strong>, right-click the solution or any project and then select <strong class=\"calibre2\">Configure Startup Projects\u2026<\/strong>, or select the solution and navigate to <strong class=\"calibre2\">Project<\/strong> | <strong class=\"calibre2\">Configure Startup Projects\u2026<\/strong>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the <strong class=\"calibre2\">Solution '&lt;name&gt;' Property Pages<\/strong> dialog box, select <strong class=\"calibre2\">Multiple startup projects<\/strong>, and for any projects that you want to start, select either <strong class=\"calibre2\">Start<\/strong> or <strong class=\"calibre2\">Start without debugging<\/strong>, as shown in <em class=\"calibre10\">Figure 15.11<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.11: Selecting multiple projects to start up in Visual Studio 2022\" height=\"1113\" src=\"\/images\/cs12\/000159.png\" width=\"2160\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.11: Selecting multiple projects to start up in Visual Studio 2022<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Click <strong class=\"calibre2\">OK<\/strong>.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Debugging<\/strong> or <strong class=\"calibre2\">Debug<\/strong> | <strong class=\"calibre2\">Start Without Debugging<\/strong> or click the equivalent buttons in the toolbar to start all the projects that you selected.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can learn more about multi-project start-up using Visual Studio 2022 at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/visualstudio\/ide\/how-to-set-multiple-startup-projects\">https:\/\/learn.microsoft.com\/en-us\/visualstudio\/ide\/how-to-set-multiple-startup-projects<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"16.5.4.2\" id=\"calibre_link-1943\">\n<h4 data-number=\"16.5.4.2\" class=\"calibre15\">If you are using Visual Studio Code<\/h4>\n<p class=\"rights\">If you need to start multiple projects at the command line with <code class=\"calibre9\">dotnet<\/code>, then write a script or batch file to execute multiple <code class=\"calibre9\">dotnet run<\/code> commands, or open multiple command prompt or terminal windows.If you need to debug multiple projects using Visual Studio Code, then after you've started the first debug session, you can just launch another session. Once the second session is running, the user interface switches to multi-target mode. For example, in the <strong class=\"calibre2\">CALL STACK<\/strong>, you will see both named projects with their own threads, and then the debug toolbar shows a drop-down list of sessions with the active one selected. Alternatively, you can define compound launch configurations in the <code class=\"calibre9\">launch.json<\/code>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can learn more about multi-target debugging using Visual Studio Code at the following link: <a href=\"https:\/\/code.visualstudio.com\/Docs\/editor\/debugging#_multitarget-debugging\">https:\/\/code.visualstudio.com\/Docs\/editor\/debugging#_multitarget-debugging<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"16.5.5\" id=\"calibre_link-822\">\n<h3 data-number=\"16.5.5\" class=\"calibre8\">Starting the web service and MVC client projects<\/h3>\n<p class=\"rights\">Now we can try out the web service with the MVC client calling it:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.WebApi<\/code> project and confirm that the web service is listening on ports <code class=\"calibre9\">5151<\/code> and <code class=\"calibre9\">5150<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">info: Microsoft.Hosting.Lifetime[14]\n  Now listening on: https:\/\/localhost:5151\ninfo: Microsoft.Hosting.Lifetime[14]\n  Now listening on: http:\/\/localhost:5150<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Mvc<\/code> project and confirm that the website is listening on ports <code class=\"calibre9\">5141<\/code> and <code class=\"calibre9\">5140<\/code>, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">info: Microsoft.Hosting.Lifetime[14]\n  Now listening on: https:\/\/localhost:5141\ninfo: Microsoft.Hosting.Lifetime[14]\n  Now listening on: http:\/\/localhost:5140<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start Chrome and navigate to <code class=\"calibre9\">https:\/\/localhost:5141\/<\/code>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">On the home page, in the customer form, enter a country like <code class=\"calibre9\">Germany<\/code>, <code class=\"calibre9\">UK<\/code>, or <code class=\"calibre9\">USA<\/code>, click <strong class=\"calibre2\">Submit<\/strong>, and note the list of customers, as shown in <em class=\"calibre10\">Figure 15.12<\/em> for the UK:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 15.12: Customers in the UK\" height=\"492\" src=\"\/images\/cs12\/000049.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 15.12: Customers in the UK<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Click the <strong class=\"calibre2\">Back<\/strong> button in your browser, clear the <strong class=\"calibre2\">Country<\/strong> textbox, click <strong class=\"calibre2\">Submit<\/strong>, and note the worldwide list of customers.<\/li>\n<li class=\"calibre3\">In a command prompt or terminal, note that the <code class=\"calibre9\">HttpClient<\/code> writes each HTTP request that it makes and each HTTP response that it receives, as shown in the following output:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">info: System.Net.Http.HttpClient.Northwind.WebApi.ClientHandler[100]\n  Sending HTTP request GET https:\/\/localhost:5151\/api\/customers\/?country=UK\ninfo: System.Net.Http.HttpClient.Northwind.WebApi.ClientHandler[101]\n  Received HTTP response headers after 931.864ms - 200<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Close Chrome and shut down the two web servers.<\/li>\n<\/ol>\n<\/section>\n<\/section>\n<section data-number=\"16.6\" id=\"calibre_link-823\">\n<h2 data-number=\"16.6\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring this chapter's topics with deeper research.<\/p>\n<section data-number=\"16.6.1\" id=\"calibre_link-824\">\n<h3 data-number=\"16.6.1\" class=\"calibre8\">Exercise 15.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Which class should you inherit from to create a controller class for an ASP.NET Core Web API service?<\/li>\n<li class=\"calibre3\">When configuring an HTTP client, how do you specify the format of data that you prefer in the response from the web service?<\/li>\n<li class=\"calibre3\">What must you do to specify which controller action method will be executed in response to an HTTP request?<\/li>\n<li class=\"calibre3\">What must you do to specify what responses should be expected when calling an action method?<\/li>\n<li class=\"calibre3\">List three methods that can be called to return responses with different status codes.<\/li>\n<li class=\"calibre3\">List four ways that you can test a web service.<\/li>\n<li class=\"calibre3\">Why should you not wrap your use of <code class=\"calibre9\">HttpClient<\/code> in a <code class=\"calibre9\">using<\/code> statement to dispose of it when you are finished even though it implements the <code class=\"calibre9\">IDisposable<\/code> interface, and what should you use instead?<\/li>\n<li class=\"calibre3\">What are the benefits of HTTP\/2 and HTTP\/3 compared to HTTP\/1.1?<\/li>\n<li class=\"calibre3\">How can you enable clients to detect if your web service is healthy with ASP.NET Core 2.2 and later?<\/li>\n<li class=\"calibre3\">What benefits does endpoint routing provide?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"16.6.2\" id=\"calibre_link-825\">\n<h3 data-number=\"16.6.2\" class=\"calibre8\">Exercise 15.2 &ndash; Practice creating and deleting customers with HttpClient<\/h3>\n<p class=\"rights\">Extend the <code class=\"calibre9\">Northwind.Mvc<\/code> website project to have pages where a visitor can fill in a form to create a new customer, or search for a customer and then delete them. The MVC controller should make calls to the Northwind web service to create and delete customers.<\/p>\n<\/section>\n<section data-number=\"16.6.3\" id=\"calibre_link-826\">\n<h3 data-number=\"16.6.3\" class=\"calibre8\">Exercise 15.3 &ndash; Implementing advanced features for web services<\/h3>\n<p class=\"rights\">If you would like to learn about web service health checks, Open API analyzers, adding security HTTP headers, and enabling HTTP\/3 support for <code class=\"calibre9\">HttpClient<\/code>, then you can read the optional online-only section at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch15-advanced.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch15-advanced.md<\/a><\/p>\n<\/section>\n<section data-number=\"16.6.4\" id=\"calibre_link-827\">\n<h3 data-number=\"16.6.4\" class=\"calibre8\">Exercise 15.4 &ndash; Building web services using Minimal APIs<\/h3>\n<p class=\"rights\">If you would like to learn how to build web services using Minimal APIs, then you can read the optional online-only section at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch15-minimal-apis.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch15-minimal-apis.md<\/a><\/p>\n<\/section>\n<section data-number=\"16.6.5\" id=\"calibre_link-828\">\n<h3 data-number=\"16.6.5\" class=\"calibre8\">Exercise 15.5 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links in the following GitHub repository to learn more details about the topics covered in this chapter:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-15---building-and-consuming-web-services\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-15---building-and-consuming-web-services<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"16.7\" id=\"calibre_link-829\">\n<h2 data-number=\"16.7\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">How to build an ASP.NET Core Web API service that can be called by any app on any platform that can make an HTTP request and process an HTTP response.<\/li>\n<li class=\"calibre3\">How to test and document web service APIs with Swagger.<\/li>\n<li class=\"calibre3\">How to consume services efficiently.<\/li>\n<li class=\"calibre3\">How to build a basic HTTP API service using Minimal APIs.<\/li>\n<\/ul>\n<p class=\"rights\">In the next chapter, you will learn how to build user interfaces using Blazor, Microsoft's component technology that enables developers to build client-side SPAs for websites using C# instead of JavaScript, and PWAs or hybrid apps for desktop.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-4\">\n<div id=\"calibre_link-1944\" class=\"calibre1\">\n<section data-number=\"17\" id=\"calibre_link-830\">\n<h1 data-number=\"17\" class=\"title\">16 Building User Interfaces Using Blazor<\/h1>\n<section data-number=\"17.1\" id=\"calibre_link-831\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"17.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000018.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This chapter is about using Blazor to build user interfaces. You will learn how to build Blazor components that can execute their C# and .NET code on the web server or in the web browser. When components execute on the server, Blazor uses SignalR to communicate needed updates to the user interface in the browser. When components execute in the browser using WebAssembly, they must make HTTP calls to interact with data on the server.In this chapter, we will cover the following topics:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">History of Blazor<\/li>\n<li class=\"calibre3\">Reviewing the Blazor Web App project template<\/li>\n<li class=\"calibre3\">Building components using Blazor<\/li>\n<li class=\"calibre3\">Enabling client-side execution using WebAssembly<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"17.2\" id=\"calibre_link-832\">\n<h2 data-number=\"17.2\" class=\"calibre5\">History of Blazor<\/h2>\n<p class=\"rights\">Blazor lets you build interactive web user interface components using C# instead of JavaScript. Blazor is supported on all modern browsers.<\/p>\n<section data-number=\"17.2.1\" id=\"calibre_link-833\">\n<h3 data-number=\"17.2.1\" class=\"calibre8\">JavaScript and friends<\/h3>\n<p class=\"rights\">Traditionally, any code that needs to be executed in a web browser must be written using the JavaScript programming language or a higher-level technology that <strong class=\"calibre2\">transpiles<\/strong> (transforms or compiles) into JavaScript. This is because all browsers have supported JavaScript for over two decades, so it is the lowest common denominator for implementing business logic in the client.JavaScript does have some issues, however. Although it has superficial similarities to C-style languages like C# and Java, it is actually very different once you dig beneath the surface. It is a dynamically typed pseudo-functional language that uses prototypes instead of class inheritance for object reuse. It might look human, but you will get a surprise when it's revealed to be a Skrull.It'd be great if we could use the same language and libraries in a browser as we do on the server.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Even Blazor cannot replace JavaScript completely. For example, some parts of the browser are only accessible to JavaScript. Blazor provides an interop service so that your C# code can call JavaScript code and vice versa. You will see this in the online-only <em class=\"calibre10\">Interop with JavaScript<\/em> section.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"17.2.2\" id=\"calibre_link-834\">\n<h3 data-number=\"17.2.2\" class=\"calibre8\">Silverlight &ndash; C# and .NET using a plugin<\/h3>\n<p class=\"rights\">Microsoft made a previous attempt at achieving this goal with a technology named Silverlight. When Silverlight 2 was released in 2008, a C# and .NET developer could use their skills to build libraries and visual components that were executed in the web browser by the Silverlight plugin.By 2011 and Silverlight 5, Apple's success with the iPhone and Steve Jobs' hatred of browser plugins like Flash eventually led to Microsoft abandoning Silverlight since, like Flash, Silverlight is banned from iPhones and iPads.<\/p>\n<\/section>\n<section data-number=\"17.2.3\" id=\"calibre_link-835\">\n<h3 data-number=\"17.2.3\" class=\"calibre8\">WebAssembly &ndash; a target for Blazor<\/h3>\n<p class=\"rights\">Another development in web browsers has given Microsoft the opportunity to make another attempt. In 2017, the <strong class=\"calibre2\">WebAssembly Consensus<\/strong> was completed, and all major browsers now support it: Chromium (Chrome, Edge, Opera, and Brave), Firefox, and WebKit (Safari).<strong class=\"calibre2\">WebAssembly<\/strong> (<strong class=\"calibre2\">Wasm<\/strong>) is a binary instruction format for a virtual machine that provides a way to run code written in multiple languages on the web at near-native speed. Wasm is designed as a portable target for the compilation of high-level languages like C#.Although Blazor is supported on Internet Explorer 11 if the components run on the server, they cannot run on the client because Internet Explorer 11 does not support WebAssembly.<\/p>\n<\/section>\n<section data-number=\"17.2.4\" id=\"calibre_link-836\">\n<h3 data-number=\"17.2.4\" class=\"calibre8\">Blazor hosting models in .NET 7 and earlier<\/h3>\n<p class=\"rights\">Blazor is a single programming or app model. For .NET 7 and earlier, a developer had to choose one hosting model for each project:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A <strong class=\"calibre2\">Blazor Server<\/strong> project runs on the server side, so the C# code has full access to all resources that your business logic might need without needing to supply credentials to authenticate. It uses SignalR to communicate user interface updates to the client side. The server must keep a live SignalR connection to each client and track the current state of every client. This means that Blazor Server does not scale well if you need to support lots of clients. It first shipped as part of ASP.NET Core 3 in September 2019.<\/li>\n<li class=\"calibre3\">A <strong class=\"calibre2\">Blazor WebAssembly<\/strong> project runs on the client side, so the C# code only has access to resources in the browser. It must make HTTP calls (that might require authentication) before it can access resources on the server. It first shipped as an extension to ASP.NET Core 3.1 in May 2020 and was versioned 3.2 because it was a current release and therefore not covered by ASP.NET Core 3.1's Long Term Support. The Blazor WebAssembly 3.2 version used the Mono runtime and Mono libraries. .NET 5 and later use the Mono runtime and the .NET libraries.<\/li>\n<li class=\"calibre3\">A <strong class=\"calibre2\">.NET MAUI Blazor App<\/strong>, aka <strong class=\"calibre2\">Blazor Hybrid<\/strong>, project renders its web UI to a web view control using a local interop channel and is hosted in a .NET MAUI app. It is conceptually like an Electron app.<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"17.2.5\" id=\"calibre_link-837\">\n<h3 data-number=\"17.2.5\" class=\"calibre8\">Unification of Blazor hosting models in .NET 8<\/h3>\n<p class=\"rights\">With .NET 8, the Blazor team has created a unified hosting model where each individual component can be set to execute using a different rendering model:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Server-Side Rendering (SSR)<\/strong>: Executes code on the server side like Razor Pages and MVC do. The complete response is then sent to the browser for display to the visitor and there is no further interaction between server and client until the browser makes a new HTTP request.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Streaming Rendering<\/strong>: Executes code on the server side, HTML markup can be returned and display in the browser, and while the connection is still open, any asynchronous operations can continue to execute. When all asynchronous operations are complete, the final markup is sent by the server to update the contents of the page. This improves the experience for the visitor because they see some content like a \"Loading\u2026\" message while waiting for the rest.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Interactive Server Rendering<\/strong>: Executes code on the server side during live interactions, which means the code has full and easy access to server-side resources like databases. This can simplify implementing functionality. Interactive requests are made using SignalR, which is more efficient than a full request. A permanent connection is needed between the browser and server, which limits scalability. A good choice for intranet websites where there are a limited number of clients and high bandwidth networking.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Interactive WebAssembly Rendering<\/strong>: Executes code on the client side, which means the code only has access to resources within the browser. This can complicate the implementation because a callback to the server must be made whenever new data is required. A good choice for public websites where there are potentially a large number of clients and low bandwidth connections for some of them.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Interactive Automatic Rendering<\/strong>: Starts by rendering on the server for faster initial display, downloads WebAssembly components in the background, and then switches to WebAssembly for subsequent interactivity.<\/li>\n<\/ul>\n<p class=\"rights\">This unified model means that, with careful planning, a developer can write Blazor components once and then choose to run them on the web server side, or the web client side, or dynamically switch. This gives the best of all worlds.In .NET 8, any Blazor WebAssembly components must still be defined in a separate project. This might change in .NET 9 or later.<\/p>\n<\/section>\n<section data-number=\"17.2.6\" id=\"calibre_link-838\">\n<h3 data-number=\"17.2.6\" class=\"calibre8\">Understanding Blazor components<\/h3>\n<p class=\"rights\">It is important to understand that Blazor is used to create <strong class=\"calibre2\">user interface components<\/strong>. Components define how to render the user interface and react to user events, and can be composed and nested, and compiled into a Razor class library for packaging and distribution.For example, to provide a user interface for star ratings of products on a commerce site, you might create a component named <code class=\"calibre9\">Rating.razor<\/code>, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;div&gt;\n@for (int i = 0; i &lt; Maximum; i++)\n{\n  if (i &lt; Value)\n  {\n    &lt;span class=\"oi oi-star-filled\" \/&gt;\n  }\n  else\n  {\n    &lt;span class=\"oi oi-star-empty\" \/&gt;\n  }\n}\n&lt;\/div&gt;\n@code {\n  [Parameter]\n  public byte Maximum { get; set; }\n  [Parameter]\n  public byte Value { get; set; }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">You could then use the component on a web page, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;h1&gt;Review&lt;\/h1&gt;\n&lt;Rating id=\"rating\" Maximum=\"5\" Value=\"3\" \/&gt;\n&lt;textarea id=\"comment\" \/&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The markup for creating an instance of a component looks like an HTML tag where the name of the tag is the component type. Components can be embedded in a web page using an element, for example, <code class=\"calibre9\">&lt;Rating Value=\"5\" \/&gt;<\/code>, or they can be routed to, like a Razor Page or MVC controller.Instead of a single file with both markup and an <code class=\"calibre9\">@code<\/code> block, the code can be stored in a separate code-behind file named <code class=\"calibre9\">Rating.razor.cs<\/code>. The class in this file must be <code class=\"calibre9\">partial<\/code> and have the same name as the component.There are many built-in Blazor components, including ones to set elements like <code class=\"calibre9\">&lt;title&gt;<\/code> in the <code class=\"calibre9\">&lt;head&gt;<\/code> section of a web page, and plenty of third parties who will sell you components for common purposes.<\/p>\n<\/section>\n<section data-number=\"17.2.7\" id=\"calibre_link-839\">\n<h3 data-number=\"17.2.7\" class=\"calibre8\">What is the difference between Blazor and Razor?<\/h3>\n<p class=\"rights\">You might wonder why Blazor components use <code class=\"calibre9\">.razor<\/code> as their file extension. Razor is a template markup syntax that allows the mixing of HTML and C#. Older technologies that support Razor syntax use the <code class=\"calibre9\">.cshtml<\/code> file extension to indicate the mix of C# and HTML.Razor syntax is used for:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">ASP.NET Core MVC <strong class=\"calibre2\">views<\/strong> and <strong class=\"calibre2\">partial views<\/strong> that use the <code class=\"calibre9\">.cshtml<\/code> file extension. The business logic is separated into a controller class that treats the view as a template to push the view model to, which then outputs it to a web page.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Razor Pages<\/strong> that use the <code class=\"calibre9\">.cshtml<\/code> file extension. The business logic can be embedded or separated into a file that uses the <code class=\"calibre9\">.cshtml.cs<\/code> file extension. The output is a web page.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Blazor components<\/strong> that use the <code class=\"calibre9\">.razor<\/code> file extension. The output is not a web page, although layouts can be used to wrap a component so it outputs as a web page, and the <code class=\"calibre9\">@page<\/code> directive can be used to assign a route that defines the URL path to retrieve the component as a page.<\/li>\n<\/ul>\n<p class=\"rights\">Now that you understand the background to Blazor, let's see something more practical: a review of the newest Blazor Web App project template that was introduced in .NET 8 and supports the new unified hosting model.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"17.3\" id=\"calibre_link-840\">\n<h2 data-number=\"17.3\" class=\"calibre5\">Reviewing the Blazor Web App project template<\/h2>\n<p class=\"rights\">Before .NET 8, there were separate project templates for the different hosting models. For example, <strong class=\"calibre2\">Blazor Server App<\/strong>, <strong class=\"calibre2\">Blazor WebAssembly App<\/strong>, and <strong class=\"calibre2\">Blazor WebAssembly App Empty<\/strong>. Introduced with .NET 8 is a single project template named <strong class=\"calibre2\">Blazor Web App<\/strong>. Consider all the others legacy and avoid them unless you must use older .NET SDKs.<\/p>\n<section data-number=\"17.3.1\" id=\"calibre_link-841\">\n<h3 data-number=\"17.3.1\" class=\"calibre8\">Creating a Blazor Web App project<\/h3>\n<p class=\"rights\">Let's look at the default template for a Blazor Web App project. Mostly, you will see that it is the same as an ASP.NET Core Razor Pages template, with a few key additions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">Use your preferred code editor to open the <code class=\"calibre9\">PracticalApps<\/code> solution and then add a new project, as defined in the following list:<\/p>\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Blazor Web App<\/strong> <strong class=\"calibre2\"><\/strong> \/ <code class=\"calibre9\">blazor<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">PracticalApps<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">Northwind.Blazor<\/code><\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Configure for HTTPS<\/strong>: Selected.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Use interactive WebAssembly components<\/strong>: Cleared.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Use interactive server components<\/strong>: Cleared.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Include sample pages<\/strong>: Selected.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Do not use top-level statements<\/strong>: Cleared.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">We have not selected the options to use interactive WebAssembly or server components so that we can build up your knowledge about how Blazor works step by step. In real-world projects, you are likely to want to select these options from the start. We have also selected to include sample pages which you will likely want to clear in a real-world project.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.Blazor<\/code> project.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Northwind.Blazor.csproj<\/code>, note that it is identical to an ASP.NET Core project that uses the Web SDK and targets .NET 8.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, note it is almost identical to an ASP.NET Core project. Differences include the section that configures services, with its call to the <code class=\"calibre9\">AddRazorComponents<\/code> method, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">var builder = WebApplication.CreateBuilder(args);\n\/\/ Add services to the container.\nbuilder.Services.AddRazorComponents();\nvar app = builder.Build(); <\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Also note the section for configuring the HTTP pipeline, which calls the <code class=\"calibre9\">MapRazorComponents&lt;App&gt;<\/code> method. This configures a root application component that will be named <code class=\"calibre9\">App.razor<\/code>, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ Configure the HTTP request pipeline.\nif (!app.Environment.IsDevelopment())\n{\n  app.UseExceptionHandler(\"\/Error\");\n  \/\/ The default HSTS value is 30 days. You may want to change this for production scenarios, see https:\/\/aka.ms\/aspnetcore-hsts.\n  app.UseHsts();\n}\napp.UseHttpsRedirection();\napp.UseStaticFiles();\napp.MapRazorComponents&lt;App&gt;();\napp.Run();<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"17.3.2\" id=\"calibre_link-842\">\n<h3 data-number=\"17.3.2\" class=\"calibre8\">Reviewing Blazor routing, layouts, and navigation<\/h3>\n<p class=\"rights\">Let's review how routing is configured for a Blazor project, the layouts, and the navigation menu:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Blazor<\/code> project folder, in the <code class=\"calibre9\">Components<\/code> folder, in <code class=\"calibre9\">App.razor<\/code>, note that it defines basic HTML page markup that references a local copy of Bootstrap for styling, and a few Blazor-specific elements, as shown highlighted in the following markup and noted in the list after the markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n  &lt;meta charset=\"utf-8\" \/&gt;\n  &lt;meta name=\"viewport\" content=\"width=device-width,\n    initial-scale=1.0, maximum-scale=1.0, user-scalable=no\" \/&gt;\n  &lt;base href=\"\/\" \/&gt;\n  &lt;link rel=\"stylesheet\" href=\"css\/bootstrap\/bootstrap.min.css\" \/&gt;\n  &lt;link rel=\"stylesheet\" href=\"css\/app.css\" \/&gt;\n  &lt;link rel=\"stylesheet\" href=\"Northwind.Blazor.styles.css\" \/&gt;\n  &lt;link rel=\"icon\" type=\"image\/png\" href=\"favicon.png\" \/&gt;\n  &lt;HeadOutlet \/&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n  &lt;Routes \/&gt;\n  &lt;script src=\"_framework\/blazor.web.js\" suppress-error=\"BL9992\"&gt;&lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">While reviewing the preceding markup, note the following:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A <code class=\"calibre9\">&lt;HeadOutlet \/&gt;<\/code> Blazor component for injecting additional content into the <code class=\"calibre9\">&lt;head&gt;<\/code> section. This is one of the built-in components available in all Blazor projects.<\/li>\n<li class=\"calibre3\">A <code class=\"calibre9\">&lt;Routes \/&gt;<\/code> Blazor component for defining the custom routes in this project. This component can be completely customized by the developer because it is part of the current project in a file named <code class=\"calibre9\">Routes.razor<\/code>.<\/li>\n<li class=\"calibre3\">A script block for <code class=\"calibre9\">blazor.web.js<\/code> that manages communication back to the server for Blazor's dynamic features like downloading WebAssembly components in the background and later switching from server-side to client-side component execution.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components<\/code> folder, in <code class=\"calibre9\">Routes.razor<\/code>, note that a <code class=\"calibre9\">&lt;Router&gt;<\/code> enables routing for all Blazor components found in the current assembly, and that if a matching route is found, then <code class=\"calibre9\">RouteView<\/code> is executed, which sets the default layout for the component to <code class=\"calibre9\">MainLayout<\/code> and passes any route data parameters to the component. For that component, the first <code class=\"calibre9\">&lt;h1&gt;<\/code> element in it will get the focus, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">  &lt;Router AppAssembly=\"@typeof(App).Assembly\"&gt;\n    &lt;Found Context=\"routeData\"&gt;\n      &lt;RouteView RouteData=\"@routeData\" \n                 DefaultLayout=\"@typeof(MainLayout)\" \/&gt;\n      &lt;FocusOnNavigate RouteData=\"@routeData\" Selector=\"h1\" \/&gt;\n    &lt;\/Found&gt;\n  &lt;\/Router&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components<\/code> folder, in <code class=\"calibre9\">_Imports.razor<\/code>, note that this file imports some useful namespaces for use in all your custom Blazor components.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Layout<\/code> folder, in <code class=\"calibre9\">MainLayout.razor<\/code>, note that it defines <code class=\"calibre9\">&lt;div&gt;<\/code> for a sidebar containing a navigation menu that is implemented by the <code class=\"calibre9\">NavMenu.razor<\/code> component file in this project, and HTML5 elements like <code class=\"calibre9\">&lt;main&gt;<\/code> and <code class=\"calibre9\">&lt;article&gt;<\/code> for the content, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@inherits LayoutComponentBase\n&lt;div class=\"page\"&gt;\n  &lt;div class=\"sidebar\"&gt;\n    &lt;NavMenu \/&gt;\n  &lt;\/div&gt;\n  &lt;main&gt;\n    &lt;div class=\"top-row px-4\"&gt;\n      &lt;a href=\"https:\/\/learn.microsoft.com\/aspnet\/core\/\" \n         target=\"_blank\"&gt;About&lt;\/a&gt;\n    &lt;\/div&gt;\n    &lt;article class=\"content px-4\"&gt;\n      @Body\n    &lt;\/article&gt;\n  &lt;\/main&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">In the <code class=\"calibre9\">Components\\Layout<\/code> folder, in <code class=\"calibre9\">MainLayout.razor.css<\/code>, note that it contains isolated CSS styles for the component. Due to the naming convention, styles defined in this file take priority over others defined elsewhere that might affect the component.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">Blazor components often need to provide their own CSS to apply styling or JavaScript for activities that cannot be performed purely in C#, like access to browser APIs. To ensure this does not conflict with site-level CSS and JavaScript, Blazor supports CSS and JavaScript isolation. If you have a component named <code class=\"calibre9\">Home.razor<\/code>, simply create a CSS file named <code class=\"calibre9\">Home.razor.css<\/code>. The styles defined within this file will override any other styles in the project.<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Layout<\/code> folder, in <code class=\"calibre9\">NavMenu.razor<\/code>, note that it has three menu items for <strong class=\"calibre2\">Home<\/strong>, <strong class=\"calibre2\">Counter<\/strong>, and <strong class=\"calibre2\">Fetch data<\/strong>. These are created by using a component named <code class=\"calibre9\">NavLink<\/code>, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;div class=\"top-row ps-3 navbar navbar-dark\"&gt;\n  &lt;div class=\"container-fluid\"&gt;\n    &lt;a class=\"navbar-brand\" href=\"\"&gt;MyBlazorWeb&lt;\/a&gt;\n  &lt;\/div&gt;\n&lt;\/div&gt;\n&lt;input type=\"checkbox\" title=\"Navigation menu\" class=\"navbar-toggler\" \/&gt;\n&lt;div class=\"nav-scrollable\" onclick=\n     \"document.querySelector('.navbar-toggler').click()\"&gt;\n  &lt;nav class=\"flex-column\"&gt;\n    &lt;div class=\"nav-item px-3\"&gt;\n      &lt;NavLink class=\"nav-link\" href=\"\" Match=\"NavLinkMatch.All\"&gt;\n        &lt;span class=\"bi bi-house-door-fill\" aria-hidden=\"true\"&gt;&lt;\/span&gt; Home\n      &lt;\/NavLink&gt;\n    &lt;\/div&gt;\n    &lt;div class=\"nav-item px-3\"&gt;\n      &lt;NavLink class=\"nav-link\" href=\"weather\"&gt;\n        &lt;span class=\"bi bi-list-nested\" aria-hidden=\"true\"&gt;&lt;\/span&gt; Weather\n      &lt;\/NavLink&gt;\n    &lt;\/div&gt;\n  &lt;\/nav&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Note <code class=\"calibre9\">NavMenu.razor<\/code> has its own isolated stylesheet named <code class=\"calibre9\">NavMenu.razor.css<\/code>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, in <code class=\"calibre9\">Home.razor<\/code>, note that it defines a component that sets the page title, and then renders a heading and a welcome message, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"\/\"\n&lt;PageTitle&gt;Home&lt;\/PageTitle&gt;\n&lt;h1&gt;Hello, world!&lt;\/h1&gt;\nWelcome to your new app.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, in <code class=\"calibre9\">Weather.razor<\/code>, note that it defines a component that fetches weather forecasts from an injected dependency weather service and then renders them in a table, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"\/weather\"\n@attribute [StreamRendering(true)]\n&lt;PageTitle&gt;Weather&lt;\/PageTitle&gt;\n    \n&lt;h1&gt;Weather&lt;\/h1&gt;\n&lt;p&gt;This component demonstrates showing data from the server.&lt;\/p&gt; \n@if (forecasts == null)\n{\n  &lt;p&gt;&lt;em&gt;Loading...&lt;\/em&gt;&lt;\/p&gt;\n}\nelse\n{\n  &lt;table class=\"table\"&gt;\n    &lt;thead&gt;\n      &lt;tr&gt;\n        &lt;th&gt;Date&lt;\/th&gt;\n        &lt;th&gt;Temp. (C)&lt;\/th&gt;\n        &lt;th&gt;Temp. (F)&lt;\/th&gt;\n        &lt;th&gt;Summary&lt;\/th&gt;\n      &lt;\/tr&gt;\n    &lt;\/thead&gt;\n    &lt;tbody&gt;\n    @foreach (var forecast in forecasts)\n    {\n      &lt;tr&gt;\n        &lt;td&gt;@forecast.Date.ToShortDateString()&lt;\/td&gt;\n        &lt;td&gt;@forecast.TemperatureC&lt;\/td&gt;\n        &lt;td&gt;@forecast.TemperatureF&lt;\/td&gt;\n        &lt;td&gt;@forecast.Summary&lt;\/td&gt;\n       &lt;\/tr&gt;\n    }\n    &lt;\/tbody&gt;\n  &lt;\/table&gt;\n}\n@code {\n  private WeatherForecast[]? forecasts;\n  protected override async Task OnInitializedAsync()\n  {\n    \/\/ Simulate asynchronous loading to demonstrate streaming rendering\n    await Task.Delay(500);\n    var startDate = DateOnly.FromDateTime(DateTime.Now);\n    var summaries = new[] { \"Freezing\", \"Bracing\", \"Chilly\", \"Cool\",\n      \"Mild\", \"Warm\", \"Balmy\", \"Hot\", \"Sweltering\", \"Scorching\" };\n    forecasts = Enumerable.Range(1, 5).Select(index =&gt;\n      new WeatherForecast\n      {\n        Date = startDate.AddDays(index),\n        TemperatureC = Random.Shared.Next(-20, 55),\n        Summary = Summaries[Random.Shared.Next(Summaries.Length)]\n      }).ToArray();\n  }\n  private class WeatherForecast\n  {\n    public DateOnly Date { get; set; }\n    public int TemperatureC { get; set; }\n    public string? Summary { get; set; }\n    public int TemperatureF =&gt; 32 + (int)(TemperatureC \/ 0.5556);\n  }\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"17.3.3\" id=\"calibre_link-843\">\n<h3 data-number=\"17.3.3\" class=\"calibre8\">How to define a routable page component<\/h3>\n<p class=\"rights\">To create a routable page component, add the <code class=\"calibre9\">@page<\/code> directive to the top of a component's <code class=\"calibre9\">.razor<\/code> file, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"customers\"<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The preceding code is the equivalent of an MVC controller decorated with the <code class=\"calibre9\">[Route]<\/code> attribute, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">[Route(\"customers\")]\npublic class CustomersController\n{<\/code><\/pre>\n<\/div>\n<p class=\"rights\">A page component can have multiple <code class=\"calibre9\">@page<\/code> directives to register multiple routes, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"\/weather\"\n@page \"\/forecast\"<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">Router<\/code> component scans the assembly specifically in its <code class=\"calibre9\">AppAssembly<\/code> parameter for components decorated with the <code class=\"calibre9\">[Route]<\/code> attribute and registers their URL paths.At runtime, the page component is merged with any specific layout that you have specified, just like an MVC view or Razor Page would be. By default, the Blazor Web App project template defines <code class=\"calibre9\">MainLayout.razor<\/code> as the layout for page components.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: By convention, put routable page Blazor components in the <code class=\"calibre9\">Components\\Pages<\/code> folder.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"17.3.4\" id=\"calibre_link-844\">\n<h3 data-number=\"17.3.4\" class=\"calibre8\">How to navigate routes and pass route parameters<\/h3>\n<p class=\"rights\">Microsoft provides a dependency service named <code class=\"calibre9\">NavigationManager<\/code> that understands Blazor routing and the <code class=\"calibre9\">NavLink<\/code> component. The <code class=\"calibre9\">NavigateTo<\/code> method is used to go to the specified URL.Blazor routes can include case-insensitive named parameters, and your code can most easily access the passed values by binding the parameter to a property in the code block using the <code class=\"calibre9\">[Parameter]<\/code> attribute, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"\/customers\/{country}\"\n&lt;div&gt;Country parameter as the value: @Country&lt;\/div&gt;\n@code {\n  [Parameter]\n  public string Country { get; set; }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The recommended way to handle a parameter that should have a default value when it is missing is to suffix the parameter with <code class=\"calibre9\">?<\/code> and use the null coalescing operator in the <code class=\"calibre9\">OnParametersSet<\/code> method, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"\/customers\/{country?}\"\n&lt;div&gt;Country parameter as the value: @Country&lt;\/div&gt;\n@code {\n  [Parameter]\n  public string Country { get; set; }\n  protected override void OnParametersSet()\n  {\n    \/\/ If the automatically set property is null, then\n    \/\/ set its value to USA.\n    Country = Country ?? \"USA\";\n  }\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"17.3.5\" id=\"calibre_link-845\">\n<h3 data-number=\"17.3.5\" class=\"calibre8\">How to use the navigation link component with routes<\/h3>\n<p class=\"rights\">In HTML, you use the <code class=\"calibre9\">&lt;a&gt;<\/code> element to define navigation links, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;a href=\"\/customers\"&gt;Customers&lt;\/a&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">In Blazor, use the <code class=\"calibre9\">&lt;NavLink&gt;<\/code> component, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;NavLink href=\"\/customers\"&gt;Customers&lt;\/NavLink&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The <code class=\"calibre9\">NavLink<\/code> component is better than an anchor element because it automatically sets its class to <code class=\"calibre9\">active<\/code> if its <code class=\"calibre9\">href<\/code> is a match on the current location URL. If your CSS uses a different class name, then you can set the class name in the <code class=\"calibre9\">NavLink.ActiveClass<\/code> property.By default, in the matching algorithm, the <code class=\"calibre9\">href<\/code> is a path <em class=\"calibre10\">prefix<\/em>, so if <code class=\"calibre9\">NavLink<\/code> has an <code class=\"calibre9\">href<\/code> of <code class=\"calibre9\">\/customers<\/code>, as shown in the preceding code example, then it would match all the following paths and set them all to have the <code class=\"calibre9\">active<\/code> class style:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/customers\n\/customers\/USA\n\/customers\/Germany\/Berlin<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To ensure that the matching algorithm only performs matches on <em class=\"calibre10\">all<\/em> of the text in the path, in other words, there is only a match when the whole complete text matches but not when just part of the path matches, then set the <code class=\"calibre9\">Match<\/code> parameter to <code class=\"calibre9\">NavLinkMatch.All<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;NavLink href=\"\/customers\" Match=\"NavLinkMatch.All\"&gt;Customers&lt;\/NavLink&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">If you set other attributes such as <code class=\"calibre9\">target<\/code>, they are passed through to the underlying <code class=\"calibre9\">&lt;a&gt;<\/code> element that is generated.<\/p>\n<\/section>\n<section data-number=\"17.3.6\" id=\"calibre_link-846\">\n<h3 data-number=\"17.3.6\" class=\"calibre8\">Understanding base component classes<\/h3>\n<p class=\"rights\">The <code class=\"calibre9\">OnParametersSet<\/code> method is defined by the base class that components inherit from by default named <code class=\"calibre9\">ComponentBase<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.AspNetCore.Components;\npublic abstract class ComponentBase : IComponent, IHandleAfterRender, IHandleEvent\n{\n  \/\/ Members not shown.\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><code class=\"calibre9\">ComponentBase<\/code> has some useful methods that you can call and override, as shown in <em class=\"calibre10\">Table 16.1<\/em>:<\/p>\n<table class=\"calibre17\">\n<colgroup class=\"calibre18\">\n<col class=\"calibre19\"><\/col>\n<col class=\"calibre19\"><\/col>\n<\/colgroup>\n<tbody class=\"calibre20\">\n<tr class=\"odd\">\n<td class=\"calibre21\">Method(s)<\/td>\n<td class=\"calibre21\">Description<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">InvokeAsync<\/code><\/td>\n<td class=\"calibre21\">Call this method to execute a function on the associated renderer's synchronization context.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><code class=\"calibre9\">OnAfterRender<\/code>,<\/p>\n<p class=\"rights\"><code class=\"calibre9\">OnAfterRenderAsync<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">Override these methods to invoke code after each time the component has been rendered.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><code class=\"calibre9\">OnInitialized<\/code>,<\/p>\n<p class=\"rights\"><code class=\"calibre9\">OnInitializedAsync<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">Override these methods to invoke code after the component has received its initial parameters from its parent in the render tree.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\">\n<p class=\"rights\"><code class=\"calibre9\">OnParametersSet<\/code>,<\/p>\n<p class=\"rights\"><code class=\"calibre9\">OnParametersSetAsync<\/code><\/p>\n<\/td>\n<td class=\"calibre21\">Override these methods to invoke code after the component has received parameters and the values have been assigned to properties.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">ShouldRender<\/code><\/td>\n<td class=\"calibre21\">Override this method to indicate if the component should render.<\/td>\n<\/tr>\n<tr class=\"odd\">\n<td class=\"calibre21\"><code class=\"calibre9\">StateHasChanged<\/code><\/td>\n<td class=\"calibre21\">Call this method to cause the component to re-render.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Table 16.1: Useful methods to override in ComponentBase<\/p>\n<p class=\"rights\">Blazor components can have shared layouts in a similar way to MVC views and Razor Pages. You would create a <code class=\"calibre9\">.razor<\/code> component file and make it explicitly inherit from <code class=\"calibre9\">LayoutComponentBase<\/code>, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@inherits LayoutComponentBase\n&lt;div&gt;\n  ...\n  @Body\n  ...\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">The base class has a property named <code class=\"calibre9\">Body<\/code> that you can render in the markup at the correct place within the layout.You can set a default layout for components in the <code class=\"calibre9\">App.razor<\/code> file and its <code class=\"calibre9\">Router<\/code> component. To explicitly set a layout for a component, use the <code class=\"calibre9\">@layout<\/code> directive, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"\/customers\"\n@layout AlternativeLayout\n&lt;div&gt;\n  ...\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"17.3.7\" id=\"calibre_link-847\">\n<h3 data-number=\"17.3.7\" class=\"calibre8\">Running the Blazor Web App project template<\/h3>\n<p class=\"rights\">Now that we have reviewed the project template and the important parts that are specific to Blazor Server, we can start the website and review its behavior:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Properties<\/code> folder, in <code class=\"calibre9\">launchSettings.json<\/code>, for the <code class=\"calibre9\">https<\/code> profile, modify the <code class=\"calibre9\">applicationUrl<\/code> to use port <code class=\"calibre9\">5161<\/code> for HTTPS and port <code class=\"calibre9\">5160<\/code> for HTTP, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\"applicationUrl\": \"https:\/\/localhost:5161;http:\/\/localhost:5160\",<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Blazor<\/code> project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Start Chrome and navigate to <code class=\"calibre9\">https:\/\/localhost:5161\/<\/code>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the left navigation menu, click <strong class=\"calibre2\">Weather<\/strong>, as shown in <em class=\"calibre10\">Figure 16.1<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 16.1: Fetching weather data into a Blazor Web App project\" height=\"504\" src=\"\/images\/cs12\/000037.png\" width=\"1427\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 16.1: Fetching weather data into a Blazor Web App project<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<\/section>\n<section data-number=\"17.4\" id=\"calibre_link-848\">\n<h2 data-number=\"17.4\" class=\"calibre5\">Building components using Blazor<\/h2>\n<p class=\"rights\">In this section, we will build a component to list, create, and edit customers in the Northwind database. We will build it over several steps:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Make a Blazor component that renders the name of a country set as a parameter.<\/li>\n<li class=\"calibre3\">Make it work as a routable page as well as a component.<\/li>\n<li class=\"calibre3\">Implement the functionality to perform CRUD operations on customers in a database.<\/li>\n<\/ol>\n<section data-number=\"17.4.1\" id=\"calibre_link-849\">\n<h3 data-number=\"17.4.1\" class=\"calibre8\">Defining and testing a simple Blazor component<\/h3>\n<p class=\"rights\">We will add the new component to the existing Blazor Web App project:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">\n<p class=\"rights\">In the <code class=\"calibre9\">Northwind.Blazor<\/code> project, in the <code class=\"calibre9\">Components\\Pages<\/code> folder, add a new file named <code class=\"calibre9\">Customers.razor<\/code>. In Visual Studio 2022, the project item template is named <strong class=\"calibre2\">Razor Component<\/strong>. In JetBrains Rider, the project item template is named <strong class=\"calibre2\">Blazor Component<\/strong>.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">Good Practice<\/strong>: Blazor component filenames must start with an uppercase letter, or you will have compile errors!<\/p>\n<\/blockquote>\n<\/li>\n<li class=\"calibre3\">Add statements to output a heading for the <code class=\"calibre9\">Customers<\/code> component and define a code block that defines a property to store the name of a country, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;h3&gt;\n  Customers @(string.IsNullOrWhiteSpace(Country)\n    ? \"Worldwide\" : \"in \" + Country)\n&lt;\/h3&gt;\n@code {\n  [Parameter]\n  public string? Country { get; set; }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, in <code class=\"calibre9\">Home.razor<\/code>, add statements to the bottom of the file to instantiate the <code class=\"calibre9\">Customers<\/code> component twice, once setting <code class=\"calibre9\">Germany<\/code> as the <code class=\"calibre9\">Country<\/code> parameter, and once without setting the country, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;Customers Country=\"Germany\" \/&gt;\n&lt;Customers \/&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Blazor<\/code> project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Start Chrome, navigate to <code class=\"calibre9\">https:\/\/localhost:5161\/<\/code>, and note the <code class=\"calibre9\">Customers<\/code> components, as shown in <em class=\"calibre10\">Figure 16.2<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 16.2: The Customers components with the Country parameter set to Germany, and not set\" height=\"441\" src=\"\/images\/cs12\/000000.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 16.2: The Customers components with the Country parameter set to Germany, and not set<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"17.4.2\" id=\"calibre_link-850\">\n<h3 data-number=\"17.4.2\" class=\"calibre8\">Using Bootstrap icons<\/h3>\n<p class=\"rights\">In the older Blazor project templates, they included all Bootstrap icons. In the new project template, only three icons are defined using SVG. Let's see who the team defined those icons, and then add some more for our own use:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Layout<\/code> folder, in <code class=\"calibre9\">NavMenu.razor.css<\/code>, find the text <code class=\"calibre9\">bi-house<\/code>, and note the three icons defined using SVG, as partially shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">.bi-house-door-fill {\n    background-image: url(\"data:image\/svg+xml,...\");\n}\n.bi-plus-square-fill {\n    background-image: url(\"data:image\/svg+xml,...\");\n}\n.bi-list-nested {\n    background-image: url(\"data:image\/svg+xml,...\");\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In your favorite browser, navigate to: <a href=\"https:\/\/icon-sets.iconify.design\/bi\/\">https:\/\/icon-sets.iconify.design\/bi\/<\/a>, and note that <strong class=\"calibre2\">Bootstrap Icons<\/strong> have an MIT license and contain more than 2000 icons.<\/li>\n<li class=\"calibre3\">In the <strong class=\"calibre2\">Search Bootstrap Icons<\/strong> box, enter <code class=\"calibre9\">globe<\/code>, and note that six globe icons are found.<\/li>\n<li class=\"calibre3\">Click the first globe, scroll down the page, click the <strong class=\"calibre2\">SVG as data: URI<\/strong> button, and note that you could copy and paste the definition of this icon for use in the CSS stylesheet, but you do not need to because I have already created a CSS file for you to use with five icons defined for you to use in your Blazor project.<\/li>\n<li class=\"calibre3\">In your favorite browser, navigate to: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Blazor\/wwwroot\/icons.css\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Blazor\/wwwroot\/icons.css<\/a>, download the file, and save it in your own project in its <code class=\"calibre9\">wwwroot<\/code> folder.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components<\/code> folder, in the <code class=\"calibre9\">App.razor<\/code> component, in the &lt;head&gt;, add a &lt;link&gt; element to reference the icons.css stylesheet, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;link rel=\"stylesheet\" href=\"icons.css\" \/&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Save and close the file.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"17.4.3\" id=\"calibre_link-851\">\n<h3 data-number=\"17.4.3\" class=\"calibre8\">Making the component a routable page component<\/h3>\n<p class=\"rights\">It is simple to turn this component into a routable page component with a route parameter for the country:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, in the <code class=\"calibre9\">Customers.razor<\/code> component, add a statement at the top of the file to register <code class=\"calibre9\">\/customers<\/code> as its route with an optional <code class=\"calibre9\">country<\/code> route parameter, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"\/customers\/{country?}\"<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Layout<\/code> folder, in <code class=\"calibre9\">NavMenu.razor<\/code>, at the bottom of the existing list item elements, add two list item elements for our routable page component to show customers worldwide and in Germany that both use an icon of people, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;div class=\"nav-item px-3\"&gt;\n  &lt;NavLink class=\"nav-link\" href=\"customers\"\n           Match=\"NavLinkMatch.All\"&gt;\n    &lt;span class=\"bi bi-globe\" aria-hidden=\"true\"&gt;&lt;\/span&gt;\n    Customers Worldwide\n  &lt;\/NavLink&gt;\n&lt;\/div&gt;\n&lt;div class=\"nav-item px-3\"&gt;\n  &lt;NavLink class=\"nav-link\" href=\"customers\/Germany\"&gt;\n    &lt;span class=\"bi bi-globe-europe-africa\"\n          aria-hidden=\"true\"&gt;&lt;\/span&gt;\n    Customers in Germany\n  &lt;\/NavLink&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, in <code class=\"calibre9\">Home.razor<\/code>, remove the two <code class=\"calibre9\">&lt;Customers&gt;<\/code> components because we can test them using their navigation menu items from now on and we want to keep the home page as simple as possible.<\/li>\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Blazor<\/code> project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Start Chrome and navigate to <code class=\"calibre9\">https:\/\/localhost:5161\/<\/code>.<\/li>\n<li class=\"calibre3\">In the left navigation menu, click <strong class=\"calibre2\">Customers in Germany<\/strong>. Note that the country name is correctly passed to the page component and that the component uses the same layout as the other page components, like <code class=\"calibre9\">Home.razor<\/code>. Also note the URL: <code class=\"calibre9\">https:\/\/localhost:5161\/customers\/Germany<\/code>.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"17.4.4\" id=\"calibre_link-852\">\n<h3 data-number=\"17.4.4\" class=\"calibre8\">Getting entities into a component<\/h3>\n<p class=\"rights\">Now that you have seen the minimum implementation of a component, we can add some useful functionality to it. In this case, we will use the Northwind database context to fetch customers from the database:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Northwind.Blazor.csproj<\/code>, add a reference to the Northwind database context project for either SQL Server or SQLite, and globally import the namespace for working with Northwind entities, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;!-- change Sqlite to SqlServer if you prefer --&gt;\n  &lt;ProjectReference Include=\"..\\Northwind.DataContext.Sqlite\n\\Northwind.DataContext.Sqlite.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;\n&lt;ItemGroup&gt;\n  &lt;Using Include=\"Northwind.EntityModels\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.Blazor<\/code> project.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, before the call to <code class=\"calibre9\">Build<\/code>, add a statement to register the Northwind database context in the dependency services collection, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddNorthwindContext();<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"17.4.5\" id=\"calibre_link-853\">\n<h3 data-number=\"17.4.5\" class=\"calibre8\">Abstracting a service for a Blazor component<\/h3>\n<p class=\"rights\">We could implement the Blazor component so that it directly calls the Northwind database context to fetch the customers using an entity model. This would work if the Blazor component executes on the server. But if the component ran in the browser using WebAssembly, then it would not work.We will now create a local dependency service to enable better reuse of the components:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Use your preferred coding tool to add a new project, as defined in the following list:\n<ul class=\"calibre16\">\n<li class=\"calibre3\">Project template: <strong class=\"calibre2\">Class Library<\/strong> \/ <code class=\"calibre9\">classlib<\/code><\/li>\n<li class=\"calibre3\">Project file and folder: <code class=\"calibre9\">Northwind.Blazor.Services<\/code><\/li>\n<li class=\"calibre3\">Solution file and folder: <code class=\"calibre9\">PracticalApps<\/code><\/li>\n<\/ul>\n<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Blazor.Services.csproj<\/code> project file, add a project reference to the Northwind entity models library, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;!-- change Sqlite to SqlServer if you prefer --&gt;\n  &lt;ProjectReference Include=\"..\\Northwind.EntityModels.Sqlite\\\nNorthwind.EntityModels.Sqlite.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.Blazor.Services<\/code> project.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Blazor.Services<\/code> project, rename <code class=\"calibre9\">Class1.cs<\/code> to <code class=\"calibre9\">INorthwindService.cs<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">INorthwindService.cs<\/code>, define a contract for a local service that abstracts CRUD operations, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.EntityModels; \/\/ To use Customer.\nnamespace Northwind.Blazor.Services;\npublic interface INorthwindService\n{\n  Task&lt;List&lt;Customer&gt;&gt; GetCustomersAsync();\n  Task&lt;List&lt;Customer&gt;&gt; GetCustomersAsync(string country);\n  Task&lt;Customer?&gt; GetCustomerAsync(string id);\n  Task&lt;Customer&gt; CreateCustomerAsync(Customer c);\n  Task&lt;Customer&gt; UpdateCustomerAsync(Customer c);\n  Task DeleteCustomerAsync(string id);\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Blazor.csproj<\/code> project file, add a project reference to the services library, as shown highlighted in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;!-- change Sqlite to SqlServer if you prefer --&gt;\n  &lt;ProjectReference Include=\"..\\Northwind.DataContext.Sqlite\n\\Northwind.DataContext.Sqlite.csproj\" \/&gt;\n  &lt;ProjectReference Include=\"..\\Northwind.Blazor.Services\\\nNorthwind.Blazor.Services.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Build the <code class=\"calibre9\">Northwind.Blazor<\/code> project.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Blazor<\/code> project, add a new folder named <code class=\"calibre9\">Services<\/code>.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">Services<\/code> folder, add a new file named <code class=\"calibre9\">NorthwindServiceServerSide.cs<\/code> and modify its contents to implement the <code class=\"calibre9\">INorthwindService<\/code> interface by using the Northwind database context, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Microsoft.EntityFrameworkCore; \/\/ To use ToListAsync&lt;T&gt;.\nnamespace Northwind.Blazor.Services;\npublic class NorthwindServiceServerSide : INorthwindService\n{\n  private readonly NorthwindContext _db;\n  public NorthwindServiceServerSide(NorthwindContext db)\n  {\n    _db = db;\n  }\n  public Task&lt;List&lt;Customer&gt;&gt; GetCustomersAsync()\n  {\n    return _db.Customers.ToListAsync();\n  }\n  public Task&lt;List&lt;Customer&gt;&gt; GetCustomersAsync(string country)\n  {\n    return _db.Customers.Where(c =&gt; c.Country == country).ToListAsync();\n  }\n  public Task&lt;Customer?&gt; GetCustomerAsync(string id)\n  {\n    return _db.Customers.FirstOrDefaultAsync\n      (c =&gt; c.CustomerId == id);\n  }\n  public Task&lt;Customer&gt; CreateCustomerAsync(Customer c)\n  {\n    _db.Customers.Add(c); \n    _db.SaveChangesAsync();\n    return Task.FromResult(c);\n  }\n  public Task&lt;Customer&gt; UpdateCustomerAsync(Customer c)\n  {\n    _db.Entry(c).State = EntityState.Modified;\n    _db.SaveChangesAsync();\n    return Task.FromResult(c);\n  }\n  public Task DeleteCustomerAsync(string id)\n  {\n    Customer? customer = _db.Customers.FirstOrDefaultAsync\n      (c =&gt; c.CustomerId == id).Result;\n    if (customer == null)\n    {\n      return Task.CompletedTask;\n    }\n    else\n    {\n      _db.Customers.Remove(customer); \n      return _db.SaveChangesAsync();\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, import the namespace for our service, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">using Northwind.Blazor.Services; \/\/ To use INorthwindService.<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, before the call to <code class=\"calibre9\">Build<\/code>, add a statement to register <code class=\"calibre9\">NorthwindServiceServerSide<\/code> as a transient service that implements the <code class=\"calibre9\">INorthwindService<\/code> interface, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddTransient&lt;INorthwindService,\n  NorthwindServiceServerSide&gt;();<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">A transient service is one that creates a new instance for each request. You can read more about the different lifetimes for services at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/extensions\/dependency-injection#service-lifetimes\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/extensions\/dependency-injection#service-lifetimes<\/a>.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components<\/code> folder, in <code class=\"calibre9\">_Imports.razor<\/code>, import the namespace for working with the Northwind entities and our service so that Blazor components that we build do not need to import the namespaces individually, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@using Northwind.Blazor.Services @* To use INorthwindService. *@\n@using Northwind.EntityModels @* To use Northwind entities. *@<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">The <code class=\"calibre9\">_Imports.razor<\/code> file only applies to <code class=\"calibre9\">.razor<\/code> files. If you use code-behind <code class=\"calibre9\">.cs<\/code> files to implement component code, then they must have namespaces imported separately or use global <code class=\"calibre9\">usings<\/code> to implicitly import the namespaces.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, in <code class=\"calibre9\">Customers.razor<\/code>, add statements to inject the service and then use it to output a table of all customers using synchronous database operations, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"\/customers\/{country?}\" \n@inject INorthwindService _service\n&lt;h3&gt;\n  Customers @(string.IsNullOrWhiteSpace(Country) \n    ? \"Worldwide\" : \"in \" + Country)\n&lt;\/h3&gt;\n@if (customers is null)\n{\n&lt;p&gt;&lt;em&gt;Loading...&lt;\/em&gt;&lt;\/p&gt;\n}\nelse\n{\n&lt;table class=\"table\"&gt;\n  &lt;thead&gt;\n    &lt;tr&gt;\n      &lt;th&gt;Id&lt;\/th&gt;\n      &lt;th&gt;Company Name&lt;\/th&gt;\n      &lt;th&gt;Address&lt;\/th&gt;\n      &lt;th&gt;Phone&lt;\/th&gt;\n      &lt;th&gt;&lt;\/th&gt;\n    &lt;\/tr&gt;\n  &lt;\/thead&gt;\n  &lt;tbody&gt;\n  @foreach (Customer c in customers)\n  {\n    &lt;tr&gt;\n      &lt;td&gt;@c.CustomerId&lt;\/td&gt;\n      &lt;td&gt;@c.CompanyName&lt;\/td&gt;\n      &lt;td&gt;\n        @c.Address&lt;br\/&gt;\n        @c.City&lt;br\/&gt;\n        @c.PostalCode&lt;br\/&gt;\n        @c.Country\n      &lt;\/td&gt;\n      &lt;td&gt;@c.Phone&lt;\/td&gt;\n      &lt;td&gt;\n        &lt;a class=\"btn btn-info\" href=\"editcustomer\/@c.CustomerId\"&gt;\n          &lt;i class=\"bi bi-pencil\"&gt;&lt;\/i&gt;&lt;\/a&gt;\n        &lt;a class=\"btn btn-danger\" \n           href=\"deletecustomer\/@c.CustomerId\"&gt;\n          &lt;i class=\"bi bi-trash\"&gt;&lt;\/i&gt;&lt;\/a&gt;\n      &lt;\/td&gt;\n    &lt;\/tr&gt;\n  }\n  &lt;\/tbody&gt;\n&lt;\/table&gt;\n}\n@code {\n  [Parameter]\n  public string? Country { get; set; }\n  private IEnumerable&lt;Customer&gt;? customers;\n  protected override async Task OnParametersSetAsync()\n  {\n    if (string.IsNullOrWhiteSpace(Country))\n    {\n      customers = await _service.GetCustomersAsync();\n    }\n    else\n    {\n      customers = await _service.GetCustomersAsync(Country);\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Blazor<\/code> project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Start Chrome and navigate to <code class=\"calibre9\">https:\/\/localhost:5161\/<\/code>.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">In the left navigation menu, click <strong class=\"calibre2\">Customers in Germany<\/strong>, and note that the table of customers loads from the database and renders in the web page, as shown in <em class=\"calibre10\">Figure 16.3<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 16.3: The list of customers in Germany\" height=\"548\" src=\"\/images\/cs12\/000158.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 16.3: The list of customers in Germany<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">In the browser address bar, change <code class=\"calibre9\">Germany<\/code> to <code class=\"calibre9\">UK<\/code>, and note that the table of customers is filtered to only show UK customers.<\/li>\n<li class=\"calibre3\">In the left navigation menu, click <strong class=\"calibre2\">Customers Worldwide<\/strong>, and note that the table of customers is unfiltered by country.<\/li>\n<li class=\"calibre3\">Click any of the edit or delete buttons and note that they return a message saying <strong class=\"calibre2\">Error: 404<\/strong> because we have not yet implemented that functionality, and note the link, for example, to edit a customer identified by the five-character <code class=\"calibre9\">Id<\/code>: <code class=\"calibre9\">https:\/\/localhost:5161\/editcustomer\/ALFKI<\/code>.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"17.4.6\" id=\"calibre_link-854\">\n<h3 data-number=\"17.4.6\" class=\"calibre8\">Enabling streaming rendering<\/h3>\n<p class=\"rights\">Now, let's improve the rendering of the customers table by enabling it to happen after the page has appeared to the visitor. We are already using an asynchronous operation to fetch the data, but this operation must finish before the web page response is sent back to the browser. This is why we never see the <strong class=\"calibre2\">Loading\u2026<\/strong> message on the page. To see it, we must enable streaming rendering. But if you are fetching data from a local database it might still happen too quickly, so to make sure we see it, we will also slow down the fetching of the data by adding a delay:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, at the top of <code class=\"calibre9\">Customers.razor<\/code>, add an attribute to enable streaming rendering, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@attribute [StreamRendering(true)]<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Customers.razor<\/code>, in the <code class=\"calibre9\">OnParametersSetAsync<\/code> method, add a statement to asynchronously delay for one second, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">protected override async Task OnParametersSetAsync()\n{\n  await Task.Delay(1000); \/\/ Delay for one second.\n  ...\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Blazor<\/code> project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Start Chrome and navigate to <code class=\"calibre9\">https:\/\/localhost:5161\/<\/code>.<\/li>\n<li class=\"calibre3\">In the left navigation menu, click <strong class=\"calibre2\">Customers in Germany<\/strong>, and note that the Loading\u2026 message appears for a second, and then is replaced by the table of customers.<\/li>\n<\/ol>\n<p class=\"rights\">So far, the component provides only a read-only table of customers. Now, we will extend it with full CRUD operations.<\/p>\n<\/section>\n<section data-number=\"17.4.7\" id=\"calibre_link-855\">\n<h3 data-number=\"17.4.7\" class=\"calibre8\">Defining forms using the EditForm component<\/h3>\n<p class=\"rights\">Microsoft provides ready-made components for building forms. We will use them to provide create, edit, and delete functionality for customers.Microsoft provides the <code class=\"calibre9\">EditForm<\/code> component and several form elements such as <code class=\"calibre9\">InputText<\/code> to make it easier to use forms with Blazor.<code class=\"calibre9\">EditForm<\/code> can have a model set to bind it to an object with properties and event handlers for custom validation, as well as to recognize standard Microsoft validation attributes on the model class, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;EditForm Model=\"@customer\" OnSubmit=\"ExtraValidation\"&gt;\n  &lt;DataAnnotationsValidator \/&gt;\n  &lt;ValidationSummary \/&gt;\n  &lt;InputText id=\"name\" @bind-Value=\"customer.CompanyName\" \/&gt;\n  &lt;button type=\"submit\"&gt;Submit&lt;\/button&gt;\n&lt;\/EditForm&gt;\n@code {\n  private Customer customer = new();\n  private void ExtraValidation()\n  {\n    \/\/ Perform any extra validation you want.\n  }\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\">As an alternative to a <code class=\"calibre9\">ValidationSummary<\/code> component, you can use the <code class=\"calibre9\">ValidationMessage<\/code> component to show a message next to an individual form element. To bind the validation message to a property, you use a lambda expression to select the property, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ValidationMessage For=\"@(() =&gt; Customer.CompanyName)\" \/&gt;<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"17.4.8\" id=\"calibre_link-856\">\n<h3 data-number=\"17.4.8\" class=\"calibre8\">Building a customer detail component<\/h3>\n<p class=\"rights\">Next, we will create a component to show the details of a customer. This will only be a component, never a page:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Blazor<\/code> project, in the <code class=\"calibre9\">Components<\/code> folder, create a new file named <code class=\"calibre9\">CustomerDetail.razor<\/code>. (The Visual Studio 2022 project item template is named <strong class=\"calibre2\">Razor Component<\/strong>. The JetBrains Rider project item template is named <strong class=\"calibre2\">Blazor Component<\/strong>.)<\/li>\n<li class=\"calibre3\">Modify its contents to define a form to edit the properties of a customer, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;EditForm Model=\"@Customer\" OnValidSubmit=\"@OnValidSubmit\"&gt;\n  &lt;DataAnnotationsValidator \/&gt;\n  &lt;div class=\"form-group\"&gt;\n    &lt;div&gt;\n      &lt;label&gt;Customer Id&lt;\/label&gt;\n      &lt;div&gt;\n        &lt;InputText @bind-Value=\"@Customer.CustomerId\" \/&gt;\n        &lt;ValidationMessage For=\"@(() =&gt; Customer.CustomerId)\" \/&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n  &lt;div class=\"form-group \"&gt;\n    &lt;div&gt;\n      &lt;label&gt;Company Name&lt;\/label&gt;\n      &lt;div&gt;\n        &lt;InputText @bind-Value=\"@Customer.CompanyName\" \/&gt;\n        &lt;ValidationMessage For=\"@(() =&gt; Customer.CompanyName)\" \/&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n  &lt;div class=\"form-group \"&gt;\n    &lt;div&gt;\n      &lt;label&gt;Address&lt;\/label&gt;\n      &lt;div&gt;\n        &lt;InputText @bind-Value=\"@Customer.Address\" \/&gt;\n        &lt;ValidationMessage For=\"@(() =&gt; Customer.Address)\" \/&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n  &lt;div class=\"form-group \"&gt;\n    &lt;div&gt;\n      &lt;label&gt;Country&lt;\/label&gt;\n      &lt;div&gt;\n        &lt;InputText @bind-Value=\"@Customer.Country\" \/&gt;\n        &lt;ValidationMessage For=\"@(() =&gt; Customer.Country)\" \/&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n  &lt;button type=\"submit\" class=\"btn btn-@ButtonStyle\"&gt;\n    @ButtonText\n  &lt;\/button&gt;\n&lt;\/EditForm&gt;\n@code { \n  [Parameter]\n  public Customer Customer { get; set; } = null!;\n  [Parameter]\n  public string ButtonText { get; set; } = \"Save Changes\";\n  [Parameter]\n  public string ButtonStyle { get; set; } = \"info\";\n  [Parameter]\n  public EventCallback OnValidSubmit { get; set; }\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"17.4.9\" id=\"calibre_link-857\">\n<h3 data-number=\"17.4.9\" class=\"calibre8\">Building customer create, edit, and delete components<\/h3>\n<p class=\"rights\">Now we can create three routable page components that use the component:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, create a new file named <code class=\"calibre9\">CreateCustomer.razor<\/code>.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">CreateCustomer.razor<\/code>, modify its contents to use the customer detail component to create a new customer, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"\/createcustomer\"\n@inject INorthwindService _service \n@inject NavigationManager _navigation\n&lt;h3&gt;Create Customer&lt;\/h3&gt;\n&lt;CustomerDetail ButtonText=\"Create Customer\"\n                Customer=\"@customer\" \n                OnValidSubmit=\"@Create\" \/&gt;\n@code {\n  private Customer customer = new();\n  private async Task Create()\n  {\n    await _service.CreateCustomerAsync(customer);\n    _navigation.NavigateTo(\"customers\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, in <code class=\"calibre9\">Customers.razor<\/code>, after the <code class=\"calibre9\">&lt;h3&gt;<\/code> element, add a <code class=\"calibre9\">&lt;div&gt;<\/code> element with a button to navigate to the create customer page component, as shown in the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;div class=\"form-group\"&gt;\n  &lt;a class=\"btn btn-info\" href=\"createcustomer\"&gt;\n  &lt;i class=\"bi bi-plus-square\"&gt;&lt;\/i&gt; Create New&lt;\/a&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, create a new file named <code class=\"calibre9\">EditCustomer.razor<\/code> and modify its contents to use the customer detail component to edit and save changes to an existing customer, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"\/editcustomer\/{customerid}\" \n@inject INorthwindService _service\n@inject NavigationManager _navigation\n&lt;h3&gt;Edit Customer&lt;\/h3&gt;\n&lt;CustomerDetail ButtonText=\"Update\"\n                Customer=\"@customer\" \n                OnValidSubmit=\"@Update\" \/&gt;\n@code { \n  [Parameter]\n  public string CustomerId { get; set; } = null!;\n  private Customer? customer = new();\n  protected override async Task OnParametersSetAsync()\n  {\n    customer = await _service.GetCustomerAsync(CustomerId);\n  }\n  private async Task Update()\n  {\n    if (customer is not null)\n    {\n      await _service.UpdateCustomerAsync(customer);\n    }\n    _navigation.NavigateTo(\"customers\");\n  }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, create a new file named <code class=\"calibre9\">DeleteCustomer.razor<\/code> and modify its contents to use the customer detail component to show the customer that is about to be deleted, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \"\/deletecustomer\/{customerid}\" \n@inject INorthwindService _service \n@inject NavigationManager _navigation\n&lt;h3&gt;Delete Customer&lt;\/h3&gt;\n&lt;div class=\"alert alert-danger\"&gt;\n  Warning! This action cannot be undone!\n&lt;\/div&gt;\n&lt;CustomerDetail ButtonText=\"Delete Customer\"\n                ButtonStyle=\"danger\" \n                Customer=\"@customer\" \n                OnValidSubmit=\"@Delete\" \/&gt;\n@code { \n  [Parameter]\n  public string CustomerId { get; set; } = null!;\n  private Customer? customer = new();\n  protected override async Task OnParametersSetAsync()\n  {\n    customer = await _service.GetCustomerAsync(CustomerId);\n  }\n  private async Task Delete()\n  {\n    if (customer is not null)\n    {\n      await _service.DeleteCustomerAsync(CustomerId);\n    }\n    _navigation.NavigateTo(\"customers\");\n  }\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"17.4.10\" id=\"calibre_link-858\">\n<h3 data-number=\"17.4.10\" class=\"calibre8\">Enabling server-side interactions<\/h3>\n<p class=\"rights\">In our Blazor project, neither server-side nor client-side interactions are enabled. We will enable server-side interactions first so that when we attempt to add a new customer, the validation will run and show error messages:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, at the end of the statement that adds Razor components, add a call to a method to enable server-side interactivity, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddRazorComponents()\n  .AddServerComponents();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code>, at the end of the statement that maps Razor components, add a call to a method to enable server-side interactivity, as shown highlighted in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.MapRazorComponents&lt;App&gt;()\n  .AddServerRenderMode();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, in <code class=\"calibre9\">CreateCustomer.razor<\/code>, at the top of the file, add a declaration to enable server-side rendering, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@attribute [RenderModeServer]<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, in <code class=\"calibre9\">EditCustomer.razor<\/code>, at the top of the file, add a declaration to enable server-side rendering, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@attribute [RenderModeServer]<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Components\\Pages<\/code> folder, in <code class=\"calibre9\">DeleteCustomer.razor<\/code>, at the top of the file, add a declaration to enable server-side rendering, as shown in the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@attribute [RenderModeServer]<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"17.4.11\" id=\"calibre_link-859\">\n<h3 data-number=\"17.4.11\" class=\"calibre8\">Testing the customer components<\/h3>\n<p class=\"rights\">Now we can test the customer components and how to use them to create, edit, and delete customers:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Start the <code class=\"calibre9\">Northwind.Blazor<\/code> project using the <code class=\"calibre9\">https<\/code> launch profile.<\/li>\n<li class=\"calibre3\">Start Chrome and navigate to <code class=\"calibre9\">https:\/\/localhost:5161\/<\/code>.<\/li>\n<li class=\"calibre3\">Navigate to <strong class=\"calibre2\">Customers in Germany<\/strong> and click the <strong class=\"calibre2\">+ Create New<\/strong> button.<\/li>\n<li class=\"calibre3\">\n<p class=\"rights\">Enter an invalid <strong class=\"calibre2\">Customer Id<\/strong> like <code class=\"calibre9\">ABCDEF<\/code><strong class=\"calibre2\">,<\/strong> leave the textbox, and note the validation message, as shown in <em class=\"calibre10\">Figure 16.4<\/em>:<\/p>\n<figure class=\"calibre24\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 16.4: Creating a new customer and entering an invalid customer ID\" height=\"686\" src=\"\/images\/cs12\/000107.png\" width=\"1428\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 16.4: Creating a new customer and entering an invalid customer ID<\/figcaption><\/figure>\n<\/li>\n<li class=\"calibre3\">Change <strong class=\"calibre2\">Customer Id<\/strong> to <code class=\"calibre9\">ABCDE<\/code>, enter values for the other textboxes like <code class=\"calibre9\">Alpha Corp<\/code>, <code class=\"calibre9\">Main Street<\/code>, and <code class=\"calibre9\">Germany<\/code>, and then click the <strong class=\"calibre2\">Create Customer<\/strong> button.<\/li>\n<li class=\"calibre3\">When the list of customers appears, click <strong class=\"calibre2\">Customers in Germany<\/strong>, scroll down to the bottom of the page to see the new customer.<\/li>\n<li class=\"calibre3\">On the <strong class=\"calibre2\">ABCDE<\/strong> customer row, click the <strong class=\"calibre2\">Edit<\/strong> icon button, change the address to something like <code class=\"calibre9\">Upper Avenue<\/code>, click the <strong class=\"calibre2\">Update<\/strong> button, and note that the customer record has been updated.<\/li>\n<li class=\"calibre3\">On the <strong class=\"calibre2\">ABCDE<\/strong> customer row, click the <strong class=\"calibre2\">Delete<\/strong> icon button, note the warning, click the <strong class=\"calibre2\">Delete Customer<\/strong> button, and note that the customer record has been deleted.<\/li>\n<li class=\"calibre3\">Close Chrome and shut down the web server.<\/li>\n<\/ol>\n<\/section>\n<\/section>\n<section data-number=\"17.5\" id=\"calibre_link-860\">\n<h2 data-number=\"17.5\" class=\"calibre5\">Enabling client-side execution using WebAssembly<\/h2>\n<p class=\"rights\">.NET 8 Release Candidate 1 had a Go Live license but the changes to Blazor were so ambitious that the client-side support was not finished in time for the final drafts of this book. We put the final section of this book online so that it could be updated to use the general availability release of .NET 8 which should complete the client-side functionality of Blazor. You can find the final section at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch16-blazor-wasm.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch16-blazor-wasm.md<\/a><\/p>\n<\/section>\n<section data-number=\"17.6\" id=\"calibre_link-861\">\n<h2 data-number=\"17.6\" class=\"calibre5\">Practicing and exploring<\/h2>\n<p class=\"rights\">Test your knowledge and understanding by answering some questions, getting some hands-on practice, and exploring this chapter's topics with deeper research.<\/p>\n<section data-number=\"17.6.1\" id=\"calibre_link-862\">\n<h3 data-number=\"17.6.1\" class=\"calibre8\">Exercise 16.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Answer the following questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the four Blazor render modes, and how are they different?<\/li>\n<li class=\"calibre3\">In a Blazor Web App project, compared to an ASP.NET Core MVC project, what extra configuration is required?<\/li>\n<li class=\"calibre3\">Why should you avoid the Blazor Server and Blazor Server Empty project templates?<\/li>\n<li class=\"calibre3\">In a Blazor Web App project, what does the <code class=\"calibre9\">App.razor<\/code> file do?<\/li>\n<li class=\"calibre3\">What is the main benefit of using the <code class=\"calibre9\">&lt;NavLink&gt;<\/code> component?<\/li>\n<li class=\"calibre3\">How can you pass a value into a component?<\/li>\n<li class=\"calibre3\">What is the main benefit of using the <code class=\"calibre9\">&lt;EditForm&gt;<\/code> component?<\/li>\n<li class=\"calibre3\">How can you execute some statements when parameters are set?<\/li>\n<li class=\"calibre3\">How can you execute some statements when a component appears?<\/li>\n<li class=\"calibre3\">One of the benefits of Blazor is being able to implement client-side components using C# and .NET instead of JavaScript. Does a Blazor component need any JavaScript?<\/li>\n<\/ol>\n<\/section>\n<section data-number=\"17.6.2\" id=\"calibre_link-863\">\n<h3 data-number=\"17.6.2\" class=\"calibre8\">Exercise 16.2 &ndash; Practice by creating a times table component<\/h3>\n<p class=\"rights\">In the <code class=\"calibre9\">Northwind.Blazor<\/code> project, create a routable page component that renders a times table based on a parameter named <code class=\"calibre9\">Number<\/code> and then test your component in two ways.First, by adding an instance of your component to the <code class=\"calibre9\">Home.razor<\/code> file, as shown in the following markup to generate the 6 times table with a default size of 12 rows or the 7 times table with a size of 10 rows:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;TimesTable Number=\"6\" \/&gt;\n&lt;TimesTable Number=\"7\" Size=\"10\" \/&gt;<\/code><\/pre>\n<\/div>\n<p class=\"rights\">Second, by entering a path in the browser address bar, as shown in the following links:<a href=\"https:\/\/localhost:5161\/timestable\/6https:\/\/localhost:5161\/timestable\/7\/10\">https:\/\/localhost:5161\/timestable\/6https:\/\/localhost:5161\/timestable\/7\/10<\/a><\/p>\n<\/section>\n<section data-number=\"17.6.3\" id=\"calibre_link-864\">\n<h3 data-number=\"17.6.3\" class=\"calibre8\">Exercise 16.3 &ndash; Practice by creating a country navigation item<\/h3>\n<p class=\"rights\">In the <code class=\"calibre9\">Northwind.Blazor<\/code> project, in the <code class=\"calibre9\">NavMenu<\/code> component, call the customer's web service to get the list of country names and loop through them, creating a menu item for each country. For example:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In the <code class=\"calibre9\">Northwind.Blazor<\/code> project, in <code class=\"calibre9\">INorthwindService.cs<\/code>, add the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">List&lt;string?&gt; GetCountries();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">NorthwindServiceServerSide.cs<\/code>, add the following code:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public List&lt;string?&gt; GetCountries()\n{\n  return _db.Customers.Select(c =&gt; c.Country)\n    .Distinct().OrderBy(country =&gt; country).ToList();\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In <code class=\"calibre9\">NavMenu.razor<\/code>, add the following markup:<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@inject INorthwindService _service\n...\n@foreach(string? country in _service.GetCountries())\n{\n    string countryLink = \"customers\/\" + country;\n    &lt;div class=\"nav-item px-3\"&gt;\n        &lt;NavLink class=\"nav-link\" href=\"@countryLink\"&gt;\n        &lt;span class=\"oi oi-people\" aria-hidden=\"true\"&gt;&lt;\/span&gt;\n        Customers in @country\n        &lt;\/NavLink&gt;\n    &lt;\/div&gt;\n}<\/code><\/pre>\n<\/div>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You cannot use <code class=\"calibre9\">&lt;NavLink class=\"nav-link\" href=\"customers\/@c\"&gt;<\/code> because Blazor does not allow combined text and <code class=\"calibre9\">@<\/code> Razor expressions in components. That is why the code above creates a local variable to do the combining to make the country URL.<\/p>\n<\/blockquote>\n<\/section>\n<section data-number=\"17.6.4\" id=\"calibre_link-865\">\n<h3 data-number=\"17.6.4\" class=\"calibre8\">Exercise 16.4 &ndash; Enhancing Blazor apps<\/h3>\n<p class=\"rights\">To learn how to enhance Blazor apps using AOT native publish, interop with JavaScript, and handle location-changing events, you can read an optional online-only section, found at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch16-enhanced-blazor.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch16-enhanced-blazor.md<\/a><\/p>\n<\/section>\n<section data-number=\"17.6.5\" id=\"calibre_link-866\">\n<h3 data-number=\"17.6.5\" class=\"calibre8\">Exercise 16.5 &ndash; Leveraging open source Blazor component libraries<\/h3>\n<p class=\"rights\">To learn how to use some common Blazor open source components, I have written an online-only section for my <em class=\"calibre10\">Apps and Services with .NET 8<\/em> companion book, found at the following link: <a href=\"https:\/\/github.com\/markjprice\/apps-services-net8\/blob\/main\/docs\/ch15-blazor-libraries.md\">https:\/\/github.com\/markjprice\/apps-services-net8\/blob\/main\/docs\/ch15-blazor-libraries.md<\/a>.<\/p>\n<\/section>\n<section data-number=\"17.6.6\" id=\"calibre_link-867\">\n<h3 data-number=\"17.6.6\" class=\"calibre8\">Exercise 16.6 &ndash; Explore topics<\/h3>\n<p class=\"rights\">Use the links on the following page to learn more details about the topics covered in this chapter:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-16---building-user-interfaces-using-blazor\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#chapter-16---building-user-interfaces-using-blazor<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"17.7\" id=\"calibre_link-868\">\n<h2 data-number=\"17.7\" class=\"calibre5\">Summary<\/h2>\n<p class=\"rights\">In this chapter, you learned:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">About the concepts of Blazor components.<\/li>\n<li class=\"calibre3\">How to build Blazor components that execute on the server side.<\/li>\n<li class=\"calibre3\">How to build Blazor components that execute on the client side using WebAssembly.<\/li>\n<li class=\"calibre3\">Some of the key differences between the two hosting models, like how data should be managed using dependency services.<\/li>\n<\/ul>\n<p class=\"rights\">In the <em class=\"calibre10\">Epilogue<\/em>, I will make some suggestions for books to take you deeper into C# and .NET.<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-2\">\n<div id=\"calibre_link-1945\" class=\"calibre1\">\n<section data-number=\"18\" id=\"calibre_link-869\">\n<h1 data-number=\"18\" class=\"title\">17 Epilogue<\/h1>\n<section data-number=\"18.1\" id=\"calibre_link-870\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"18.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000125.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">I wanted this book to be different from others on the market. I hope that you found it to be a brisk, fun read, packed with practical, hands-on walk-throughs of each subject. This epilogue contains the following short sections:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Next steps on your C# and .NET learning journey<\/li>\n<li class=\"calibre3\">The ninth edition, coming November 2024<\/li>\n<li class=\"calibre3\">Good luck!<\/li>\n<\/ul>\n<\/section>\n<section data-number=\"18.2\" id=\"calibre_link-871\">\n<h2 data-number=\"18.2\" class=\"calibre5\">Next steps on your C# and .NET learning journey<\/h2>\n<p class=\"rights\">For subjects that I didn\u2019t have space to include in this book but you might want to learn more about, I hope that the notes, good practice tips, and links in the GitHub repository point you in the right direction: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md<\/a><\/p>\n<section data-number=\"18.2.1\" id=\"calibre_link-872\">\n<h3 data-number=\"18.2.1\" class=\"calibre8\">Polishing your skills with design guidelines<\/h3>\n<p class=\"rights\">Now that you have learned the fundamentals of developing using C# and .NET, you are ready to improve the quality of your code by learning more detailed design guidelines. Back in the early .NET Framework era, Microsoft published a book that gave good practices in all areas of .NET development. Those recommendations are still very much applicable to modern .NET development. The following topics are covered:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Naming Guidelines<\/li>\n<li class=\"calibre3\">Type Design Guidelines<\/li>\n<li class=\"calibre3\">Member Design Guidelines<\/li>\n<li class=\"calibre3\">Designing for Extensibility<\/li>\n<li class=\"calibre3\">Design Guidelines for Exceptions<\/li>\n<li class=\"calibre3\">Usage Guidelines<\/li>\n<li class=\"calibre3\">Common Design Patterns<\/li>\n<\/ul>\n<p class=\"rights\">To make the guidance as easy to follow as possible, the recommendations are simply labeled with the terms <strong class=\"calibre2\">Do<\/strong>, <strong class=\"calibre2\">Consider<\/strong>, <strong class=\"calibre2\">Avoid<\/strong>, and <strong class=\"calibre2\">Do not<\/strong>. Microsoft has made excerpts of the book available at the following link:<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/design-guidelines\/\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/design-guidelines\/<\/a>I strongly recommend that you review all the guidelines and apply them to your code.<\/p>\n<\/section>\n<section data-number=\"18.2.2\" id=\"calibre_link-873\">\n<h3 data-number=\"18.2.2\" class=\"calibre8\">Companion books to continue your learning journey<\/h3>\n<p class=\"rights\">Soon, I will have written two more books to continue your learning journey with .NET 8 that you started with this fundamentals book. The two other books act as companions to this book, and together they all form a .NET 8 trilogy.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">The first book (the one you're reading now) covers the fundamentals of C#, .NET, and ASP.NET Core for web development.<\/li>\n<li class=\"calibre3\">The second book covers more specialized topics, like internationalization and popular third-party packages including Serilog and Noda Time. You will learn how to build native AOT-compiled services with ASP.NET Core Minimal APIs and how to improve performance, scalability, and reliability using caching, queues, and background services. You will implement more services using GraphQL, gRPC, SignalR, and Azure Functions. Finally, you will learn how to build graphical user interfaces for websites and desktop and mobile apps with Blazor and .NET MAUI.<\/li>\n<li class=\"calibre3\">The third book covers important tools and skills you should learn to become a well-rounded professional .NET developer. These include design patterns and solution architecture, debugging, memory analysis, all the important types of testing, from unit to performance and web and mobile, and then hosting and deployment topics like Docker and Azure Pipelines. Finally, we will look at how to prepare for an interview to get the .NET developer career that you want.<\/li>\n<\/ol>\n<p class=\"rights\">A summary of the .NET 8 trilogy and their most important topics is shown in <em class=\"calibre10\">Figure 17.1<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 17.1: Companion books for learning C# and .NET\" height=\"1222\" src=\"\/images\/cs12\/000142.png\" width=\"2126\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 17.1: Companion books for learning C# and .NET<\/figcaption><\/figure>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><em class=\"calibre10\">Tools and Skills for .NET 8 Pros<\/em> is scheduled to be published in the first half of 2024. Look out for it in your favorite bookstore to complete your .NET 8 trilogy.<\/p>\n<\/blockquote>\n<p class=\"rights\">To see a list of all the books that I have published with Packt, you can use the following link:<a href=\"https:\/\/subscription.packtpub.com\/search?query=mark+j.+price\">https:\/\/subscription.packtpub.com\/search?query=mark+j.+price<\/a><\/p>\n<\/section>\n<section data-number=\"18.2.3\" id=\"calibre_link-874\">\n<h3 data-number=\"18.2.3\" class=\"calibre8\">Other books to take your learning further<\/h3>\n<p class=\"rights\">If you are looking for other books from my publisher that cover related subjects, there are many to choose from, as shown in <em class=\"calibre10\">Figure 17.2<\/em>:<\/p>\n<figure class=\"calibre11\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Figure 17.2: Packt books to take your C# and .NET learning further\" height=\"1406\" src=\"\/images\/cs12\/000058.png\" width=\"2361\" class=\"calibre12\" \/><figcaption aria-hidden=\"true\" class=\"calibre13\">Figure 17.2: Packt books to take your C# and .NET learning further<\/figcaption><\/figure>\n<p class=\"rights\">You will also find a list of Packt books in the GitHub repository at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#learn-from-other-packt-books\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/book-links.md#learn-from-other-packt-books<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"18.3\" id=\"calibre_link-875\">\n<h2 data-number=\"18.3\" class=\"calibre5\">The ninth edition, coming November 2024<\/h2>\n<p class=\"rights\">I have already started work identifying areas for improvement for the ninth edition, which we plan to publish with the release of .NET 9 in November 2024. While I do not expect major new features at the level of the unification of Blazor hosting models, I do expect .NET 9 to make worthwhile improvements to all aspects of .NET. You can learn how to use .NET 9 with this book at the following link:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/dotnet9.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/dotnet9.md<\/a>If you have suggestions for topics that you would like to see covered or expanded upon, or you spot mistakes that need fixing in the text or code, then please let me know the details via chat in the Discord channel or the GitHub repository for this book, found at the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\">https:\/\/github.com\/markjprice\/cs12dotnet8<\/a><\/p>\n<\/section>\n<section data-number=\"18.4\" id=\"calibre_link-876\">\n<h2 data-number=\"18.4\" class=\"calibre5\">Good luck!<\/h2>\n<p class=\"rights\">I wish you the best of luck with all your C# and .NET projects!<\/p>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n<div class=\"calibre\" id=\"calibre_link-932\">\n<div id=\"calibre_link-1946\" class=\"calibre1\">\n<section data-number=\"19\" id=\"calibre_link-877\">\n<h1 data-number=\"19\" class=\"title\">Appendix: Answers to the Test Your Knowledge Questions<\/h1>\n<section data-number=\"19.1\" id=\"calibre_link-878\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.1\" class=\"calibre5\">Join our book community on Discord<\/h2>\n<p class=\"rights\"><a href=\"https:\/\/packt.link\/EarlyAccess\">https:\/\/packt.link\/EarlyAccess<\/a><\/p>\n<p class=\"rights\"><img loading=\"lazy\" decoding=\"async\" alt=\"Qr code Description automatically generated\" height=\"283\" src=\"\/images\/cs12\/000074.png\" width=\"283\" class=\"calibre6\" \/><\/p>\n<p class=\"rights\">This appendix has the answers to the questions in the <strong class=\"calibre2\">Test Your Knowledge<\/strong> section at the end of each chapter.<\/p>\n<\/section>\n<section data-number=\"19.2\" id=\"calibre_link-879\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.2\" class=\"calibre5\">Chapter 1 &ndash; Hello, C#! Welcome, .NET!<\/h2>\n<section data-number=\"19.2.1\" id=\"calibre_link-880\">\n<h3 data-number=\"19.2.1\" class=\"calibre8\">Exercise 1.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Is Visual Studio 2022 better than Visual Studio Code?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: No. Each is optimized for different tasks. Visual Studio 2022 for Windows is large, heavyweight, and can create applications with graphical user interfaces, for example, Windows Forms, WPF, UWP, and .NET MAUI apps, but it is only available on Windows. Visual Studio 2022 is an <strong class=\"calibre2\">Interactive Development Environment<\/strong> (<strong class=\"calibre2\">IDE<\/strong>) rather than a code editor. Visual Studio Code is smaller, more lightweight, code-focused, supports many more languages, and is available cross-platform.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Is .NET 5 and later better than .NET Framework?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: For modern development, yes, but it depends on what you need. .NET 5 and later are modern, cross-platform, performance-oriented versions of the legacy, mature .NET Framework. Modern .NET is more frequently improved. .NET Framework has better support for legacy applications; however, .NET Framework 4.8 will be the last release apart from security and bug fixes. It will never support some language features of C# 8 and later.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is .NET Standard and why is it still important?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: .NET Standard defines an API, aka contract, that a .NET platform can implement. The latest versions of .NET Framework, Xamarin, and modern .NET implement .NET Standard 2.0 to provide a single, standard API that developers can target for maximum reuse. .NET Core 3.0 or later implement .NET Standard 2.1, which has some new features not supported by .NET Framework. If you want to create a new class library that supports all .NET platforms, you will need it to be .NET Standard 2.0-compatible.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why can a programmer use different languages, for example, C# and F#, to write applications that run on .NET?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Multiple languages are supported on .NET because each one has a compiler that translates the source code into <strong class=\"calibre2\">intermediate language<\/strong> (<strong class=\"calibre2\">IL<\/strong>) code. This IL code is then compiled to native CPU instructions at runtime by the <strong class=\"calibre2\">Common Language Runtime<\/strong> (<strong class=\"calibre2\">CLR<\/strong>).<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is a top-level program and how do you access any command-line arguments?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A top-level program is a project that does not need to explicitly define a <code class=\"calibre9\">Program<\/code> class with a <code class=\"calibre9\">Main<\/code> method entry point, with a parameter named <code class=\"calibre9\">args<\/code>, to access any command-line arguments. These are implicitly defined for you so that you can type statements without boilerplate code.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the name of the entry point method of a .NET console app and how should it be explicitly declared if you are not using the top-level program feature?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The entry point of a .NET console app is the <code class=\"calibre9\">Main<\/code> method. An optional <code class=\"calibre9\">string<\/code> array for command-line arguments and a return type of <code class=\"calibre9\">int<\/code> are recommended, but they are not required. They can be explicitly declared, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public static void Main() \/\/ minimum\npublic static int Main(string[] args) \/\/ recommended<\/code><\/pre>\n<\/div>\n<p class=\"rights\">With .NET 6 and later, it is implicitly declared using the top-level program feature, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public static int &lt;Main&gt;$(String[] args) \/\/ compiler-generated<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">What namespace is the <code class=\"calibre9\">Program<\/code> class defined in with a top-level program?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: With a top-level program, the <code class=\"calibre9\">Program<\/code> class is defined in a <code class=\"calibre9\">null<\/code> namespace.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Where would you look for help with a C# keyword?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The Microsoft Learn website. Specifically, C# keywords are documented at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/<\/a>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Where would you look first for solutions to common programming problems?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <a href=\"https:\/\/stackoverflow.com\/\">https:\/\/stackoverflow.com\/<\/a>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What should you do after getting an AI to write code for you?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You should never trust the code written by an AI so test it thoroughly.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.3\" id=\"calibre_link-881\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.3\" class=\"calibre5\">Chapter 2 &ndash; Speaking C#<\/h2>\n<section data-number=\"19.3.1\" id=\"calibre_link-882\">\n<h3 data-number=\"19.3.1\" class=\"calibre8\">Exercise 2.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What statement can you type in a C# file to discover the compiler and language version?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">#error version<\/code><\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the two types of comments in C#?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The two types of comments in C# are a single-line comment prefixed with <code class=\"calibre9\">\/\/<\/code> and a multi-line comment starting with <code class=\"calibre9\">\/*<\/code> and ending with <code class=\"calibre9\">*\/<\/code>. There are also XML comments, which are introduced in <em class=\"calibre10\">Chapter 4<\/em>, <em class=\"calibre10\">Writing, Debugging, and Testing Functions<\/em>, so I would not expect you to know about them yet.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between a verbatim <code class=\"calibre9\">string<\/code> and an interpolated <code class=\"calibre9\">string<\/code>?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A verbatim <code class=\"calibre9\">string<\/code> is prefixed with the <code class=\"calibre9\">@<\/code> symbol and each character (except <code class=\"calibre9\">\"<\/code>) is interpreted as itself; for example, a backslash <code class=\"calibre9\">\\<\/code> is a backslash <code class=\"calibre9\">\\<\/code>. An interpolated <code class=\"calibre9\">string<\/code> is prefixed with the <code class=\"calibre9\">$<\/code> symbol and can include expressions surrounded with braces like this: <code class=\"calibre9\">{expression}<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why should you be careful when using <code class=\"calibre9\">float<\/code> and <code class=\"calibre9\">double<\/code> values?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You should be careful when using <code class=\"calibre9\">float<\/code> and <code class=\"calibre9\">double<\/code> values because they are not guaranteed to be accurate, especially when performing equality comparisons.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How can you determine how many bytes a type like <code class=\"calibre9\">double<\/code> uses in memory?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You can determine how many bytes a type like <code class=\"calibre9\">double<\/code> uses in memory by using the <code class=\"calibre9\">sizeof()<\/code> operator, for example, <code class=\"calibre9\">sizeof(double)<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">When should you use the <code class=\"calibre9\">var<\/code> keyword?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You should only use the <code class=\"calibre9\">var<\/code> keyword to declare local variables when you cannot specify a known type. It is easy to overuse <code class=\"calibre9\">var<\/code> due to its convenience when initially writing code, but its use can make it harder to maintain code later.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the newest syntax to create an instance of a class like <code class=\"calibre9\">XmlDocument<\/code>?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The newest way to create an instance of a class like <code class=\"calibre9\">XmlDocument<\/code> is to use a <strong class=\"calibre2\">target-typed new<\/strong> expression, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">XmlDocument doc = new();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why should you be careful when using the <code class=\"calibre9\">dynamic<\/code> type?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You should be careful when using the <code class=\"calibre9\">dynamic<\/code> type because the type of object stored in it is not checked until runtime, which can mean runtime exceptions being thrown if you attempt to use a member that does not exist on the type.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How do you right-align a format <code class=\"calibre9\">string<\/code>?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To right-align a format <code class=\"calibre9\">string<\/code>, after the index or expression, add a comma and an integer value to specify a column width within which to align the value. Positive integers mean right-aligned and negative integers mean left-aligned.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What character separates arguments for a console app?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The space character separates arguments for a console app.<\/p>\n<\/section>\n<section data-number=\"19.3.2\" id=\"calibre_link-883\">\n<h3 data-number=\"19.3.2\" class=\"calibre8\">Exercise 2.2 &ndash; Test your knowledge of number types<\/h3>\n<p class=\"rights\">What type would you choose for the following \"numbers\"?<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">A person's telephone number.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">string<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">A person's height.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">float<\/code> or <code class=\"calibre9\">double<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">A person's age.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">int<\/code> for best performance on most CPUs or <code class=\"calibre9\">byte<\/code> (0 to 255) for the smallest size.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">A person's salary.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">decimal<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">A book's ISBN.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">string<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">A book's price.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">decimal<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">A book's shipping weight.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">float<\/code> or <code class=\"calibre9\">double<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">A country's population.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">uint<\/code> (0 to about 4 billion).<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">The number of stars in the universe.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">ulong<\/code> (0 to about 18 quadrillion) or <code class=\"calibre9\">System.Numerics.BigInteger<\/code> (allows an arbitrarily large integer).<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">The number of employees in each of the small or medium businesses in the United Kingdom (up to about 50,000 employees per business).<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Since there are hundreds of thousands of small or medium businesses, we need to take memory size as the determining factor, so choose <code class=\"calibre9\">ushort<\/code>, because it only takes 2 bytes compared to an <code class=\"calibre9\">int<\/code>, which takes 4 bytes.<\/p>\n<\/section>\n<section data-number=\"19.3.3\" id=\"calibre_link-884\">\n<h3 data-number=\"19.3.3\" class=\"calibre8\">Exercise 2.3 &ndash; Practice number sizes and ranges<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter02\/Ch02Ex03Numbers\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter02\/Ch02Ex03Numbers<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.4\" id=\"calibre_link-885\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.4\" class=\"calibre5\">Chapter 3 &ndash; Controlling Flow, Converting Types, and Handling Exceptions<\/h2>\n<section data-number=\"19.4.1\" id=\"calibre_link-886\">\n<h3 data-number=\"19.4.1\" class=\"calibre8\">Exercise 3.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What happens when you divide an <code class=\"calibre9\">int<\/code> variable by <code class=\"calibre9\">0<\/code>?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">DivideByZeroException<\/code> is thrown when dividing an integer or decimal by <code class=\"calibre9\">0<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What happens when you divide a <code class=\"calibre9\">double<\/code> variable by <code class=\"calibre9\">0<\/code>?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">double<\/code> type contains a special value of <code class=\"calibre9\">Infinity<\/code>. Instances of floating-point numbers can have the special values of <code class=\"calibre9\">NaN<\/code> (not a number), or in the case of dividing by <code class=\"calibre9\">0<\/code>, either <code class=\"calibre9\">PositiveInfinity<\/code> or <code class=\"calibre9\">NegativeInfinity<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What happens when you overflow an <code class=\"calibre9\">int<\/code> variable, that is, set it to a value beyond its range?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: It will loop unless you wrap the statement in a <code class=\"calibre9\">checked<\/code> block, in which case, <code class=\"calibre9\">OverflowException<\/code> will be thrown.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between <code class=\"calibre9\">x = y++;<\/code> and <code class=\"calibre9\">x = ++y;<\/code>?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: In the statement <code class=\"calibre9\">x = y++;<\/code>, the current value of <code class=\"calibre9\">y<\/code> will be assigned to <code class=\"calibre9\">x<\/code> and then <code class=\"calibre9\">y<\/code> will be incremented, and in the statement <code class=\"calibre9\">x = ++y;<\/code>, the value of <code class=\"calibre9\">y<\/code> will be incremented and then the result will be assigned to <code class=\"calibre9\">x<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between <code class=\"calibre9\">break<\/code>, <code class=\"calibre9\">continue<\/code>, and <code class=\"calibre9\">return<\/code> when used inside a loop statement?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">break<\/code> statement will end the whole loop and continue executing after the loop, the <code class=\"calibre9\">continue<\/code> statement will end the current iteration of the loop and continue executing at the start of the loop block for the next iteration, and the <code class=\"calibre9\">return<\/code> statement will end the current method call and continue executing after the method call.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the three parts of a <code class=\"calibre9\">for<\/code> statement and which of them are required?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The three parts of a <code class=\"calibre9\">for<\/code> statement are the initializer, condition, and incrementer expressions. All three parts are optional. If the condition is missing, then it will loop forever unless you break out of the loop using <code class=\"calibre9\">break<\/code>, <code class=\"calibre9\">return<\/code>, or something else.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between the <code class=\"calibre9\">=<\/code> and <code class=\"calibre9\">==<\/code> operators?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">=<\/code> operator is the assignment operator for assigning values to variables, while the <code class=\"calibre9\">==<\/code> operator is the equality check operator that returns <code class=\"calibre9\">true<\/code> or <code class=\"calibre9\">false<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Does the following statement compile? <code class=\"calibre9\">for ( ; ; ) ;<\/code><\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Yes. The <code class=\"calibre9\">for<\/code> statement only requires the semicolons to separate the initializer expression, condition expression, and incrementer expressions. All three expressions are optional, so they can be missing. This <code class=\"calibre9\">for<\/code> statement will execute the empty <code class=\"calibre9\">;<\/code> statement after the closing brace, forever. It is an example of an infinite loop.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does the underscore <code class=\"calibre9\">_<\/code> represent in a <code class=\"calibre9\">switch<\/code> expression?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The underscore <code class=\"calibre9\">_<\/code> represents the default return value. It is called a discard because it is used to represent a potential variable that is not needed. It can be used not just in <code class=\"calibre9\">switch<\/code> expressions but also in other scenarios where a placeholder variable must be declared but its value is not needed, like parameters to lambda expressions and tuple deconstruction.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What interface must an object \"implement\" to be enumerated over by using the <code class=\"calibre9\">foreach<\/code> statement?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: An object must \"implement\" the <code class=\"calibre9\">IEnumerable<\/code> interface. It must have the correct methods with the correct signatures even if the object does not actually implement the interface.<\/p>\n<\/section>\n<section data-number=\"19.4.2\" id=\"calibre_link-887\">\n<h3 data-number=\"19.4.2\" class=\"calibre8\">Exercise 3.2 &ndash; Explore loops and overflow<\/h3>\n<p class=\"rights\">What will happen if this code executes?<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">int max = 500;\nfor (byte i = 0; i &lt; max; i++)\n{\n  WriteLine(i);\n}<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>:The code will loop forever because the value of <code class=\"calibre9\">i<\/code> can only be between <code class=\"calibre9\">0<\/code> and <code class=\"calibre9\">255<\/code>. Once <code class=\"calibre9\">i<\/code> gets incremented beyond <code class=\"calibre9\">255<\/code>, it loops back to <code class=\"calibre9\">0<\/code> and, therefore, will always be less than <code class=\"calibre9\">max<\/code> (<code class=\"calibre9\">500<\/code>).To prevent the infinite loop, you can add a checked statement around the code. This would cause an exception to be thrown after <code class=\"calibre9\">255<\/code> due to the overflow, as shown in the following output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">254\n255\nSystem.OverflowException says Arithmetic operation resulted in an overflow.<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter03\/Ch03Ex02LoopsAndOverflow\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter03\/Ch03Ex02LoopsAndOverflow<\/a><\/p>\n<\/section>\n<section data-number=\"19.4.3\" id=\"calibre_link-888\">\n<h3 data-number=\"19.4.3\" class=\"calibre8\">Exercise 3.3 &ndash; Test your knowledge of operators<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter03\/Ch03Ex03Operators\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter03\/Ch03Ex03Operators<\/a><\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the values of <code class=\"calibre9\">x<\/code> and <code class=\"calibre9\">y<\/code> after the following statements execute?<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">x = 3;\ny = 2 + ++x;<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">x<\/code> is <code class=\"calibre9\">4<\/code> and <code class=\"calibre9\">y<\/code> is <code class=\"calibre9\">6<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the values of <code class=\"calibre9\">x<\/code> and <code class=\"calibre9\">y<\/code> after the following statements execute?<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">x = 3 &lt;&lt; 2;\ny = 10 &gt;&gt; 1;<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">x<\/code> is <code class=\"calibre9\">12<\/code> and <code class=\"calibre9\">y<\/code> is <code class=\"calibre9\">5<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the values of <code class=\"calibre9\">x<\/code> and <code class=\"calibre9\">y<\/code> after the following statements execute?<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">x = 10 &amp; 8;\ny = 10 | 7;<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">x<\/code> is <code class=\"calibre9\">8<\/code> and <code class=\"calibre9\">y<\/code> is <code class=\"calibre9\">15<\/code>.<\/p>\n<\/section>\n<section data-number=\"19.4.4\" id=\"calibre_link-889\">\n<h3 data-number=\"19.4.4\" class=\"calibre8\">Exercise 3.4 &ndash; Practice loops and operators<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter03\/Ch03Ex04FizzBuzz\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter03\/Ch03Ex04FizzBuzz<\/a><\/p>\n<\/section>\n<section data-number=\"19.4.5\" id=\"calibre_link-890\">\n<h3 data-number=\"19.4.5\" class=\"calibre8\">Exercise 3.5 &ndash; Practice exception handling<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter03\/Ch03Ex05Exceptions\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter03\/Ch03Ex05Exceptions<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.5\" id=\"calibre_link-891\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.5\" class=\"calibre5\">Chapter 4 &ndash; Writing, Debugging, and Testing Functions<\/h2>\n<section data-number=\"19.5.1\" id=\"calibre_link-892\">\n<h3 data-number=\"19.5.1\" class=\"calibre8\">Exercise 4.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does the C# keyword <code class=\"calibre9\">void<\/code> mean?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: It indicates that a method has no return value.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are some differences between imperative and functional programming styles?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: An imperative programming style means writing a sequence of statements that the runtime executes step by step like a recipe. Your code tells the runtime exactly how to perform the task. Do this. Now do that. It has variables meaning that the state can change at any time, including outside the current function. Imperative programming causes side effects, changing the value of some state somewhere in your program. Side effects are tricky to debug. A functional programming style describes what you want to achieve instead of how. It can also be described as declarative. But the most important point is that functional programming languages make all states immutable by default to avoid side effects.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In Visual Studio Code or Visual Studio, what is the difference between pressing <span>F5<\/span>, <span>Ctrl<\/span> or <span>Cmd<\/span> + <span>F5<\/span>, <span>Shift<\/span> + <span>F5<\/span>, and <span>Ctrl<\/span> or <span>Cmd<\/span> + <span>Shift<\/span> + <span>F5<\/span>?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <span>F5<\/span> saves, compiles, runs, and attaches the debugger; <span>Ctrl<\/span> or <span>Cmd<\/span> + <span>F5<\/span> saves, compiles, and runs the application without the debugger attached; <span>Shift<\/span> + <span>F5<\/span> stops the debugger and running application; and <span>Ctrl<\/span> or <span>Cmd<\/span> + <span>Shift<\/span> + <span>F5<\/span> restarts the application without the debugger attached.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Where does the <code class=\"calibre9\">Trace.WriteLine<\/code> method write its output to?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">Trace.WriteLine<\/code> writes its output to any configured trace listeners. By default, this includes the terminal or the command line but can be configured to be a text file or any custom listener.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the five trace levels?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: 0 = Off, 1 = Error, 2 = Warning, 3 = Info, and 4 = Verbose.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between the <code class=\"calibre9\">Debug<\/code> and <code class=\"calibre9\">Trace<\/code> classes?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">Debug<\/code> is active only during development. <code class=\"calibre9\">Trace<\/code> is active during development and after release into production.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">When writing a unit test, what are the three \u201cA\u201ds?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Arrange, Act, and Assert.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">When writing a unit test using xUnit, what attribute must you decorate the test methods with?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">[Fact]<\/code> or <code class=\"calibre9\">[Theory]<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What <code class=\"calibre9\">dotnet<\/code> command executes xUnit tests?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">dotnet test<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What statement should you use to rethrow a caught exception named <code class=\"calibre9\">ex<\/code> without losing the stack trace?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Use <code class=\"calibre9\">throw;<\/code>. Do not use <code class=\"calibre9\">throw ex;<\/code> because this will lose stack trace information.<\/p>\n<\/section>\n<section data-number=\"19.5.2\" id=\"calibre_link-893\">\n<h3 data-number=\"19.5.2\" class=\"calibre8\">Exercise 4.2 &ndash; Practice writing functions with debugging and unit testing<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter04\/Ch04Ex02PrimeFactorsLibhttps:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter04\/Ch04Ex02PrimeFactorsTestshttps:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter04\/Ch04Ex02PrimeFactorsApp\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter04\/Ch04Ex02PrimeFactorsLibhttps:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter04\/Ch04Ex02PrimeFactorsTestshttps:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter04\/Ch04Ex02PrimeFactorsApp<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.6\" id=\"calibre_link-894\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.6\" class=\"calibre5\">Chapter 5 &ndash; Building Your Own Types with Object-Oriented Programming<\/h2>\n<section data-number=\"19.6.1\" id=\"calibre_link-895\">\n<h3 data-number=\"19.6.1\" class=\"calibre8\">Exercise 5.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the seven access modifier keywords and combinations of keywords and what do they do?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The seven combinations of access modifier keywords and their effects are described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">private<\/code>: This modifier makes a type or member only visible inside the class.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">internal<\/code>: This modifier makes a type or member only visible inside the same assembly.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">protected<\/code>: This modifier makes a type or member only visible inside the class or derived classes.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">internal protected<\/code>: This modifier makes a type or member only visible inside the class, derived classes, or within the same assembly.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">private protected<\/code>: This modifier makes a type or member only visible inside the class or derived classes that are within the same assembly.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">public<\/code>: This modifier makes a type or member visible everywhere.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">file<\/code>: This modifier makes a type visible only within the same code file. It cannot be applied to a member.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between the <code class=\"calibre9\">static<\/code>, <code class=\"calibre9\">const<\/code>, and <code class=\"calibre9\">readonly<\/code> keywords when applied to a type member?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The difference between the <code class=\"calibre9\">static<\/code>, <code class=\"calibre9\">const<\/code>, and <code class=\"calibre9\">readonly<\/code> keywords when applied to a type member is described in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">static<\/code>: This keyword makes the member shared by all instances and it must be accessed through the type, not an instance of the type.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">const<\/code>: This keyword makes the field a fixed literal value that must never change because, during the compilation, assemblies that use the field copy the literal value at the time of compilation.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">readonly<\/code>: This keyword restricts the field so that it can only be assigned to using a constructor or field initializer at runtime.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does a constructor do?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A constructor allocates memory and initializes field values.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why do you need to apply the <code class=\"calibre9\">[Flags]<\/code> attribute to an <code class=\"calibre9\">enum<\/code> type when you want to store combined values?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: If you don't apply the <code class=\"calibre9\">[Flags]<\/code> attribute to an <code class=\"calibre9\">enum<\/code> type when you want to store combined values, then a stored <code class=\"calibre9\">enum<\/code> value that is a combination will be returned by a call to <code class=\"calibre9\">ToString<\/code> as the stored integer value, instead of one or more of the comma-separated list of text values.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why is the <code class=\"calibre9\">partial<\/code> keyword useful?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You can use the <code class=\"calibre9\">partial<\/code> keyword to split the definition of a type over multiple files.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is a tuple?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A tuple is a data structure consisting of multiple parts. It is used when you want to store multiple values as a unit without defining a type for them.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does the <code class=\"calibre9\">record<\/code> keyword do?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">record<\/code> keyword defines a data structure that is immutable by default to enable a more functional programming style. Like a class, a record can have properties and methods, but the values of properties can only be set during initialization.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does overloading mean?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Overloading is when you define more than one method with the same method name and different input parameters.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between the following two statements? (Do not just say a \"&gt;\" character!)<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public List&lt;Person&gt; Children = new();\npublic List&lt;Person&gt; Children =&gt; new();<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The first statement defines a field named <code class=\"calibre9\">Children<\/code> and initializes it to an empty list of <code class=\"calibre9\">Person<\/code> objects. The second statement defines a read-only property named <code class=\"calibre9\">Children<\/code> that returns an empty list of <code class=\"calibre9\">Person<\/code> objects. A field is a data storage location that can be referenced. A property is one or a pair of methods that get and\/or set a value. The value of a property is often stored in a private field. A read-only property only has a <code class=\"calibre9\">get<\/code> method that can be implemented using lambda expression syntax.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How do you make a method parameter optional?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You make a method parameter optional by assigning a default value to it in the method signature.<\/p>\n<\/section>\n<section data-number=\"19.6.2\" id=\"calibre_link-896\">\n<h3 data-number=\"19.6.2\" class=\"calibre8\">Exercise 5.2 &ndash; Practice with access modifiers<\/h3>\n<p class=\"rights\">The code given in this exercise will cause the compiler to show the following errors:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">Error CS0122 'Car' is inaccessible due to its protection level\nError CS0122 'Car.Start()' is inaccessible due to its protection level\nError CS0122 'Car.Wheels' is inaccessible due to its protection level<\/code><\/pre>\n<\/div>\n<p class=\"rights\">In the class library project, in <code class=\"calibre9\">Car.cs<\/code>, you would need to apply the <code class=\"calibre9\">public<\/code> access modifier to the class because the default access modifier for a type is <code class=\"calibre9\">internal<\/code>, and to the two properties and the method because the default access modifier for a member is <code class=\"calibre9\">private<\/code>, as shown highlighted in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class Car\n{\n  public int Wheels { get; set; }\n  public public bool IsEV { get; set; }\n  public void Start()\n  {\n    Console.WriteLine(\"Starting...\");\n  }\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<\/section>\n<section data-number=\"19.7\" id=\"calibre_link-897\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.7\" class=\"calibre5\">Chapter 6 &ndash; Implementing Interfaces and Inheriting Classes<\/h2>\n<section data-number=\"19.7.1\" id=\"calibre_link-898\">\n<h3 data-number=\"19.7.1\" class=\"calibre8\">Exercise 6.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is a delegate?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A delegate is a type-safe method reference. It can be used to execute any method with a matching signature.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is an event?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: An event is a field that is a delegate having the <code class=\"calibre9\">event<\/code> keyword applied. The keyword ensures that only <code class=\"calibre9\">+=<\/code> and <code class=\"calibre9\">-=<\/code> are used; this safely combines multiple delegates without replacing any existing event handlers.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How are a base class and a derived class related and how can the derived class access the base class?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A derived class (or subclass) is a class that inherits from a base class (or superclass). Inside a derived class, you use the <code class=\"calibre9\">base<\/code> keyword to access the class that the subclass inherits from.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between <code class=\"calibre9\">is<\/code> and <code class=\"calibre9\">as<\/code> operators?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">is<\/code> operator returns <code class=\"calibre9\">true<\/code> if an object can be cast to the type; otherwise, it returns <code class=\"calibre9\">false<\/code>. The <code class=\"calibre9\">as<\/code> operator returns a reference to the object if an object can be cast to the type; otherwise, it returns <code class=\"calibre9\">null<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Which keyword is used to prevent a class from being derived from or a method from being overridden?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">sealed<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Which keyword is used to prevent a class from being instantiated with the <code class=\"calibre9\">new<\/code> keyword?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">abstract<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Which keyword is used to allow a member to be overridden?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">virtual<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What's the difference between a destructor and a deconstruct method?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A destructor, also known as a finalizer, must be used to release resources owned by the object. A deconstruct method is a feature of C# 7 or later that allows a complex object to be broken down into smaller parts. It is especially useful when working with tuples.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the signatures of the constructors that all exceptions should have?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The signatures of the three constructors that all exceptions should have are shown in the following list:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A constructor with no parameters.<\/li>\n<li class=\"calibre3\">A constructor with a <code class=\"calibre9\">string<\/code> parameter, usually named <code class=\"calibre9\">message<\/code>.<\/li>\n<li class=\"calibre3\">A constructor with a <code class=\"calibre9\">string<\/code> parameter, usually named <code class=\"calibre9\">message<\/code>, and an <code class=\"calibre9\">Exception<\/code> parameter, usually named <code class=\"calibre9\">innerException<\/code>.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is an extension method, and how do you define one?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: An extension method is a compiler trick that makes a <code class=\"calibre9\">static<\/code> method of a <code class=\"calibre9\">static<\/code> class appear to be one of the members of another type. You define which type you want to extend by prefixing the first parameter of that type in the method with the <code class=\"calibre9\">this<\/code> keyword.<\/p>\n<\/section>\n<section data-number=\"19.7.2\" id=\"calibre_link-899\">\n<h3 data-number=\"19.7.2\" class=\"calibre8\">Exercise 6.2 &ndash; Practice creating an inheritance hierarchy<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter06\/Ch06Ex02Inheritance\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter06\/Ch06Ex02Inheritance<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.8\" id=\"calibre_link-900\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.8\" class=\"calibre5\">Chapter 7 &ndash; Packaging and Distributing .NET Types<\/h2>\n<section data-number=\"19.8.1\" id=\"calibre_link-901\">\n<h3 data-number=\"19.8.1\" class=\"calibre8\">Exercise 7.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between a namespace and an assembly?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A namespace is the logical container of a type. An assembly is the physical container of a type. To use a type, the developer must reference its assembly. Optionally, the developer can import its namespace, or specify the namespace when specifying the type.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How do you reference another project in a <code class=\"calibre9\">.csproj<\/code> file?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You reference another project in a <code class=\"calibre9\">.csproj<\/code> file by adding a <code class=\"calibre9\">&lt;ProjectReference&gt;<\/code> element that sets its <code class=\"calibre9\">Include<\/code> attribute to a path to the reference project file inside an <code class=\"calibre9\">&lt;ItemGroup&gt;<\/code> element, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;ItemGroup&gt;\n  &lt;ProjectReference Include=\"..\\Calculator\\Calculator.csproj\" \/&gt;\n&lt;\/ItemGroup&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the benefit of a tool like ILSpy?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A benefit of a tool like ILSpy is learning how to write code in C# for the .NET platform by seeing how other packages are written. You should never steal their intellectual property, of course. But it is especially useful to see how the Microsoft developers have implemented key components of the base class libraries. Decompiling can also be useful when calling a third-party library and you need to better understand how it works to call it appropriately.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Which .NET type does the C# <code class=\"calibre9\">float<\/code> alias represent?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">System.Single<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">When porting an application from .NET Framework to modern .NET, what tool should you run before porting, and what tool could you run to perform much of the porting work?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You should use the .NET Portability Analyzer before porting an application from .NET Framework to .NET 6. You could use the .NET Upgrade Assistant to perform much of the porting work.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between framework-dependent and self-contained deployments of .NET applications?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Framework-dependent modern .NET applications require .NET to be installed for an operating system to execute. Self-contained .NET applications include everything necessary to execute on their own.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is a RID?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <strong class=\"calibre2\">RID<\/strong> is the acronym for <strong class=\"calibre2\">Runtime Identifier<\/strong>. RID values are used to identify target platforms where a .NET application runs.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between the <code class=\"calibre9\">dotnet pack<\/code> and <code class=\"calibre9\">dotnet publish<\/code> commands?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">dotnet pack<\/code> command creates a NuGet package that could then be uploaded to a NuGet feed like Microsoft's. The <code class=\"calibre9\">dotnet publish<\/code> command puts the application and its dependencies into a folder for deployment to a hosting system.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What types of applications written for .NET Framework can be ported to modern .NET?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Console, ASP.NET MVC, ASP.NET Web API, Windows Forms, and <strong class=\"calibre2\">Windows Presentation Foundation<\/strong> (<strong class=\"calibre2\">WPF<\/strong>) apps.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Can you use packages written for .NET Framework with modern .NET?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Yes, if they only call APIs in .NET Standard 2.0.<\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.9\" id=\"calibre_link-902\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.9\" class=\"calibre5\">Chapter 8 &ndash; Working with Common .NET Types<\/h2>\n<section data-number=\"19.9.1\" id=\"calibre_link-903\">\n<h3 data-number=\"19.9.1\" class=\"calibre8\">Exercise 8.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the maximum number of characters that can be stored in a <code class=\"calibre9\">string<\/code> variable?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The maximum size of a <code class=\"calibre9\">string<\/code> variable is 2 GB, or about 1 billion characters, because each character uses 2 bytes due to the internal use of Unicode (UTF-16) encoding for characters in a <code class=\"calibre9\">string<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">When and why should you use a <code class=\"calibre9\">SecureString<\/code> type?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The string type leaves text data in the memory for too long and it's too visible. The <code class=\"calibre9\">SecureString<\/code> type encrypts its text and ensures that the memory is released immediately. For example, in WPF, the <code class=\"calibre9\">PasswordBox<\/code> control stores its password as a <code class=\"calibre9\">SecureString<\/code> variable, and when starting a new process, the <code class=\"calibre9\">Password<\/code> parameter must be a <code class=\"calibre9\">SecureString<\/code> variable.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">When is it appropriate to use a <code class=\"calibre9\">StringBuilder<\/code> class?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: When concatenating more than three <code class=\"calibre9\">string<\/code> variables, you will use less memory and get improved performance using <code class=\"calibre9\">StringBuilder<\/code> than using the <code class=\"calibre9\">string.Concat<\/code> method or the <code class=\"calibre9\">+<\/code> operator.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">When should you use a <code class=\"calibre9\">LinkedList&lt;T&gt;<\/code> class?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Each item in a linked list has a reference to its previous and next siblings as well as the list itself. A linked list should be used when items need to be inserted and removed from positions in the list without moving the items in memory.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">When should you use a <code class=\"calibre9\">SortedDictionary&lt;T&gt;<\/code> class rather than a <code class=\"calibre9\">SortedList&lt;T&gt;<\/code> class?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">SortedList&lt;T&gt;<\/code> class uses less memory than <code class=\"calibre9\">SortedDictionary&lt;T&gt;<\/code>; <code class=\"calibre9\">SortedDictionary&lt;T&gt;<\/code> has faster insertion and removal operations for unsorted data. If the list is populated all at once from sorted data, <code class=\"calibre9\">SortedList&lt;T&gt;<\/code> is faster than <code class=\"calibre9\">SortedDictionary&lt;T&gt;<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In a regular expression, what does <code class=\"calibre9\">$<\/code> mean?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: In a regular expression, <code class=\"calibre9\">$<\/code> represents the end of the input.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In a regular expression, how can you represent digits?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: In a regular expression, you can represent digit characters using <code class=\"calibre9\">\\d<\/code> or <code class=\"calibre9\">[0-9]<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why should you <em class=\"calibre10\">not<\/em> use the official standard for email addresses to create a regular expression to validate a user's email address?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The effort is not worth the pain for you or your users. Validating an email address using the official specification doesn't check whether that address exists or whether the person entering the address is its owner.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What characters are output when the following code runs?<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string city = \"Aberdeen\";\nReadOnlySpan&lt;char&gt; citySpan = city.AsSpan()[^5..^0];\nWriteLine(citySpan.ToString());<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">rdeen<\/code>. <code class=\"calibre9\">^5..<\/code> means the range is 5 characters long. <code class=\"calibre9\">..^0<\/code> means the range ends zero characters in from the right end.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How could you check that a web service is available before calling it?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Use the <code class=\"calibre9\">Ping<\/code> class to call the web service and check the <code class=\"calibre9\">Status<\/code> of the reply.<\/p>\n<\/section>\n<section data-number=\"19.9.2\" id=\"calibre_link-904\">\n<h3 data-number=\"19.9.2\" class=\"calibre8\">Exercise 8.2 &ndash; Practice regular expressions<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter08\/Ch08Ex02RegularExpressions\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter08\/Ch08Ex02RegularExpressions<\/a><\/p>\n<\/section>\n<section data-number=\"19.9.3\" id=\"calibre_link-905\">\n<h3 data-number=\"19.9.3\" class=\"calibre8\">Exercise 8.3 &ndash; Practice writing extension methods<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter08\/Ch08Ex03NumbersAsWordsLibhttps:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter08\/Ch08Ex03NumbersAsWordsTestshttps:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter08\/Ch08Ex03NumbersAsWordsApp\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter08\/Ch08Ex03NumbersAsWordsLibhttps:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter08\/Ch08Ex03NumbersAsWordsTestshttps:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter08\/Ch08Ex03NumbersAsWordsApp<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.10\" id=\"calibre_link-906\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.10\" class=\"calibre5\">Chapter 9 &ndash; Working with Files, Streams, and Serialization<\/h2>\n<section data-number=\"19.10.1\" id=\"calibre_link-907\">\n<h3 data-number=\"19.10.1\" class=\"calibre8\">Exercise 9.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between using the <code class=\"calibre9\">File<\/code> class and the <code class=\"calibre9\">FileInfo<\/code> class?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">File<\/code> class has <code class=\"calibre9\">static<\/code> methods and it cannot be instantiated. It is best used for one-off tasks such as copying a file. The <code class=\"calibre9\">FileInfo<\/code> class requires the instantiation of an object that represents a file. It is best used when you need to perform multiple operations on the same file.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between the <code class=\"calibre9\">ReadByte<\/code> method and the <code class=\"calibre9\">Read<\/code> method of a stream?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">ReadByte<\/code> method returns a single byte each time it is called and the <code class=\"calibre9\">Read<\/code> method fills a temporary array with bytes up to a specified length. It is generally best to use <code class=\"calibre9\">Read<\/code> to process multiple bytes at once.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">When would you use the <code class=\"calibre9\">StringReader<\/code>, <code class=\"calibre9\">TextReader<\/code>, and <code class=\"calibre9\">StreamReader<\/code> classes?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">StringReader<\/code> is used for efficiently reading from a string stored in memory.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">TextReader<\/code> is an abstract class that <code class=\"calibre9\">StringReader<\/code> and <code class=\"calibre9\">StreamReader<\/code> both inherit from for their shared functionality.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">StreamReader<\/code> is used for reading strings from a stream that can be any type of text file, including XML and JSON.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does the <code class=\"calibre9\">DeflateStream<\/code> type do?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">DeflateStream<\/code> implements the same compression algorithm as GZIP, but without a cyclical redundancy check; so, although it produces smaller compressed files, it cannot perform integrity checks when decompressing.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How many bytes per character does UTF-8 encoding use?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The number of bytes per character used by the UTF-8 encoding depends on the character. Most Western alphabet characters are stored using one byte. Other characters may need two or more bytes.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is an object graph?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: An object graph is any set of connected instances of classes that reference each other. For example, a <code class=\"calibre9\">Customer<\/code> object may have a property named <code class=\"calibre9\">Orders<\/code> that references a collection of <code class=\"calibre9\">Order<\/code> instances.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the best serialization format to choose for minimizing space requirements?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <strong class=\"calibre2\">JavaScript Object Notation<\/strong> (<strong class=\"calibre2\">JSON<\/strong>) has a good balance between space requirements and practical factors like human readability, but the <strong class=\"calibre2\">protocol buffers<\/strong> (<strong class=\"calibre2\">Protobuf<\/strong>) serialization format used by the gRPC standard is best for minimizing space requirements.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the best serialization format to choose for cross-platform compatibility?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: There is still an argument for <strong class=\"calibre2\">eXtensible Markup Language<\/strong> (<strong class=\"calibre2\">XML<\/strong>) if you need maximum compatibility, especially with legacy systems, although JSON is better if you need to integrate with web systems, or Protobuf for best performance and minimum bandwidth use.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why is it bad to use a <code class=\"calibre9\">string<\/code> value like <code class=\"calibre9\">\"\\Code\\Chapter01\"<\/code> to represent a path, and what should you do instead?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: It is bad to use a <code class=\"calibre9\">string<\/code> value like <code class=\"calibre9\">\"\\Code\\Chapter01\"<\/code> to represent a path because it assumes that backslashes are used as a folder separator on all operating systems. Instead, you should use the <code class=\"calibre9\">Path.Combine<\/code> method and pass separate <code class=\"calibre9\">string<\/code> values for each folder, or a <code class=\"calibre9\">string<\/code> array, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">string path = Path.Combine(new[] { \"Code\", \"Chapter01\" });<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">Where can you find information about NuGet packages and their dependencies?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You can find information about NuGet packages and their dependencies at the following link: <a href=\"https:\/\/www.nuget.org\/\">https:\/\/www.nuget.org\/<\/a>.<\/p>\n<\/section>\n<section data-number=\"19.10.2\" id=\"calibre_link-908\">\n<h3 data-number=\"19.10.2\" class=\"calibre8\">Exercise 9.2 &ndash; Practice serializing as XML<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter09\/Ch09Ex02SerializingShapes\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter09\/Ch09Ex02SerializingShapes<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.11\" id=\"calibre_link-909\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.11\" class=\"calibre5\">Chapter 10 &ndash; Working with Data Using Entity Framework Core<\/h2>\n<section data-number=\"19.11.1\" id=\"calibre_link-910\">\n<h3 data-number=\"19.11.1\" class=\"calibre8\">Exercise 10.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What type would you use for the property that represents a table, for example, the <code class=\"calibre9\">Products<\/code> property of a database context?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">DbSet&lt;T&gt;<\/code>, where <code class=\"calibre9\">T<\/code> is the entity type, for example, <code class=\"calibre9\">Product<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What type would you use for the property that represents a one-to-many relationship, for example, the <code class=\"calibre9\">Products<\/code> property of a <code class=\"calibre9\">Category<\/code> entity?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">ICollection&lt;T&gt;<\/code>, where <code class=\"calibre9\">T<\/code> is the entity type, for example, <code class=\"calibre9\">Product<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the EF Core convention for primary keys?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The property named <code class=\"calibre9\">ID<\/code> or <code class=\"calibre9\">Id<\/code> or <code class=\"calibre9\">ClassNameID<\/code> or <code class=\"calibre9\">ClassNameId<\/code> is assumed to be the primary key. If the type of that property is any of the following, then the property is also marked as being an <code class=\"calibre9\">IDENTITY<\/code> column: <code class=\"calibre9\">tinyint<\/code>, <code class=\"calibre9\">smallint<\/code>, <code class=\"calibre9\">int<\/code>, <code class=\"calibre9\">bigint<\/code>, and <code class=\"calibre9\">guid<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">When might you use an annotation attribute in an entity class?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You might use an annotation attribute in an entity class when the conventions cannot work out the correct mapping between the classes and tables, for example, if a class name does not match a table name or a property name does not match a column name. You might also define constraints, like a maximum length of characters in a text value or a range of numeric values, by decorating with validation attributes. These can be read by technologies like ASP.NET Core MVC and Blazor to provide automatic validation warnings to users.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why might you choose Fluent API in preference to annotation attributes?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You might choose Fluent API in preference to annotation attributes when you want to keep your entity classes free from extraneous code that is not needed in all scenarios. For example, when creating a .NET Standard 2.0 class library for entity classes, you might want to only use validation attributes so that the metadata can be read by EF Core and by technologies like ASP.NET Core model binding validation and .NET MAUI desktop and mobile apps. However, you might want to use Fluent API to define EF Core-specific functionality like mapping to a different table or column name.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does a transaction isolation level of <code class=\"calibre9\">Serializable<\/code> mean?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Maximum locks are applied to ensure complete isolation from any other processes working with the affected data.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does the <code class=\"calibre9\">DbContext.SaveChanges<\/code> method return?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: An <code class=\"calibre9\">int<\/code> value for the number of entities affected.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between eager loading and explicit loading?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Eager loading means related entities are included in the original query to the database so that they do not have to be loaded later. Explicit loading means related entities are not included in the original query to the database, and they must be explicitly loaded just before they are needed.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How should you define an EF Core entity class to match the following table?<\/li>\n<\/ol>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">CREATE TABLE Employees(\n  EmpId INT IDENTITY,\n  FirstName NVARCHAR(40) NOT NULL,\n  Salary MONEY\n)<\/code><\/pre>\n<\/div>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Use the following class:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">public class Employee\n{\n  [Column(\"EmpId\")]\n  public int EmployeeId { get; set; }\n  [Required]\n  [StringLength(40)]\n  public string FirstName { get; set; }\n  [Column(TypeName = \"money\")]\n  public decimal? Salary { get; set; }\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">What benefit do you get from declaring entity navigation properties as <code class=\"calibre9\">virtual<\/code>?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You can enable lazy loading if you declare entity navigation properties as <code class=\"calibre9\">virtual<\/code>.<\/p>\n<\/section>\n<section data-number=\"19.11.2\" id=\"calibre_link-911\">\n<h3 data-number=\"19.11.2\" class=\"calibre8\">Exercise 10.2 &ndash; Exporting data using different serialization formats<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter10\/Ch10Ex02DataSerialization\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter10\/Ch10Ex02DataSerialization<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.12\" id=\"calibre_link-912\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.12\" class=\"calibre5\">Chapter 11 &ndash; Querying and Manipulating Data Using LINQ<\/h2>\n<section data-number=\"19.12.1\" id=\"calibre_link-913\">\n<h3 data-number=\"19.12.1\" class=\"calibre8\">Exercise 11.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the two required parts of LINQ?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A LINQ provider and the LINQ extension methods. You must import the <code class=\"calibre9\">System.Linq<\/code> namespace to make the LINQ extension methods available and reference a LINQ provider assembly for the type of data that you want to work with.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Which LINQ extension method would you use to return a subset of properties from a type?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">Select<\/code> method allows the projection (aka selection) of properties.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Which LINQ extension method would you use to filter a sequence?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">Where<\/code> method allows filtering by supplying a delegate (or lambda expression) that returns a Boolean to indicate whether the value should be included in the results.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">List five LINQ extension methods that perform aggregation.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Any five of the following: <code class=\"calibre9\">Max<\/code>, <code class=\"calibre9\">Min<\/code>, <code class=\"calibre9\">Count<\/code>, <code class=\"calibre9\">LongCount<\/code>, <code class=\"calibre9\">Average<\/code>, <code class=\"calibre9\">Sum<\/code>, and <code class=\"calibre9\">Aggregate<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between the <code class=\"calibre9\">Select<\/code> and <code class=\"calibre9\">SelectMany<\/code> extension methods?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">Select<\/code> returns exactly what you specify to return. <code class=\"calibre9\">SelectMany<\/code> checks that the items you have selected are themselves <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> and then breaks them down into smaller parts. For example, if the type you select is a <code class=\"calibre9\">string<\/code> value (which is <code class=\"calibre9\">IEnumerable&lt;char&gt;<\/code>), <code class=\"calibre9\">SelectMany<\/code> will break each <code class=\"calibre9\">string<\/code> value returned into its individual <code class=\"calibre9\">char<\/code> values and combine them into a single sequence.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the difference between <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> and <code class=\"calibre9\">IQueryable&lt;T&gt;<\/code>? How do you switch between them?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> interface indicates a LINQ provider that will execute the query locally like LINQ to Objects. These providers have no limitations but can be less efficient. The <code class=\"calibre9\">IQueryable&lt;T&gt;<\/code> interface indicates a LINQ provider that first builds an expression tree to represent the query and then converts it into another query syntax before executing it, like Entity Framework Core converts LINQ into SQL statements. These providers sometimes have limitations, like a lack of support for some expressions, and may throw exceptions. You can convert from an <code class=\"calibre9\">IQueryable&lt;T&gt;<\/code> provider to an <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> provider by calling the <code class=\"calibre9\">AsEnumerable<\/code> method.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does the last type parameter <code class=\"calibre9\">T<\/code> in generic <code class=\"calibre9\">Func<\/code> delegates like <code class=\"calibre9\">Func&lt;T1, T2, T&gt;<\/code> represent?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The last type parameter <code class=\"calibre9\">T<\/code> in generic <code class=\"calibre9\">Func<\/code> delegates like <code class=\"calibre9\">Func&lt;T1, T2, T&gt;<\/code> represents the type of the return value. For example, for <code class=\"calibre9\">Func&lt;string, int, bool&gt;<\/code>, the delegate or lambda function used must return a Boolean value.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the benefit of a LINQ extension method that ends with <code class=\"calibre9\">OrDefault<\/code>?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The benefit of a LINQ extension method that ends with <code class=\"calibre9\">OrDefault<\/code> is that it returns the default value instead of throwing an exception if it cannot return a value. For example, calling the <code class=\"calibre9\">First<\/code> method on a sequence of <code class=\"calibre9\">int<\/code> values would throw an exception if the collection is empty, but the <code class=\"calibre9\">FirstOrDefault<\/code> method would return <code class=\"calibre9\">0<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why is query comprehension syntax optional?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Query comprehension syntax is optional because it is just syntactic sugar. It makes code easier for humans to read but it does not add any additional functionality except the <code class=\"calibre9\">let<\/code> keyword.<\/p>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">You can learn more about the <code class=\"calibre9\">let<\/code> keyword at the following link: <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/let-clause\">https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/keywords\/let-clause<\/a><\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">How can you create your own LINQ extension methods?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Create a <code class=\"calibre9\">static<\/code> class with a <code class=\"calibre9\">static<\/code> method, with an <code class=\"calibre9\">IEnumerable&lt;T&gt;<\/code> parameter prefixed with <code class=\"calibre9\">this<\/code>, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">namespace System.Linq\n{\n  public static class MyLinqExtensionMethods\n  {\n    public static IEnumerable&lt;T&gt; MyChainableExtensionMethod&lt;T&gt;(\n      this IEnumerable&lt;T&gt; sequence)\n    {\n      \/\/ return something IEnumerable&lt;T&gt;\n    }\n    public static int? MyAggregateExtensionMethod&lt;T&gt;(\n      this IEnumerable&lt;T&gt; sequence)\n    {\n      \/\/ return some int value\n    }\n  }\n}<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"19.12.2\" id=\"calibre_link-914\">\n<h3 data-number=\"19.12.2\" class=\"calibre8\">Exercise 11.2 &ndash; Practice querying with LINQ<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter11\/Ch11Ex02LinqQueries\">https:\/\/github.com\/markjprice\/cs12dotnet8\/tree\/main\/code\/Chapter11\/Ch11Ex02LinqQueries<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.13\" id=\"calibre_link-915\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.13\" class=\"calibre5\">Chapter 12 &ndash; Introducing Web Development Using ASP.NET Core<\/h2>\n<section data-number=\"19.13.1\" id=\"calibre_link-916\">\n<h3 data-number=\"19.13.1\" class=\"calibre8\">Exercise 12.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What was the name of Microsoft's first dynamic server-side executed web page technology, and why is it still useful to know this history today?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <strong class=\"calibre2\">Active Server Pages<\/strong> (<strong class=\"calibre2\">ASP<\/strong>). The name ASP.NET Core derives from ASP, and it is still used in new features like Tag Helpers, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">&lt;a asp-controller=\"Home\" asp-action=\"Index\"&gt;Home&lt;\/a&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the names of two Microsoft web servers?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Kestrel (cross-platform) and <strong class=\"calibre2\">Internet Information Services<\/strong> (<strong class=\"calibre2\">IIS<\/strong>), which is Windows-only.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are some differences between a microservice and a nanoservice?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A microservice implements more than one function grouped into a small domain and is always running. A nanoservice implements a single function and is not always running, i.e., it can be \"serverless.\"<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is Blazor?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Blazor is a .NET-based technology for implementing client-side web user interfaces. It is designed to be used instead of <strong class=\"calibre2\">single-page applications<\/strong> (<strong class=\"calibre2\">SPAs<\/strong>) like React, Angular, and Vue.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What was the first version of ASP.NET Core that cannot be hosted on .NET Framework?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: ASP.NET Core 3.0 requires .NET Standard 2.1, which is not supported by .NET Framework.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is a user agent?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: A user agent is a client to a web server, for example, a web browser or a search engine web crawler.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What impact does the HTTP request-response communication model have on web developers?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Website dynamic code resides on and executes on a web server. The server code cannot trigger communication. A web browser must make an HTTP request to trigger code on the server, which can then generate an HTTP response. This makes updating a web page difficult because it is under the control of the client, not the server, when requests for more data are made.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Name and describe four components of a URL.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <em class=\"calibre10\">scheme<\/em> determines if you are using HTTP or HTTPS. The <em class=\"calibre10\">domain<\/em> is the unique address of the computer (or a web farm of servers acting as a single logical computer). The <em class=\"calibre10\">port number<\/em> is the port on which the server(s) are listening (usually <code class=\"calibre9\">80<\/code> for HTTP and <code class=\"calibre9\">443<\/code> for HTTPS). The <em class=\"calibre10\">path<\/em> is the relative path to a resource like a folder or file. The <em class=\"calibre10\">query string<\/em> is for optional parameters passed along with the request. The <em class=\"calibre10\">fragment<\/em> is an identified element within a resource like a web page.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What capabilities does Developer Tools give you?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Developer Tools allows you to see every HTTP request and response, view client-side application data like cookies, sessions, and local storage, provides a console for logging, and so on.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the three main client-side web development technologies and what do they do?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: HTML5 (structure), CSS3 (styles), and JavaScript (execute actions).<\/p>\n<\/section>\n<section data-number=\"19.13.2\" id=\"calibre_link-917\">\n<h3 data-number=\"19.13.2\" class=\"calibre8\">Exercise 12.2 &ndash; Know your webbreviations<\/h3>\n<p class=\"rights\">What do the following web abbreviations stand for and what do they do?<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\"><strong class=\"calibre2\">URI (Uniform Resource Identifier)<\/strong> is a unique sequence of characters that identifies a resource.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">URL (Uniform Resource Location)<\/strong> is the address of a unique resource.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">WCF (Windows Communication Foundation)<\/strong> is a framework for building service-oriented applications. It is part of .NET Framework and an open-source implementation named WCF Core is available for modern .NET.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">TLD (Top-Level Domain)<\/strong> is one of the domains at the highest level in the hierarchical <strong class=\"calibre2\">DNS (Domain Name System)<\/strong> of the internet, for example, <code class=\"calibre9\">packt.com<\/code>.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">API (Application Programming Interface)<\/strong> is a mechanism for a computer system to allow other computer systems to communicate with it. They should be well-documented.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">SPA (Single-Page Application)<\/strong> is a web app that loads only a single web page and then updates the content dynamically via JavaScript APIs when needed. SPA frameworks include Angular, React, Vue, and Blazor.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">CMS (Content Management System)<\/strong> is a software application that allows users to build and manage a website without having to write code.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Wasm (WebAssembly)<\/strong> is a binary instruction format and is designed as a compilation target for programming languages like C# for deployment on the web, on the client, and server.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">SASS (Syntactically Awesome Style Sheets)<\/strong> is a CSS preprocessor. SASS has features that don't exist in CSS yet like nesting, mixins, and inheritance that help you write maintainable CSS.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">REST (REpresentational State Transfer)<\/strong> is an architectural style for distributed hypermedia systems. Roy Fielding presented it in 2000 in his famous dissertation.<\/li>\n<\/ol>\n<blockquote class=\"calibre14\">\n<p class=\"rights\"><strong class=\"calibre2\">In case you missed it (ICYMI)<\/strong>: Acronyms and initialisms are types of abbreviation. Learn more at the following link: <a href=\"https:\/\/www.rd.com\/article\/acronym-vs-abbreviation-whats-the-difference\/\">https:\/\/www.rd.com\/article\/acronym-vs-abbreviation-whats-the-difference\/<\/a>.<\/p>\n<\/blockquote>\n<\/section>\n<\/section>\n<section data-number=\"19.14\" id=\"calibre_link-918\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.14\" class=\"calibre5\">Chapter 13 &ndash; Building Websites Using ASP. NET Core Razor Pages<\/h2>\n<section data-number=\"19.14.1\" id=\"calibre_link-919\">\n<h3 data-number=\"19.14.1\" class=\"calibre8\">Exercise 13.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">List six method names that can be specified in an HTTP request.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">GET<\/code>, <code class=\"calibre9\">HEAD<\/code>, <code class=\"calibre9\">POST<\/code>, <code class=\"calibre9\">PUT<\/code>, <code class=\"calibre9\">PATCH<\/code>, and <code class=\"calibre9\">DELETE<\/code>. Others include <code class=\"calibre9\">TRACE<\/code>, <code class=\"calibre9\">OPTIONS<\/code>, and <code class=\"calibre9\">CONNECT<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">List six status codes and their descriptions that can be returned in an HTTP response.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">200<\/code> OK, <code class=\"calibre9\">201<\/code> Created, <code class=\"calibre9\">301<\/code> Moved Permanently, <code class=\"calibre9\">400<\/code> Bad Request, <code class=\"calibre9\">404<\/code> Not Found (missing resource), and <code class=\"calibre9\">500<\/code> Internal Server Error. Others include <code class=\"calibre9\">101<\/code> Switching Protocols (e.g., from HTTP to WebSocket), <code class=\"calibre9\">202<\/code> Accepted, <code class=\"calibre9\">204<\/code> No Content, <code class=\"calibre9\">304<\/code> Not Modified, <code class=\"calibre9\">401<\/code> Unauthorized, <code class=\"calibre9\">403<\/code> Forbidden, <code class=\"calibre9\">406<\/code> Not Acceptable (for example, requesting a response format that is not supported by a website), and <code class=\"calibre9\">503<\/code> Service Unavailable.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In ASP.NET Core, what is the <code class=\"calibre9\">Program<\/code> class used for?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: In ASP.NET Core, the <code class=\"calibre9\">Program<\/code> class is where you add and configure dependency services like Razor Pages, MVC, and Entity Framework Core data contexts. It is also where you configure middleware in the request and response pipeline. This might include error handling, security options, static files, default files, and endpoint routing.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does the acronym HSTS stand for and what does it do?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <strong class=\"calibre2\">HTTP Strict Transport Security<\/strong> (<strong class=\"calibre2\">HSTS<\/strong>) is an opt-in security enhancement. If a website specifies it and a browser supports it, then it forces all communication over HTTPS and prevents the visitor from using untrusted or invalid certificates.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How do you enable static HTML pages for a website?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To enable static HTML pages for a website, you must add statements to use default files and then static files (this order is important!), as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">app.UseDefaultFiles(); \/\/ index.xhtml, default.xhtml, and so on \napp.UseStaticFiles();<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">How do you mix C# code into the middle of HTML to create a dynamic page?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To mix C# code into the middle of HTML to create a dynamic page, you can create a Razor file with the <code class=\"calibre9\">.cshtml<\/code> file extension, and then prefix any C# expressions with the <code class=\"calibre9\">@<\/code> symbol, and for C# statements, wrap them in braces or create a <code class=\"calibre9\">@functions<\/code> section, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page \n@functions\n{\n  public string[] DaysOfTheWeek\n  {\n    get =&gt; System.Threading.Thread.CurrentThread\n      .CurrentCulture.DateTimeFormat.DayNames;\n  }\n  public string WhatDayIsIt\n  {\n    get =&gt; System.DateTime.Now.ToString(\"dddd\");\n  }\n}\n&lt;html&gt;\n  &lt;head&gt;\n    &lt;title&gt;Today is @WhatDayIsIt&lt;\/title&gt;\n  &lt;\/head&gt;\n  &lt;body&gt;\n    &lt;h1&gt;Days of the week in your culture&lt;\/h1&gt;\n    &lt;ul&gt;\n    @{\n      \/\/ to add a block of statements: use braces\n      foreach (string dayName in DaysOfTheWeek)\n      {\n        &lt;li&gt;@dayName&lt;\/li&gt;\n      }\n    }\n    &lt;\/ul&gt;\n  &lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">How can you define shared layouts for Razor Pages?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To define shared layouts for Razor Pages, create at least two files: <code class=\"calibre9\">_Layout.cshtml<\/code> will define the markup for the shared layout, and <code class=\"calibre9\">_ViewStart.cshtml<\/code> will set the default layout, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@{\n  Layout = \"_Layout\";\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">How can you separate the markup from the code-behind in a Razor Page?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To separate the markup from the code-behind in a Razor Page, create two files: <code class=\"calibre9\">MyPage.cshtml<\/code> contains the markup and <code class=\"calibre9\">MyPage.cshtml.cs<\/code> contains a class that inherits from <code class=\"calibre9\">PageModel<\/code>. In <code class=\"calibre9\">MyPage.cshtml<\/code>, set the model to use the class, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@page\n@model MyProject.Pages.MyPageModel<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">How do you configure an Entity Framework Core data context for use with an ASP.NET Core website?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To configure an Entity Framework Core data context for use with an ASP.NET Core website:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">In the project file, reference the assembly that defines the data context class.<\/li>\n<li class=\"calibre3\">In <code class=\"calibre9\">Program.cs<\/code> or the <code class=\"calibre9\">Startup<\/code> class, import the namespaces for <code class=\"calibre9\">Microsoft.EntityFrameworkCore<\/code> and the data context class.<\/li>\n<li class=\"calibre3\">In the <code class=\"calibre9\">ConfigureServices<\/code> method or the section of <code class=\"calibre9\">Program.cs<\/code> that configures services, add a statement that configures the data context with a database connection string for use with a specified database provider, like SQLite or SQL Server, as shown in the following code:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">services.AddDbContext&lt;MyDataContext&gt;(options =&gt; \/\/ or UseSqlServer()\n  options.UseSqlite(\"my database connection string\")); <\/code><\/pre>\n<\/div>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">In the Razor Page model class or <code class=\"calibre9\">@functions<\/code> section, declare a private field to store the data context and then set it in the constructor, as shown in the following code:<\/li>\n<\/ul>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">private MyDataContext db;\npublic SuppliersModel(MyDataContext injectedContext)\n{\n  db = injectedContext;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">How can you reuse Razor Pages with ASP.NET Core 2.2 or later?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To reuse Razor Pages with ASP.NET Core 2.2 or later, everything related to a Razor page can be compiled into a class library. To create one, enter the following command:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">dotnet new razorclasslib -s<\/code><\/pre>\n<\/div>\n<\/section>\n<section data-number=\"19.14.2\" id=\"calibre_link-920\">\n<h3 data-number=\"19.14.2\" class=\"calibre8\">Exercise 13.4 &ndash; Practice building a data-driven web page<\/h3>\n<p class=\"rights\">My suggested solution can be found at the following links:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Customers.cshtmlhttps:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Customers.cshtml.cshttps:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/CustomerOrders.cshtmlhttps:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/CustomerOrders.cshtml.cs\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Customers.cshtmlhttps:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Customers.cshtml.cshttps:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/CustomerOrders.cshtmlhttps:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/CustomerOrders.cshtml.cs<\/a><\/p>\n<\/section>\n<section data-number=\"19.14.3\" id=\"calibre_link-921\">\n<h3 data-number=\"19.14.3\" class=\"calibre8\">Exercise 13.5 &ndash; Practice building web pages for functions<\/h3>\n<p class=\"rights\">My suggested solution can be found at the following links:<a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Functions.cshtmlhttps:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Functions.cshtml.cs\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Functions.cshtmlhttps:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Web\/Pages\/Functions.cshtml.cs<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.15\" id=\"calibre_link-922\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.15\" class=\"calibre5\">Chapter 14 &ndash; Building Websites Using the Model-View-Controller Pattern<\/h2>\n<section data-number=\"19.15.1\" id=\"calibre_link-923\">\n<h3 data-number=\"19.15.1\" class=\"calibre8\">Exercise 14.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What do the files with the special names <code class=\"calibre9\">_ViewStart<\/code> and <code class=\"calibre9\">_ViewImports<\/code> do when created in the <code class=\"calibre9\">Views<\/code> folder?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">A <code class=\"calibre9\">_ViewStart<\/code> file contains a block of statements that are executed when the <code class=\"calibre9\">View<\/code> method is executed, when a controller action method passes a model to a view, for example, to set a default layout.<\/li>\n<li class=\"calibre3\">A <code class=\"calibre9\">_ViewImports<\/code> file contains <code class=\"calibre9\">@using<\/code> statements to import namespaces for all views, to avoid having to add the same import statements at the top of all views.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the names of the three segments defined in the default ASP.NET Core MVC route, what do they represent, and which are optional?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">{controller}<\/code>: For example, <code class=\"calibre9\">\/shippers<\/code> represents a controller class to instantiate, for example, <code class=\"calibre9\">ShippersController<\/code>. It is optional because it can use the default value: <code class=\"calibre9\">Home<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">{action}<\/code>: For example, <code class=\"calibre9\">\/privacy<\/code> represents an action method to execute, for example, <code class=\"calibre9\">Privacy<\/code>. It is optional because it can use the default value: <code class=\"calibre9\">Index<\/code>.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">{id}<\/code>: For example, <code class=\"calibre9\">\/5<\/code> represents a parameter in the action method, for example, <code class=\"calibre9\">int id<\/code>. It is optional because it is suffixed with <code class=\"calibre9\">?<\/code>.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">What does the default model binder do, and what data types can it handle?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The default model binder sets parameters in the action method. It can handle the following data types:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Simple types like <code class=\"calibre9\">int<\/code>, <code class=\"calibre9\">string<\/code>, and <code class=\"calibre9\">DateTime<\/code>, including nullable types.<\/li>\n<li class=\"calibre3\">Complex types like <code class=\"calibre9\">Person<\/code> and <code class=\"calibre9\">Product<\/code>.<\/li>\n<li class=\"calibre3\">Collection types like <code class=\"calibre9\">ICollection&lt;T&gt;<\/code> or <code class=\"calibre9\">IList&lt;T&gt;<\/code>.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In a shared layout file like <code class=\"calibre9\">_Layout.cshtml<\/code>, how do you output the content of the current view?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To output the content of the current view in a shared layout, call the <code class=\"calibre9\">RenderBody<\/code> method, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@RenderBody()<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">In a shared layout file like <code class=\"calibre9\">_Layout.cshtml<\/code>, how do you output a section that the current view can supply content for, and how does the view supply the contents for that section?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To output the content of a section in a shared layout, call the <code class=\"calibre9\">RenderSection<\/code> method, specifying a name for the section if it is required, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@RenderSection(\"Scripts\", required: false)<\/code><\/pre>\n<\/div>\n<p class=\"rights\">To define the contents of the section in the view, create a named section, as shown in the following markup:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">@section Scripts\n{\n&lt;script&gt; \n  alert('Hello, Mr. Page!');\n&lt;\/script&gt;\n}<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">When calling the <code class=\"calibre9\">View<\/code> method inside a controller's action method, what paths are searched for the view by convention?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: When calling the <code class=\"calibre9\">View<\/code> method inside a controller's action method, three paths are searched for the view by default, based on combinations of the names of the controller and action method and a special <code class=\"calibre9\">Shared<\/code> folder, as shown in the following example output:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">InvalidOperationException: The view 'Index' was not found. The following locations were searched:\n\/Views\/Home\/Index.cshtml\n\/Views\/Shared\/Index.cshtml\n\/Pages\/Shared\/Index.cshtml<\/code><\/pre>\n<\/div>\n<p class=\"rights\">This can be generalized as follows:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">\/Views\/[controller]\/[action].cshtml<\/code><\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">\/Views\/Shared\/[action].cshtml<\/code><\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">\/Pages\/Shared\/[action].cshtml<\/code><\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">How can you instruct the visitor's browser to cache the response for 24 hours?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To instruct the visitor's browser to cache the response for 24 hours, decorate the controller class or action method with the <code class=\"calibre9\">[ResponseCache]<\/code> attribute, and set the <code class=\"calibre9\">Duration<\/code> parameter to <code class=\"calibre9\">86400<\/code> seconds and the <code class=\"calibre9\">Location<\/code> parameter to <code class=\"calibre9\">ResponseCacheLocation.Client<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why might you enable Razor Pages even if you are not creating any yourself?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: If you have used features like ASP.NET Core Identity UI, then they require Razor Pages.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How does ASP.NET Core MVC identify classes that can act as controllers?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: ASP.NET Core MVC identifies classes that can act as controllers by looking to see if the class (or a class that it derives from) is decorated with the <code class=\"calibre9\">[Controller]<\/code> attribute.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In what ways does ASP.NET Core MVC make it easier to test a website?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <strong class=\"calibre2\">Model-View-Controller<\/strong> (<strong class=\"calibre2\">MVC<\/strong>) design pattern separates the technical concerns. These consist of:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">The shape of the data (model).<\/li>\n<li class=\"calibre3\">The executable statements to process the incoming request and outgoing response (controller).<\/li>\n<li class=\"calibre3\">The generation of the response in a format requested by the user agent like HTML or JSON (view).<\/li>\n<\/ul>\n<p class=\"rights\">This makes it easier to write unit tests. ASP.NET Core also makes it easy to implement the <strong class=\"calibre2\">Inversion-of-Control<\/strong> (<strong class=\"calibre2\">IoC<\/strong>) and <strong class=\"calibre2\">dependency injection<\/strong> (<strong class=\"calibre2\">DI<\/strong>) design patterns to remove dependencies when testing a component like a controller.<\/p>\n<\/section>\n<section data-number=\"19.15.2\" id=\"calibre_link-924\">\n<h3 data-number=\"19.15.2\" class=\"calibre8\">Exercise 14.2 &ndash; Practice implementing MVC by implementing a category detail page<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Mvc\/Controllers\/HomeController.cs#L249https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Mvc\/Views\/Home\/CategoryDetail.cshtml\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Mvc\/Controllers\/HomeController.cs#L249https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.Mvc\/Views\/Home\/CategoryDetail.cshtml<\/a><\/p>\n<\/section>\n<section data-number=\"19.15.3\" id=\"calibre_link-925\">\n<h3 data-number=\"19.15.3\" class=\"calibre8\">Exercise 14.4 &ndash; Practice unit testing MVC controllers<\/h3>\n<p class=\"rights\"><a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.UnitTests\/ControllerUnitTests.cs\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/code\/PracticalApps\/Northwind.UnitTests\/ControllerUnitTests.cs<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.16\" id=\"calibre_link-926\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.16\" class=\"calibre5\">Chapter 15 &ndash; Building and Consuming Web Services<\/h2>\n<section data-number=\"19.16.1\" id=\"calibre_link-927\">\n<h3 data-number=\"19.16.1\" class=\"calibre8\">Exercise 15.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Which class should you inherit from to create a controller class for an ASP.NET Core Web API service?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To create a controller class for an ASP.NET Core Web API service, you should inherit from <code class=\"calibre9\">ControllerBase<\/code>. Do not inherit from <code class=\"calibre9\">Controller<\/code> as you would in MVC, because this class includes methods like <code class=\"calibre9\">View<\/code> that use Razor files to render HTML that is not needed for a web service.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">When configuring an HTTP client, how do you specify the format of data that you prefer in the response from the web service?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: When configuring an HTTP client, you specify the format of the response that you prefer by adding an <code class=\"calibre9\">Accept<\/code> header to the HTTP request that specifies the document format you prefer, and if you specify multiple and want to give them different weights, then set quality values between <code class=\"calibre9\">0.0<\/code> and <code class=\"calibre9\">1.0<\/code>, as shown highlighted in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">builder.Services.AddHttpClient(name: \"Northwind.WebApi\",\n  configureClient: options =&gt;\n  {\n    options.BaseAddress = new Uri(\"https:\/\/localhost:5002\/\");\n    options.DefaultRequestHeaders.Accept.Add(\n      new MediaTypeWithQualityHeaderValue(\n      mediaType: \"application\/json\", quality: 1.0));\n  });<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">What must you do to specify which controller action method will be executed in response to an HTTP request?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To specify which controller action method will be executed in response to a request, you must decorate the action method with an attribute. For example, to respond to an HTTP <code class=\"calibre9\">POST<\/code> request, decorate the action method with <code class=\"calibre9\">[HttpPost]<\/code>.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What must you do to specify what responses should be expected when calling an action method?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To specify what responses should be expected when calling an action method, decorate the action method with the <code class=\"calibre9\">[ProducesResponseType]<\/code> attribute, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ GET: api\/customers\/[id]\n[HttpGet(\"{id}\", Name = nameof(Get))] \/\/ named route [ProducesResponseType(200, Type = typeof(Customer))] [ProducesResponseType(404)]\npublic IActionResult Get(string id)\n{<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">List three methods that can be called to return responses with different status codes.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Three methods that can be called to return responses with different status codes include:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><code class=\"calibre9\">Ok<\/code>: This returns the <code class=\"calibre9\">200<\/code> status code and the object passed to this method in the body.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">CreatedAtRoute<\/code>: This returns the <code class=\"calibre9\">201<\/code> status code and the object passed to this method in the body.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">NoContentResult<\/code>: This returns the <code class=\"calibre9\">204<\/code> status code and an empty body.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">BadRequest<\/code>: This returns the <code class=\"calibre9\">400<\/code> status code and an optional error message.<\/li>\n<li class=\"calibre3\"><code class=\"calibre9\">NotFound<\/code>: This returns the <code class=\"calibre9\">404<\/code> status code and an optional error message.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">List four ways that you can test a web service.<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Four ways that you can test a web service include:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\">Using a browser to test simple HTTP <code class=\"calibre9\">GET<\/code> requests.<\/li>\n<li class=\"calibre3\">Installing the REST Client extension for Visual Studio Code.<\/li>\n<li class=\"calibre3\">Installing the Swagger NuGet package in your web service project, enabling Swagger, and then using the Swagger testing user interface.<\/li>\n<li class=\"calibre3\">Installing the Postman tool from the following link: <a href=\"https:\/\/www.postman.com\">https:\/\/www.postman.com<\/a>.<\/li>\n<\/ul>\n<blockquote class=\"calibre14\">\n<p class=\"rights\">I listed the four above because they are techniques that I covered or mentioned in the chapter. There are, of course, many other ways to test a web service, for example, curl. Give yourself an extra point for any valid additional methods beyond the ones I have listed.<\/p>\n<\/blockquote>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why should you not wrap your use of <code class=\"calibre9\">HttpClient<\/code> in a <code class=\"calibre9\">using<\/code> statement to dispose of it when you are finished even though it implements the <code class=\"calibre9\">IDisposable<\/code> interface, and what should you use instead?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: <code class=\"calibre9\">HttpClient<\/code> is shared, reentrant, and partially thread-safe, so it is tricky to use correctly in many scenarios. You should use <code class=\"calibre9\">HttpClientFactory<\/code>, which was introduced in .NET Core 2.1.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the benefits of HTTP\/2 and HTTP\/3 compared to HTTP\/1.1?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: HTTP\/2 benefits from full multiplexing, which reduces latency, supports request prioritization, and minimizes overhead in the protocol using header compression. HTTP\/3 benefits from being based on UDP rather than TCP so any packet loss does not block all streams. HTTP\/3 also has 0-RTT support meaning subsequent connections do not repeat the TLS acknowledgement so the client can start requesting data faster.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How can you enable clients to detect if your web service is healthy with ASP.NET Core 2.2 and later?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: To enable clients to detect if your web service is healthy, you can install health check APIs including database health checks for Entity Framework Core data contexts. Health checks can be extended to report detailed information back to the client.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What benefits does endpoint routing provide?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Endpoint routing provides improved performance of routing and action method selection, and a link generation service.<\/p>\n<\/section>\n<section data-number=\"19.16.2\" id=\"calibre_link-928\">\n<h3 data-number=\"19.16.2\" class=\"calibre8\">Exercise 15.2 &ndash; Practice creating and deleting customers with HttpClient<\/h3>\n<p class=\"rights\">For hints on how to complete this exercise, please see the following link: <a href=\"https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch15-exercise-2.md\">https:\/\/github.com\/markjprice\/cs12dotnet8\/blob\/main\/docs\/ch15-exercise-2.md<\/a><\/p>\n<\/section>\n<\/section>\n<section data-number=\"19.17\" id=\"calibre_link-929\">\n<div class=\"calibre4\"><\/div>\n<h2 data-number=\"19.17\" class=\"calibre5\">Chapter 16 &ndash; Building User Interfaces Using Blazor<\/h2>\n<section data-number=\"19.17.1\" id=\"calibre_link-930\">\n<h3 data-number=\"19.17.1\" class=\"calibre8\">Exercise 16.1 &ndash; Test your knowledge<\/h3>\n<p class=\"rights\">Suggested answers to these questions:<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What are the four Blazor render modes, and how are they different?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The four Blazor render modes are Server-Side, Streaming, Interactive Server, and Interactive WebAssembly:<\/p>\n<ul class=\"calibre7\">\n<li class=\"calibre3\"><strong class=\"calibre2\">Server-Side Rendering (SSR)<\/strong>: Executes code on the server side like Razor Pages and MVC do. The complete response is sent to the browser for display to the visitor.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Streaming Rendering<\/strong>: Executes code on the server side, HTML markup can be displayed in the browser, and while the connection is still open, more markup is sent by the server to update the contents of the page. This improves the experience for the visitor because they see some content while waiting for the rest.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Interactive Server Rendering<\/strong>: Executes code on the server side, which means the code has full and easy access to server-side resources like databases. This can simplify implementing functionality. Interactive requests are made using SignalR, which is more efficient than a full request. A permanent connection is needed between the browser and server, which limits scalability.<\/li>\n<li class=\"calibre3\"><strong class=\"calibre2\">Interactive WebAssembly Rendering<\/strong>: Executes code on the client side, which means the code only has access to resources within the browser. This can complicate the implementation because a callback to the server must be made whenever new data is required.<\/li>\n<\/ul>\n<ol class=\"toc\">\n<li class=\"calibre3\">In a Blazor Web App project, compared to an ASP.NET Core MVC project, what extra configuration is required?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: In the section that configures services, you must call <code class=\"calibre9\">AddRazorComponents<\/code>. To use interactive server rendering, you must also call <code class=\"calibre9\">AddServerComponents<\/code>. To use interactive client rendering, you must also call <code class=\"calibre9\">AddWebAssemblyComponents<\/code>. In the section that configures the HTTP pipeline, you must call <code class=\"calibre9\">MapRazorComponents&lt;App&gt;<\/code> when setting up endpoint mapping to all the components configured in the <code class=\"calibre9\">App.razor<\/code> file.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">Why should you avoid the Blazor Server and Blazor Server Empty project templates?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The Blazor Server and Blazor Server Empty project templates are now legacy since they create projects where all the components are rendered on the server and interactions are handled by SignalR. Use the Blazor Web App project template instead and then enable interactive server rendering in the components that need it.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">In a Blazor Web App project, what does the <code class=\"calibre9\">App.razor<\/code> file do?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The <code class=\"calibre9\">App.razor<\/code> file configures a <code class=\"calibre9\">Router<\/code> used by all Blazor components in the current assembly. For example, it sets a default shared layout for components that match a route and a view to use when no match is found.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the main benefit of using the <code class=\"calibre9\">&lt;NavLink&gt;<\/code> component?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The main benefit of using the <code class=\"calibre9\">&lt;NavLink&gt;<\/code> component is that it integrates with the Blazor routing system, so it can automatically apply a current style to visually indicate when the current route matches the <code class=\"calibre9\">&lt;NavLink&gt;<\/code> component.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How can you pass a value into a component?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You can pass a value into a component by decorating a public property in the component with the <code class=\"calibre9\">[Parameter]<\/code> attribute and then setting the attribute in the component when using it, as shown in the following code:<\/p>\n<div class=\"c0-consolepackt\">\n<pre class=\"calibre22\"><code class=\"calibre23\">\/\/ defining the component\n@code {\n  [Parameter]\n  public string ButtonText { get; set; };\n}\n\/\/ using the component\n&lt;CustomerDetail ButtonText=\"Create Customer\" \/&gt;<\/code><\/pre>\n<\/div>\n<ol class=\"toc\">\n<li class=\"calibre3\">What is the main benefit of using the <code class=\"calibre9\">&lt;EditForm&gt;<\/code> component?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: The main benefit of using the <code class=\"calibre9\">&lt;EditForm&gt;<\/code> component is automatic validation messages.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How can you execute some statements when parameters are set?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You can execute some statements when parameters are set by defining an <code class=\"calibre9\">OnParametersSet<\/code> method or an <code class=\"calibre9\">OnParametersSetAsync<\/code> method to handle that event.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">How can you execute some statements when a component appears?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: You can execute some statements when a component appears by defining an <code class=\"calibre9\">OnInitialized<\/code> method or an <code class=\"calibre9\">OnInitializedAsync<\/code> method to handle that event.<\/p>\n<ol class=\"toc\">\n<li class=\"calibre3\">One of the benefits of Blazor is being able to implement client-side components using C# and .NET instead of JavaScript. Does a Blazor component need any JavaScript?<\/li>\n<\/ol>\n<p class=\"rights\"><strong class=\"calibre2\">Answer<\/strong>: Yes, Blazor components need some minimal JavaScript. For Blazor Server, this is provided by the file <code class=\"calibre9\">_framework\/blazor.server.js<\/code>. For Blazor WebAssembly, this is provided by the file <code class=\"calibre9\">_framework\/blazor.webassembly.js<\/code>. Blazor WebAssembly with progressive web application (PWA) also uses a JavaScript service worker file, <code class=\"calibre9\">service-worker.js<\/code>. JavaScript is also needed to invoke browser and other client-side APIs, like getting the current geolocation or interacting with browser storage and alert dialog boxes.<\/p>\n<\/section>\n<\/section>\n<\/section>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>C# 12 and .NET 8 Modern Cross-Platform Development Fundamentals C# 12 and .NET 8 &ndash; Modern Cross-Platform Development Fundamentals Copyright \u00a9 2023 Packt Publishing All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-456","post","type-post","status-publish","format-standard","hentry","category-csharp"],"_links":{"self":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts\/456","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=456"}],"version-history":[{"count":0,"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts\/456\/revisions"}],"wp:attachment":[{"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}