Chapter 2. C# 2
Listing 2.1. Generating and printing names by using arrays
Listing 2.2. Generating and printing names by using ArrayList
Listing 2.3. Generating and printing names by using StringCollection
Listing 2.4. Generating and printing names with List<T>
Listing 2.5. Copying elements from one collection to another
Listing 2.6. Printing items in the invariant culture by using type constraints
Listing 2.7. Printing the result of the typeof operator
Listing 2.8. Exploring static fields in generic types
Listing 2.9. The effects of boxing nullable value type values
Listing 2.10. Calling GetType on nullable values leads to surprising results
Listing 2.11. A simple iterator yielding integers
Listing 2.12. The expansion of a foreach loop
Listing 2.13. Iterating over the Fibonacci sequence
Listing 2.14. An iterator that logs its progress
Listing 2.15. A simple foreach loop to iterate and log
Listing 2.16. Breaking out of a foreach loop by using an iterator
Listing 2.17. Expansion of listing 2.16 to not use a foreach loop
Listing 2.18. Reading lines from a file
Listing 2.19. Sample iterator method to decompile
Listing 2.20. Infrastructure of the generated code for an iterator
Listing 2.21. Simplified MoveNext() method
Listing 2.22. A simple partial class
Listing 2.23. Two partial methods—one implemented, one not
Listing 2.24. Demonstration of static classes
Listing 2.25. Namespace aliases in C# 1
Listing 2.26. Using fixed-size buffers for a versioned chunk of binary data
Chapter 3. C# 3: LINQ and everything that comes with it
Listing 3.1. Modeling an order in an e-commerce system
Listing 3.2. Creating and populating an order without object and collection initializers
Listing 3.3. Creating and populating an order with object and collection initializers
Listing 3.4. Modifying default headers on a new HttpClient with a nested object initializer
Listing 3.5. Anonymous type with Name and Score properties
Listing 3.6. Capturing variables in a lambda expression
Listing 3.7. Translation of a lambda expression with captured variables
Listing 3.8. Instantiating a local variable multiple times
Listing 3.9. Creating multiple context instances, one for each instantiation
Listing 3.10. Capturing variables from multiple scopes
Listing 3.11. Capturing variables from multiple scopes leads to multiple classes
Listing 3.12. A simple expression tree to add two integers
Listing 3.13. Handwritten code to create an expression tree to add two integers
Listing 3.14. Compiling an expression tree to a delegate and invoking the result
Listing 3.15. ToInstant extension method targeting DateTimeOffset from Noda Time
Listing 3.16. Invoking the ToInstant() extension method outside Noda Time
Listing 3.17. A simple query on strings
Listing 3.18. A simple query without using extension methods
Listing 3.19. A simple query in multiple statements
Listing 3.20. Introductory query expression with filtering, ordering, and projection
Listing 3.21. A let clause introducing a new range variable
Listing 3.22. Query translation using a transparent identifier
Chapter 4. C# 4: Improving interoperability
Listing 4.1. Taking a substring by using dynamic typing
Listing 4.2. Addition of dynamic values
Listing 4.3. Dynamic method overload resolution
Listing 4.4. Examples of compile-time failures involving dynamic values
Listing 4.5. Storing and retrieving items in an ExpandoObject
Listing 4.6. Using JSON data dynamically
Listing 4.7. Example of intended use of dynamic behavior
Listing 4.8. Implementing SimpleDynamicExample
Listing 4.9. The result of decompiling two simple dynamic operations
Listing 4.10. A LINQ query over a list of dynamic values
Listing 4.11. Attempting to call an extension method on a dynamic target
Listing 4.12. Attempting to use a dynamic element type in an IQueryable<T>
Listing 4.13. Dynamic access to a property of an anonymous type
Listing 4.14. Example of explicit interface implementation
Listing 4.15. Calling a method with optional parameters
Listing 4.16. Setting a range of values in Excel with implicit dynamic conversion
Listing 4.17. Creating a Word document and saving it before C# 4
Listing 4.18. Creating a Word document and saving it using C# 4
Listing 4.19. Accessing a named indexer
Listing 4.20. Creating a List<object> from a string query without variance
Listing 4.21. Creating a List<object> from a string query by using variance
Listing 4.22. Sorting a List<Circle> with an IComparer<Shape>
Chapter 5. Writing asynchronous code
Listing 5.1. Displaying a page length asynchronously
Listing 5.2. Retrieving a page length in an asynchronous method
Listing 5.3. Using unsafe code in an async method
Listing 5.4. Awaiting completed and noncompleted tasks
Listing 5.5. Catching exceptions when fetching web pages
Listing 5.6. Broken argument validation in an async method
Listing 5.7. Eager argument validation with a separate method
Listing 5.8. Creating a canceled task by throwing OperationCanceledException
Listing 5.9. Creating and calling an asynchronous function using a lambda expression
Listing 5.10. Wrapping a stream for efficient asynchronous byte-wise access
Listing 5.11. Skeleton of the members required for a generic task type
Chapter 6. Async implementation
Listing 6.1. Simple introductory async method
Listing 6.2. Generated code for listing 6.1 (except for MoveNext)
Listing 6.3. The decompiled MoveNext() method from listing 6.1
Listing 6.4. Pseudocode of a MoveNext() method
Listing 6.5. A section of listing 6.3 corresponding to a single await
Listing 6.6. Introducing a loop between await expressions
Listing 6.7. Awaiting in a loop
Listing 6.8. Decompiled loop without using any loop constructs
Listing 6.9. Awaiting within a try block
Chapter 7. C# 5 bonus features
Listing 7.1. Capturing the iteration variable in a foreach loop
Listing 7.2. Capturing the iteration variable in a for loop
Listing 7.3. Basic demonstration of caller member attributes
Listing 7.4. Implementing INotifyPropertyChanged the old way
Listing 7.5. Using caller information to implement INotifyPropertyChanged
Listing 7.6. Caller information attributes and dynamic typing
Listing 7.7. Caller information in a constructor
Listing 7.8. Caller information in query expressions
Listing 7.9. Attribute class that captures caller information
Listing 7.10. Applying the attribute to a class and a method
Chapter 8. Super-sleek properties and expression-bodied members
Listing 8.1. Point class with public fields
Listing 8.2. Point class with properties in C# 1
Listing 8.3. Point class with properties in C# 3
Listing 8.4. Point class with read-only properties via manual implementation in C# 3
Listing 8.6. Point class using read-only automatically implemented properties
Listing 8.7. Person class with manual property in C# 2
Listing 8.8. Person class with automatically implemented property in C# 3
Listing 8.9. Person class with automatically implemented read/write property in C# 6
Listing 8.10. Person class with automatically implemented read-only property in C# 6
Listing 8.11. Point struct in C# 5 using automatically implemented properties
Listing 8.12. Point struct in C# 6 using automatically implemented properties
Listing 8.13. Adding a DistanceFromOrigin property to Point
Listing 8.14. Delegating properties in Noda Time
Listing 8.15. Simple methods and operators in C# 5
Listing 8.16. Expression-bodied methods and operators in C# 6
Listing 8.17. IReadOnlyList<T> implementation using expression-bodied members
Chapter 9. Stringy features
Listing 9.1. Displaying a price, tip, and total with values aligned
Listing 9.2. Formatting a single date in every culture
Listing 9.3. Aligned values using interpolated string literals
Listing 9.4. Aligned values using a single interpolated verbatim string literal
Listing 9.5. Members declared by FormattableString
Listing 9.6. Formatting a date in the invariant culture
Listing 9.7. Awooga! Awooga! Do not use this code!
Listing 9.8. Safe SQL parameterization using FormattableString
Listing 9.9. Implementing safe SQL formatting
Listing 9.10. Implementing FormattableString from scratch
Listing 9.11. Even FormattableString evaluates expressions eagerly
Listing 9.12. Printing out the names of a class, method, field, and parameter
Listing 9.13. A simple method using its parameter twice in the body
Listing 9.14. Using nameof to raise a property change notification
Listing 9.15. Specifying a test case source with nameof
Listing 9.16. All the valid ways of accessing names of members in other types
Chapter 10. A smörgåsbord of features for concise code
Listing 10.1. Polar-to-Cartesian conversion in C# 5
Listing 10.2. Polar-to-Cartesian conversion in C# 6
Listing 10.3. Selective importing of extension methods
Listing 10.4. Attempting to call Enumerable.Count in two ways
Listing 10.5. Using an indexer in a StringBuilder object initializer
Listing 10.6. Two ways of initializing a dictionary
Listing 10.7. A schemaless entity type with key properties
Listing 10.8. Two ways of initializing a SchemalessEntity
Listing 10.9. Exposing explicit interface implementations via extension methods
Listing 10.10. Adding a type-argument-specific Add method for dictionaries
Listing 10.11. Exposing explicit interface implementations via extension methods
Listing 10.12. Sketch of a null-conditional-friendly logging API
Listing 10.13. Throwing three exceptions and catching two of them
Listing 10.14. A three-level demonstration of exception filtering
Chapter 11. Composition using tuples
Listing 11.1. Representing the minimum and maximum values of a sequence as a tuple
Listing 11.2. Reading and writing tuple elements by name and position
Listing 11.3. Using a tuple instead of two local variables in MinMax
Listing 11.4. Reassigning the result tuple in one statement in MinMax
Listing 11.5. Implementing the Fibonacci sequence without tuples
Listing 11.6. Implementing the Fibonacci sequence with tuples
Listing 11.7. Separating concerns of sequence generation for Fibonacci
Listing 11.8. Equality and inequality operators
Listing 11.9. Finding and ordering distinct points
Listing 11.10. Structural comparisons with a case-insensitive comparer
Listing 11.11. Displaying the highest-scoring player for a date
Chapter 12. Deconstruction and pattern matching
Listing 12.1. Overview of deconstruction using tuples
Listing 12.2. Calling a method and deconstructing the result into three variables
Listing 12.3. Assignments to existing variables using deconstruction
Listing 12.4. Simple constructor assignments using deconstruction and a tuple literal
Listing 12.5. Deconstruction in which evaluation order matters
Listing 12.6. Slow-motion deconstruction to show evaluation order
Listing 12.7. Deconstructing a Point to two variables
Listing 12.8. Using an extension method to deconstruct DateTime
Listing 12.9. Using Deconstruct overloads
Listing 12.10. Computing a perimeter without patterns
Listing 12.11. Computing a perimeter with patterns
Listing 12.12. Simple constant matches
Listing 12.13. Using type patterns instead of as/if
Listing 12.14. Behavior of nullable value types in type patterns
Listing 12.15. Generic method using type patterns
Listing 12.16. Using the var pattern to introduce a variable on error
Listing 12.17. Implementing the Fibonacci sequence recursively with patterns
Listing 12.18. Using multiple case labels with patterns for a single case body
Chapter 13. Improving efficiency with more pass by reference
Listing 13.1. Using the same variable for multiple ref parameters
Listing 13.2. Incrementing twice via two variables
Listing 13.3. Modifying array elements using ref local
Listing 13.4. Aliasing the field of a specific object by using ref local
Listing 13.5. Identity conversion in ref local declaration
Listing 13.6. Simplest possible ref return demonstration
Listing 13.7. Incrementing the result of a ref return directly
Listing 13.8. A ref return indexer exposing array elements
Listing 13.9. Counting even and odd elements in a sequence
Listing 13.10. ref readonly return and local
Listing 13.11. A read-only view over an array with copy-free reads
Listing 13.12. Valid and invalid possibilities for passing arguments for in parameters
Listing 13.13. in parameter and value parameter differences in the face of side effects
Listing 13.14. Using in parameters safely
Listing 13.15. A trivial year/month/day struct
Listing 13.16. Accessing properties via a read-only or read-write field
Listing 13.17. A trivial Vector3D struct
Listing 13.18. Extension methods using ref and in
Listing 13.19. Calling ref and in extension methods
Listing 13.20. Generating a random string by using a char[]
Listing 13.21. Generating a random string by using stackalloc and a pointer
Listing 13.22. Generating a random string by using stackalloc and a Span<char>
Listing 13.23. Generating a random string with string.Create
Chapter 14. Concise code in C# 7
Listing 14.1. A simple local method that accesses a local variable
Listing 14.2. Local method modifying a local variable
Listing 14.3. What Roslyn does with listing 14.2
Listing 14.4. Capturing variables from multiple scopes
Listing 14.5. What Roslyn does with listing 14.4
Listing 14.6. Method group conversion of a local method
Listing 14.7. What Roslyn does with listing 14.6
Listing 14.8. Implementing Select without local methods
Listing 14.9. Implementing Select with a local method
Listing 14.10. Using an out variable in a constructor initializer
Listing 14.11. Specifying a default literal as a method argument
Chapter 15. C# 8 and beyond
Listing 15.1. Initial model before C# 8
Listing 15.2. Model with non-nullable properties everywhere
Listing 15.3. Making the customer Address property nullable
Listing 15.4. Safe dereferencing using the null conditional operator
Listing 15.5. Checking a reference with a local variable
Listing 15.6. Checking a reference with repeated property access
Listing 15.7. Using the bang operator to satisfy the compiler
Listing 15.8. Using the bang operator in unit tests
Listing 15.9. Converting a switch statement into a switch expression
Listing 15.10. Using a switch expression to implement an expression-bodied method
Listing 15.11. Matching nested patterns
Listing 15.12. Matching customers against multiple patterns concisely
Listing 15.13. Trimming the first and last character from a string with a range
Listing 15.14. Index and range literals
Listing 15.15. Using indexer overloads for index and range in a string and a span
Listing 15.16. Implementing IAsyncDisposal and calling it with using await
Listing 15.17. Simplified RPC-based service for listing cities
Listing 15.18. Wrapper around the RPC service to provide a simpler API
Listing 15.19. Using foreach await with a GeoClient
Listing 15.20. Implementing ListCitiesAsync with an iterator