Chapter 1. The changing face of C# development
1.1. Starting with a simple data type
1.1.1. The Product type in C# 1
1.1.2. Strongly typed collections in C# 2
1.3. Handling an absence of data
1.6. Dissecting the .NET platform
1.7. Making your code super awesome
1.7.1. Presenting full programs as snippets
Chapter 2. Core foundations: building on C# 1
2.1.1. A recipe for simple delegates
2.1.2. Combining and removing delegates
2.2. Type system characteristics
2.2.1. C#’s place in the world of type systems
2.3. Value types and reference types
2.3.1. Values and references in the real world
2.4. Beyond C# 1: new features on a solid base
2.4.1. Features related to delegates
2. C# 2: Solving the Issues of C# 1
Chapter 3. Parameterized typing with generics
3.1. Why generics are necessary
3.2. Simple generics for everyday use
3.2.1. Learning by example: a generic dictionary
3.4.1. Static fields and static constructors
3.5. Limitations of generics in C# and other languages
3.5.1. Lack of generic variance
3.5.2. Lack of operator constraints or a “numeric” constraint
3.5.3. Lack of generic properties, indexers, and other member types
Chapter 4. Saying nothing with nullable types
4.1. What do you do when you just don’t have a value?
4.2. System.Nullable<T>and System.Nullable
4.2.1. Introducing Nullable<T>
4.2.2. Boxing Nullable<T>and unboxing
4.3. C# 2’s syntactic sugar for nullable types
4.3.2. Assigning and comparing with null
4.3.3. Nullable conversions and operators
4.4. Novel uses of nullable types
4.4.1. Trying an operation without using output parameters
4.4.2. Painless comparisons with the null coalescing operator
Chapter 5. Fast-tracked delegates
5.1. Saying goodbye to awkward delegate syntax
5.3. Covariance and contravariance
5.3.1. Contravariance for delegate parameters
5.4. Inline delegate actions with anonymous methods
5.4.1. Starting simply: acting on a parameter
5.5. Capturing variables in anonymous methods
5.5.1. Defining closures and different types of variables
5.5.2. Examining the behavior of captured variables
5.5.3. What’s the point of captured variables ?
5.5.4. The extended lifetime of captured variables
5.5.5. Local variable instantiations
Chapter 6. Implementing iterators the easy way
6.1. C# 1: the pain of handwritten iterators
6.2. C# 2: simple iterators with yield statements
6.2.1. Introducing iterator blocks and yield return
6.2.2. Visualizing an iterator’s workflow
6.3. Real-life iterator examples
6.3.1. Iterating over the dates in a timetable
6.3.2. Iterating over lines in a file
6.3.3. Filtering items lazily using an iterator block and a predicate
6.4. Pseudo-synchronous code with the Concurrency and Coordination Runtime
Chapter 7. Concluding C# 2: the final features
7.3. Separate getter/setter property access
7.4.1. Qualifying namespace aliases
7.6. Fixed-size buffers in unsafe code
7.7. Exposing internal members to selected assemblies
7.7.1. Friend assemblies in the simple case
3. C# 3: Revolutionizing How We Code
Chapter 8. Cutting fluff with a smart compiler
8.1. Automatically implemented properties
8.2. Implicit typing of local variables
8.2.1. Using var to declare a local variable
8.2.2. Restrictions on implicit typing
8.3. Simplified initialization
8.3.1. Defining our sample types
8.3.2. Setting simple properties
8.3.3. Setting properties on embedded objects
8.5.1. First encounters of the anonymous kind
8.5.2. Members of anonymous types
Chapter 9. Lambda expressions and expression trees
9.1. Lambda expressions as delegates
9.1.1. Preliminaries: introducing the Func<...> delegate types
9.1.2. First transformation to a lambda expression
9.1.3. Using a single expression as the body
9.2. Simple examples using List<T> and events
9.3.1. Building expression trees programmatically
9.3.2. Compiling expression trees into delegates
9.3.3. Converting C# lambda expressions to expression trees
9.4. Changes to type inference and overload resolution
9.4.1. Reasons for change: streamlining generic method calls
9.4.2. Inferred return types of anonymous functions
9.4.3. Two-phase type inference
10.1. Life before extension methods
10.2.1. Declaring extension methods
10.2.2. Calling extension methods
10.3. Extension methods in .NET 3.5
10.3.1. First steps with Enumerable
10.3.2. Filtering with Where and chaining method calls together
10.3.3. Interlude: haven’t we seen the Where method before?
10.3.4. Projections using the Select method and anonymous types
10.4. Usage ideas and guidelines
Chapter 11. Query expressions and LINQ to Objects
11.2. Simple beginnings: selecting elements
11.2.1. Starting with a source and ending with a selection
11.2.2. Compiler translations as the basis of query expressions
11.3. Filtering and ordering a sequence
11.3.1. Filtering using a where clause
11.4. Let clauses and transparent identifiers
11.5.1. Inner joins using join clauses
11.5.2. Group joins with join ... into clauses
11.5.3. Cross joins and flattening sequences using multiple from clauses
11.6. Groupings and continuations
11.7. Choosing between query expressions and dot notation
11.7.1. Operations that require dot notation
Chapter 12. LINQ beyond collections
12.1. Querying a database with LINQ to SQL
12.2. Translations using IQueryable and IQueryProvider
12.2.1. Introducing IQueryable<T> and related interfaces
12.2.2. Faking it: interface implementations to log calls
12.2.3. Gluing expressions together: the Queryable extension methods
12.3. LINQ-friendly APIs and LINQ to XML
12.3.1. Core types in LINQ to XML
12.3.2. Declarative construction
12.3.3. Queries on single nodes
12.4. Replacing LINQ to Objects with Parallel LINQ
12.4.1. Plotting the Mandelbrot set with a single thread
12.4.2. Introducing ParallelEnumerable, ParallelQuery, and AsParallel
12.5. Inverting the query model with LINQ to Rx
12.5.1. IObservable<T> and IObserver<T>
12.6. Extending LINQ to Objects
4. C# 4: Playing Nicely with Others
Chapter 13. Minor changes to simplify code
13.1. Optional parameters and named arguments
13.2. Improvements for COM interoperability
13.2.1. The horrors of automating Word before C# 4
13.2.2. The revenge of optional parameters and named arguments
13.2.3. When is a ref parameter not a ref parameter?
13.3. Generic variance for interfaces and delegates
13.3.1. Types of variance: covariance and contravariance
13.3.2. Using variance in interfaces
13.4. Teeny tiny changes to locking and field-like events
Chapter 14. Dynamic binding in a static language
14.1.1. What is dynamic typing?
14.2. The five-minute guide to dynamic
14.3. Examples of dynamic typing
14.3.1. COM in general, and Microsoft Office in particular
14.4. Looking behind the scenes
14.4.1. Introducing the Dynamic Language Runtime
14.4.3. How the C# compiler handles dynamic
14.5. Implementing dynamic behavior
Chapter 15. Letting your code speak more clearly with Code Contracts
15.1. Life before Code Contracts
15.2. Introducing Code Contracts
15.3. Rewriting binaries with ccrewrite and ccrefgen
15.5. Documenting contracts with ccdocgen
16.1. C#—mixing tradition and modernity
Appendix A. LINQ standard query operators
Appendix B. Generic collections in .NET
B.2.4. Collection<T>, BindingList<T>, ObservableCollection<T>, and KeyedCollection<TKey, TItem>
B.2.5. ReadOnlyCollection<T>and ReadOnlyObservableCollection<T>
B.3.1. Dictionary<TKey, TValue>
B.3.2. SortedList<TKey, TValue>and SortedDictionary<TKey, TValue>
B.6. Concurrent collections (.NET 4)
B.6.1. IProducerConsumerCollection<T> and BlockingCollection<T>
B.6.2. ConcurrentBag<T>, ConcurrentQueue<T>, ConcurrentStack<T>
C.1. Desktop framework major releases
C.3. Framework library features
18.221.249.198