C# 9.0 in a Nutshell The Definitive Reference Joseph Albahari C# 9.0 IN A NUTSHELL THE DEFINITIVE REFERENCE Joseph Albahari C# 9.0 in a Nutshell by Joseph Albahari Copyright © 2021 Joseph Albahari. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://oreilly.com). For more information, contact our corporate/institutional sales department: 800-998-9938 or [email protected]. Acquisitions Editor: Amanda Quinn Indexer: WordCo Indexing Services, Inc. Development Editor: Corbin Collins Interior Designer: David Futato Production Editor: Kristen Brown Cover Designer: Karen Montgomery Copyeditor: Charles Roumeliotis Illustrator: Kate Dullea Proofreader: Piper Editorial Consulting, LLC March 2021: First Edition Revision History for the First Edition 2021-02-26: First Release See http://oreilly.com/catalog/errata.csp?isbn=9781098100964 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. C# 9.0 in a Nutshell, the cover image, and related trade dress are trademarks of O’Reilly Media, Inc. The views expressed in this work are those of the author, and do not represent the publisher’s views. While the publisher and the author have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the author disclaim all responsibility for errors or omissions, including without limitation responsibility for damages resulting from the use of or reliance on this work. Use of the infor‐ mation and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights. 978-1-098-10096-4 [LSI] Table of Contents Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi 1. Introducing C# and .NET. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Object Orientation 1 Type Safety 2 Memory Management 3 Platform Support 3 CLRs, BCLs, and Runtimes 3 A Brief History of C# 8 2. C# Language Basics. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 A First C# Program 25 Syntax 28 Type Basics 30 Numeric Types 41 Boolean Type and Operators 50 Strings and Characters 52 Arrays 54 Variables and Parameters 59 Expressions and Operators 70 Null Operators 74 Statements 76 Namespaces 87 3. Creating Types in C#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Classes 95 Inheritance 115 The object Type 125 iii Structs 129 Access Modifiers 131 Interfaces 134 Enums 140 Nested Types 143 Generics 145 4. Advanced C#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 Delegates 159 Events 167 Lambda Expressions 174 Anonymous Methods 179 try Statements and Exceptions 180 Enumeration and Iterators 189 Nullable Value Types 194 Nullable Reference Types 200 Extension Methods 202 Anonymous Types 204 Tuples 206 Records (C# 9) 210 Patterns 220 Attributes 225 Caller Info Attributes 227 Dynamic Binding 228 Operator Overloading 236 Unsafe Code and Pointers 240 Preprocessor Directives 245 XML Documentation 247 5. .NET Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 .NET Standard 254 Runtime and C# Language Versions 257 Reference Assemblies 257 The CLR and BCL 257 Application Layers 261 6. .NET Fundamentals. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 String and Text Handling 265 Dates and Times 278 iv | Table of Contents Dates and Time Zones 286 Formatting and Parsing 291 Standard Format Strings and Parsing Flags 297 Other Conversion Mechanisms 304 Globalization 308 Working with Numbers 309 Enums 313 The Guid Struct 317 Equality Comparison 317 Order Comparison 328 Utility Classes 331 7. Collections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 Enumeration 337 The ICollection and IList Interfaces 345 The Array Class 349 Lists, Queues, Stacks, and Sets 357 Dictionaries 366 Customizable Collections and Proxies 372 Immutable Collections 378 Plugging in Equality and Order 382 8. LINQ Queries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 Getting Started 389 Fluent Syntax 391 Query Expressions 397 Deferred Execution 402 Subqueries 408 Composition Strategies 412 Projection Strategies 415 Interpreted Queries 417 EF Core 424 Building Query Expressions 435 9. LINQ Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441 Overview 442 Filtering 445 Projecting 449 Joining 461 Table of Contents | v Ordering 470 Grouping 472 Set Operators 476 Conversion Methods 477 Element Operators 480 Aggregation Methods 482 Quantifiers 486 Generation Methods 487 10. LINQ to XML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489 Architectural Overview 489 X-DOM Overview 490 Instantiating an X-DOM 494 Navigating and Querying 496 Updating an X-DOM 501 Working with Values 505 Documents and Declarations 507 Names and Namespaces 511 Annotations 516 Projecting into an X-DOM 517 11. Other XML and JSON Technologies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521 XmlReader 521 XmlWriter 529 Patterns for Using XmlReader/XmlWriter 531 Working with JSON 536 12. Disposal and Garbage Collection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543 IDisposable, Dispose, and Close 543 Automatic Garbage Collection 549 Finalizers 551 How the GC Works 555 Managed Memory Leaks 562 Weak References 565 13. Diagnostics. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571 Conditional Compilation 571 Debug and Trace Classes 575 Debugger Integration 578 vi | Table of Contents Processes and Process Threads 579 StackTrace and StackFrame 580 Windows Event Logs 582 Performance Counters 584 The Stopwatch Class 588 Cross-Platform Diagnostics Tools 589 14. Concurrency and Asynchrony. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595 Introduction 595 Threading 596 Tasks 612 Principles of Asynchrony 620 Asynchronous Functions in C# 625 Asynchronous Patterns 645 Obsolete Patterns 653 15. Streams and I/O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657 Stream Architecture 657 Using Streams 659 Stream Adapters 673 Compression Streams 681 Working with ZIP Files 684 File and Directory Operations 685 File I/O in UWP 696 OS Security 700 Memory-Mapped Files 703 16. Networking. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707 Network Architecture 707 Addresses and Ports 709 URIs 710 Client-Side Classes 712 Working with HTTP 726 Writing an HTTP Server 730 Using FTP 733 Using DNS 735 Sending Mail with SmtpClient 735 Using TCP 736 Table of Contents | vii Receiving POP3 Mail with TCP 740 TCP in UWP 742 17. Assemblies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745 What’s in an Assembly 745 Strong Names and Assembly Signing 750 Assembly Names 751 Authenticode Signing 753 Resources and Satellite Assemblies 756 Loading, Resolving, and Isolating Assemblies 763 18. Reflection and Metadata. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 785 Reflecting and Activating Types 786 Reflecting and Invoking Members 793 Reflecting Assemblies 805 Working with Attributes 806 Dynamic Code Generation 811 Emitting Assemblies and Types 818 Emitting Type Members 821 Emitting Generic Methods and Types 827 Awkward Emission Targets 829 Parsing IL 832 19. Dynamic Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839 The Dynamic Language Runtime 839 Numeric Type Unification 840 Dynamic Member Overload Resolution 842 Implementing Dynamic Objects 848 Interoperating with Dynamic Languages 851 20. Cryptography. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 855 Overview 855 Windows Data Protection 856 Hashing 857 Symmetric Encryption 859 Public-Key Encryption and Signing 864 21. Advanced Threading. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 869 Synchronization Overview 870 viii | Table of Contents