Chapter 1. The changing face of C# development
Listing 1.1. The Product type (C# 1)
Listing 1.2. Strongly typed collections and private setters (C# 2)
Listing 1.3. Automatically implemented properties and simpler initialization (C# 3)
Listing 1.4. Named arguments for clear initialization code (C# 4)
Listing 1.5. Sorting an ArrayList using IComparer (C# 1)
Listing 1.6. Sorting a List<Product> using IComparer<Product> (C# 2)
Listing 1.7. Sorting a List<Product> using Comparison<Product> (C# 2)
Listing 1.8. Sorting using Comparison<Product> from a lambda expression (C# 3)
Listing 1.9. Ordering a List<Product> using an extension method (C# 3)
Listing 1.10. Looping, testing, printing out (C# 1)
Listing 1.11. Separating testing from printing (C# 2)
Listing 1.12. Separating testing from printing redux (C# 2)
Listing 1.13. Testing with a lambda expression (C# 3)
Listing 1.14. Displaying products with an unknown price (C# 3)
Listing 1.15. First steps with query expressions: filtering a collection
Listing 1.16. Joining, filtering, ordering, and projecting (C# 3)
Listing 1.17. Complex processing of an XML file with LINQ to XML (C# 3)
Listing 1.18. Applying a query expression to a SQL database (C# 3)
Listing 1.19. Saving data to Excel using COM (C# 4)
Listing 1.20. Running IronPython and extracting properties dynamically (C# 4)
Chapter 2. Core foundations: building on C# 1
Listing 2.1. Using delegates in a variety of simple ways
Listing 2.2. Demonstrating a type-unsafe system with C code
Listing 2.3. Demonstration of the covariance of arrays, and execution time checking
Listing 2.4. Improvements in delegate instantiation brought in by C# 2
Listing 2.5. Lambda expressions, which are like improved anonymous methods
Listing 2.6. Demonstration of anonymous types and implicit typing
Listing 2.7. Dynamic typing in C# 4
Listing 2.8. Demonstration of a variety of nullable type features
Chapter 3. Parameterized typing with generics
Listing 3.1. Using a Dictionary<TKey,TValue> to count words in text
Listing 3.2. The List<T>.ConvertAll<TOutput> method in action
Listing 3.3. Implementing a generic method in a nongeneric type
Listing 3.4. Comparing a given value to the default in a generic way
Listing 3.5. Comparisons using == and != using reference comparisons
Listing 3.6. Generic class representing a pair of values
Listing 3.7. Using a nongeneric type with a generic method to enable type inference
Listing 3.8. Proof that different closed types have different static fields
Listing 3.9. Static constructors with nested generic types
Listing 3.10. A full generic iterator—of the numbers 0 to 9
Listing 3.11. Using the typeof operator with type parameters
Listing 3.12. Various ways of retrieving generic and constructed Type objects
Listing 3.13. Retrieving and invoking a generic method with reflection
Listing 3.14. Working around the lack of contravariance with a helper
Chapter 4. Saying nothing with nullable types
Listing 4.1. Using various members of Nullable<T>
Listing 4.2. Boxing and unboxing behavior of nullable types
Listing 4.3. The same code as listing 4.2 but using the ? modifier
Listing 4.4. Part of a Person class including calculation of age
Listing 4.5. An alternative implementation of the TryXXX pattern
Chapter 5. Fast-tracked delegates
Listing 5.1. Subscribing to three of a button’s events
Listing 5.2. Demonstration of method group conversions and delegate contravariance
Listing 5.3. Demonstration of covariance of return types for delegates
Listing 5.4. Demonstration of breaking change between C# 1 and C# 2
Listing 5.5. Anonymous methods used with the Action<T> delegate type
Listing 5.6. Extreme example of code compactness. Warning: unreadable code ahead!
Listing 5.7. Returning a value from an anonymous method
Listing 5.8. Using anonymous methods to sort files simply
Listing 5.9. Subscribing to events with anonymous methods that ignore parameters
Listing 5.10. Examples of different kinds of variables with respect to anonymous methods
Listing 5.11. Accessing a variable both inside and outside an anonymous method
Listing 5.12. Demonstration of a captured variable having its lifetime extended
Listing 5.13. Capturing multiple variable instantiations with multiple delegates
Listing 5.14. Capturing variables in different scopes. Warning: nasty code ahead!
Chapter 6. Implementing iterators the easy way
Listing 6.1. Code using the (as yet unimplemented) new collection type
Listing 6.2. Skeleton of the new collection type, with no iterator implementation
Listing 6.3. Nested class implementing the collection’s iterator
Listing 6.4. Iterating through the sample collection with C# 2 and yield return
Listing 6.5. Showing the sequence of calls between an iterator and its caller
Listing 6.6. Demonstration of yield break
Listing 6.7. Demonstration of yield break working with try/finally
Listing 6.8. Looping over the lines in a file using an iterator block
Listing 6.9. Implementing LINQ’s Where method using iterator blocks
Chapter 7. Concluding C# 2: the final features
Listing 7.1. Demonstration of mixing declarations of a partial type
Listing 7.2. A partial method called from a constructor
Listing 7.3. A typical C# 1 utility class
Listing 7.4. The same utility class as in listing 7.3 but converted into a C# 2 static class
Listing 7.5. Using aliases to distinguish between different Button types
Listing 7.6. Using :: to tell the compiler to use aliases
Listing 7.7. Use of the global namespace alias to specify the desired type exactly
Listing 7.8. Working with different types of the same type in different assemblies
Listing 7.9. Class containing an unused field
Listing 7.10. Disabling (and restoring) warning CS0169
Listing 7.11. Demonstration of fixed-size buffers to obtain console color information
Chapter 8. Cutting fluff with a smart compiler
Listing 8.1. Demonstration of the awkwardness of static automatic properties
Listing 8.2. A fairly simple Person class used for further demonstrations
Listing 8.3. Building up a rich object using object and collection initializers
Listing 8.4. Creating objects of an anonymous type with Name and Age properties
Listing 8.5. Populating an array using anonymous types and then finding the total age
Listing 8.6. Transformation from Person to a name and adulthood flag
Chapter 9. Lambda expressions and expression trees
Listing 9.1. Using an anonymous method to create a delegate instance
Listing 9.2. A long-winded first lambda expression, similar to an anonymous method
Listing 9.3. A concise lambda expression
Listing 9.4. Manipulating a list of films using lambda expressions
Listing 9.5. Logging events using lambda expressions
Listing 9.6. A simple expression tree, adding 2 and 3
Listing 9.7. Compiling and executing an expression tree
Listing 9.8. Using lambda expressions to create expression trees
Listing 9.9. Demonstration of a more complicated expression tree
Listing 9.10. Building a method call expression tree in code
Listing 9.11. Example of code requiring the new type inference rules
Listing 9.12. Attempting to infer the return type of an anonymous method
Listing 9.13. Code returning an integer or an object depending on the time of day
Listing 9.14. Flexible type inference combining information from multiple arguments
Listing 9.15. Multistage type inference
Listing 9.16. Sample of overloading choice influenced by delegate return type
Chapter 10. Extension methods
Listing 10.1. A simple utility class to provide extra functionality for streams
Listing 10.2. Using StreamUtil to copy a web response stream to a file
Listing 10.3. The StreamUtil class again, but this time with extension methods
Listing 10.4. Copying a stream using an extension method
Listing 10.5. Extension method being called on a null reference
Listing 10.6. Using Enumerable.Range to print out the numbers 0 to 9
Listing 10.7. Reversing a collection with the Reverse method
Listing 10.8. Using the Where method with a lambda expression to find odd numbers
Listing 10.9. Projection using a lambda expression and an anonymous type
Chapter 11. Query expressions and LINQ to Objects
Listing 11.1. Trivial query to print the list of users
Listing 11.2. The query expression of listing 11.1 translated into a method call
Listing 11.3. Compiler translation calling methods on a dummy LINQ implementation
Listing 11.4. Query selecting just the names of the users
Listing 11.5. Using Cast and OfType to work with weakly typed collections
Listing 11.6. Using an explicitly typed range variable to automatically call Cast
Listing 11.7. Query expression using multiple where clauses
Listing 11.8. Sorting by the severity of a defect, from high to low priority
Listing 11.9. Ordering by severity and then last modified time
Listing 11.10. Sorting by the lengths of user names without a let clause
Listing 11.11. Using a let clause to remove redundant calculations
Listing 11.12. Joining the defects and notification subscriptions based on project
Listing 11.13. Joining defects and subscriptions with a group join
Listing 11.14. Counting the number of defects raised on each day in May
Listing 11.15. Cross joining users against projects
Listing 11.16. Cross join where the right sequence depends on the left element
Listing 11.17. Grouping defects by assignee—trivial projection
Listing 11.18. Grouping defects by assignee—projection retains just the summary
Listing 11.19. Continuing a grouping with another projection
Listing 11.20. Query expression continuations from group and select
Chapter 12. LINQ beyond collections
Listing 12.1. Querying the database to find all Tim’s open defects
Listing 12.2. Using a let clause in LINQ to SQL
Listing 12.3. A simple implementation of IQueryable that logs method calls
Listing 12.4. An implementation of IQueryProvider that uses FakeQuery
Listing 12.5. A simple query expression using the fake query classes
Listing 12.6. IQueryProvider.Execute
Listing 12.7. Creating elements from the sample users
Listing 12.8. Creating elements with text nodes
Listing 12.9. Displaying the users within an XML structure
Listing 12.10. Single-threaded Mandelbrot generation query
Listing 12.11. First attempt at a multithreaded Mandelbrot generation query
Listing 12.12. Multithreaded Mandelbrot query maintaining ordering
Listing 12.13. First contact with IObservable<T>
Listing 12.14. Filtering and projecting in LINQ to Rx
Listing 12.15. Grouping numbers mod 3
Listing 12.16. SelectMany producing multiple ranges
Listing 12.17. Extension method to choose a random element from a sequence
Chapter 13. Minor changes to simplify code
Listing 13.1. Declaring a method with optional parameters and calling
Listing 13.2. Using null default values to handle nonconstant situations
Listing 13.3. Simple examples of using named arguments
Listing 13.4. Logging argument evaluation
Listing 13.5. Abusing argument evaluation order
Listing 13.6. Combining named and optional arguments
Listing 13.7. Constructing an immutable message using C# 4
Listing 13.8. Creating and saving a document in C# 3
Listing 13.9. Automating Word using normal C# 4 features
Listing 13.10. Passing arguments by value in COM methods
Listing 13.11. Displaying synonym counts using a named indexer
Listing 13.12. Building a list of general shapes from lists of circles and squares
Listing 13.13. Sorting circles using a general-purpose comparer and contravariance
Listing 13.14. Using variance with simple Func<T> and Action<T> delegates
Listing 13.15. Demonstrating covariance and contravariance with a single type
Chapter 14. Dynamic binding in a static language
Listing 14.1. Using dynamic to iterate through a list, concatenating strings
Listing 14.2. Adding integers to strings dynamically
Listing 14.3. Adding integers to integers
Listing 14.4. Adding integers to integers—but without the exception
Listing 14.5. Setting a range of values with static typing
Listing 14.6. Using implicit conversions from dynamic in Excel
Listing 14.7. Using dynamic everywhere
Listing 14.8. Printing “hello, world” twice using Python embedded in C#
Listing 14.9. Passing information between a host and a script using ScriptScope
Listing 14.10. Calling a function declared in a ScriptScope
Listing 14.11. Using dynamic type inference
Listing 14.12. Summing an arbitrary sequence of elements dynamically
Listing 14.13. Summing a list of TimeSpan elements dynamically
Listing 14.14. Accessing a Count property with duck typing
Listing 14.15. Counting different types efficiently using multiple dispatch
Listing 14.16. Experimenting with method overloading and dynamic values
Listing 14.17. The results of compiling dynamic code
Listing 14.18. Dynamic overload resolution within a single type
Listing 14.19. Dynamic overload resolution within a class hierarchy
Listing 14.20. Catching errors in dynamic calls at compile time
Listing 14.21. Generic type inference with mixed static and dynamic values
Listing 14.22. Calling extension methods with dynamic arguments
Listing 14.23. Dynamic types and lambda expressions
Listing 14.24. Querying a collection of dynamic elements
Listing 14.25. Storing and retrieving values with ExpandoObject
Listing 14.26. Faking methods on an ExpandoObject with delegates
Listing 14.27. Implementing a simplistic XML DOM conversion with ExpandoObject
Listing 14.28. Using a dynamic DOM created from expandos
Listing 14.29. Skeleton of DynamicXElement
Listing 14.30. Adding nondynamic members to DynamicXElement
Listing 14.31. Implementing a dynamic property with TryGetMember()
Listing 14.32. Testing DynamicXElement
Listing 14.33. Implementing GetDynamicMemberNames in DynamicXElement
Listing 14.34. The final aim: calling methods dynamically until we hit the right name
Listing 14.35. The Rumpelstiltskin type, without its metaobject code
Listing 14.36. The real dynamic guts of Rumpelstiltskin—its metaobject
Chapter 15. Letting your code speak more clearly with Code Contracts
Listing 15.1. Simple method with argument validation and documentation
Listing 15.2. Expressing a simple postcondition for a return value
Listing 15.3. A complicated postcondition involving a return value, old and new state
Listing 15.4. Making assumptions and assertions when rolling dice
Listing 15.5. Signalling the end of a contract block explicitly
Listing 15.6. A simple contract after binary rewriting
Listing 15.7. Contract inheritance with concrete classes
Listing 15.8. Specifying contracts for an interface
Listing 15.9. Adding preconditions at the call site
Listing 15.10. Masking a contract with Contract.ContractFailed
Listing 15.11. Experimenting with the static checker and simple contracts
Listing 15.12. Testing implicit non-null obligations
Listing 15.13. Invalid indexing due to a typo
Listing 15.14. More complex array bounds checking
Listing 15.15. An incorrect implementation of a “reverse comparer”
Listing 15.16. Applying checking selectively with [ContractVerification]
Listing 15.17. Automatically documenting method contracts with ccdocgen
Appendix B. Generic collections in .NET
Listing B.1. Demonstration of custom key comparisons in a dictionary
3.145.87.161