C# in Depth, Fourth Edition
Jon Skeet
  • MEAP began March 2017
  • Publication in Spring 2018 (estimated)
  • ISBN 9781617294532
  • 375 pages (estimated)
  • printed in black & white


An eBook copy of the previous edition, C# in Depth, Third Edition, is included at no additional cost. It will be automatically added to your Manning account within 24 hours of purchase.

C# is an amazing language that's up to any challenge you can throw at it. As a C# developer, you also need to be up to the task. C# in Depth, Fourth Edition is your key to unlocking the powerful new features added to the language in C# 5, 6, and 7. Following the expert guidance of C# legend Jon Skeet, you'll master asynchronous functions, expression-bodied members, interpolated strings, tuples, and much more.
Table of Contents detailed table of contents

Part 1: Introduction

1. Survival of the sharpest

2. Greatest hits of C# 2-4

Part 2: C# 5

3. Writing asynchronous code

3.1. Introducing asynchronous functions

3.1.1. First encounters of the asynchronous kind

3.1.2. Breaking down the first example

3.2. Thinking about asynchrony

3.2.1. Fundamentals of asynchronous execution

3.2.2. Synchronization contexts

3.2.3. Modeling asynchronous methods

3.3. Async method declarations

3.3.1. Return types from async methods

3.3.2. Parameters in async methods

3.4. Await expressions

3.4.1. The awaitable pattern

3.4.2. Restrictions on await expressions

3.5. Wrapping of return values

3.6. Asynchronous method flow

3.6.1. What is awaited and when?

3.6.2. Evaluation of await expressions

3.6.3. The use of awaitable pattern members

3.6.4. Exception unwrapping

3.6.5. Method completion

3.7. Asynchronous anonymous functions

3.8. Custom task types in C#7

3.8.1. The 99.9% case: ValueTask<TResult>

3.8.2. The 0.1% case: building your own custom task type

3.9. Async main methods in C#7.1

3.10. Usage tips

3.10.1. Avoid context capture using ConfigureAwait (where appropriate)

3.10.2. Enable parallelism by starting multiple independent tasks

3.10.3. Avoid mixing synchronous and asynchronous code

3.10.4. Allow cancellation wherever possible

3.10.5. Testing asynchrony

3.11. Summary

4. Async implementation

4.1. Structure of the generated code

4.1.1. The stub method: preparation and taking the first step

4.1.2. Structure of the state machine

4.1.3. The MoveNext() method (high level)

4.1.4. The SetStateMachine method and the state machine boxing dance

4.2. A “simple” MoveNext() implementation

4.2.1. A full concrete example

4.2.2. MoveNext() method general structure

4.2.3. Zooming into an await expression

4.3. How control flow affects MoveNext()

4.3.1. Control flow between await expressions is simple

4.3.2. Awaiting within a loop

4.3.3. Awaiting within a try/finally block

4.4. Execution contexts and flow

4.5. Custom task types revisited

4.6. Summary

5. C# 5 bonus features

Part 3: C# 6

6. Super-sleek properties and expression-bodied members

6.1. A brief history of properties

6.2. Upgrades to automatically implemented properties

6.2.1. Read-only automatically implemented properties

6.2.2. Initializing automatically implemented properties

6.2.3. Automatically implemented properties in structs

6.3. Expression-bodied members

6.3.1. Even simpler read-only computed properties

6.3.2. Expression-bodied methods, indexers and operators

6.3.3. Restrictions on expression-bodied members in C# 6

6.3.4. Guidelines for using expression-bodied members

6.4. Summary

7. Stringy features

7.1. A recap on string formatting in .NET

7.1.1. Simple string formatting

7.1.2. Custom formatting with format strings

7.1.3. Localization

7.2. Introducing interpolated string literals

7.2.1. Simple interpolation

7.2.2. Format strings in interpolated string literals

7.2.3. Interpolated verbatim string literals

7.2.4. Compiler handling of interpolated string literals (part 1)

7.3. Localization using FormattableString

7.3.1. Compiler handling of interpolated string literals (part 2)

7.3.2. Formatting a FormattableString in a specific culture

7.3.3. Other uses for FormattableString

7.3.4. Using FormattableString before with older versions of .NET

7.4. Uses, guidelines and limitations

7.4.1. Developers and machines, but maybe not end users

7.4.2. Hard limitations of interpolated string literals

7.4.3. When you can, but really shouldn't

7.5. Accessing identifiers with nameof

7.5.1. Common uses of nameof

7.5.2. Extra details

7.6. Summary

8. A smörgåsbord of features for concise code

8.1. "Using static" directives

8.1.1. Importing static members

8.1.2. Extension methods and using static

8.2. Object and collection initializer enhancements

8.2.1. Indexers in object initializers

8.2.2. Using extension methods in collection initializers

8.2.3. Test code vs production code

8.3. The null conditional operator

8.3.1. Simple and safe property dereferencing

8.3.2. The null conditional operator in more detail

8.3.3. Handling Boolean comparisons

8.3.4. Indexers and the null conditional operator

8.3.5. Working effectively with the null conditional operator

8.3.6. Limitations of the null conditional operator

8.4. Exception filters

8.4.1. Syntax and semantics of exception filters

8.4.2. Retrying operations

8.4.3. Logging as a side-effect

8.4.4. Individual, case-specific exception filters

8.4.5. Why not just throw?

8.5. Summary

Part 4: C# 7 and beyond

9. Composition using tuples

9.1. Introduction to tuples

9.2. Tuple literals and tuple types

9.2.1. Syntax

9.2.2. Tuples as bags of variables

9.3. Tuple types and conversions

9.3.1. Inferred types of tuple literals

9.3.2. Conversions from tuple literals to tuple types

9.3.3. Conversions between tuple types

9.3.4. Uses of conversions

9.3.5. Element name checking in inheritance

9.4. Tuples in the CLR

9.4.1. Introducing System.ValueTuple<…​>

9.4.2. Element name handling

9.4.3. Tuple conversion implementations

9.4.4. String representations of tuples

9.4.5. Regular equality and ordering comparisons

9.4.6. Structural equality and ordering comparisons

9.4.7. Womples and large tuples

9.4.8. The non-generic ValueTuple struct

9.4.9. Extension methods

9.5. Alternative options

9.5.1. System.Tuple<…​.>

9.5.2. Anonymous types

9.5.3. Named types

9.6. Uses and recommendations

9.6.1. Non-public APIs and easily-changed code

9.6.2. Local variables

9.6.3. Fields

9.6.4. Tuples and dynamic don't play together nicely

9.7. Summary

10. Pattern matching and deconstruction

10.1. Deconstruction of tuples

10.1.1. Deconstruction to new variables

10.1.2. Deconstruction assignments to existing variables and properties

10.1.3. Details of tuple literal deconstruction

10.2. Deconstruction of non-tuple types

10.2.1. Instance deconstruction methods

10.2.2. Extension deconstruction methods and overloading

10.2.3. Compiler handling of Deconstruct calls

10.3. Introduction to pattern matching

10.4. Patterns available in C# 7.0

10.4.1. Constant patterns

10.4.2. Type patterns

10.4.3. The var pattern

10.5. Using patterns with the is operator

10.6. Using patterns with switch statements

10.6.1. Guard clauses

10.6.2. Pattern variable scope for case labels

10.6.3. Evaluation order of pattern-based switch statements

10.7. Thoughts on usage

10.7.1. Spotting deconstruction opportunities

10.7.2. Spotting pattern matching opportunities

10.8. Summary

11. Efficiency and readability tweaks

11.1. Ref locals and ref return

11.1.1. Recap: what do we know about ref?

11.1.2. Ref locals

11.1.3. Ref return

11.1.4. Uses for ref local and ref return

11.2. Local methods

11.2.1. Variable access within local methods

11.2.2. Local method implementations

11.2.3. Usage guidelines

11.3. Out variables

11.4. Improvements to numeric literals

11.4.1. Binary integer literals

11.4.2. Underscore separators

11.5. Throw expressions

11.6. Summary

12. The Future

12.1. C# 7.1

12.1.1. The default literal

12.1.2. Async Main methods

12.1.3. Inferred element names for tuple literals

12.1.4. Pattern matching with generics

12.2. C# 7.2

12.2.1. More efficiency: in parameters, ref readonly and readonly structs

12.2.2. Blittable types

12.2.3. Stack based ref-like types

12.2.4. Non-trailing named arguments

12.3. C# release cadence and community involvement

12.4. C# 8

12.4.1. Nullable reference types

12.4.2. Features around type shapes and extensions

12.4.3. More async language integration

12.4.4. Record types

12.5. Conclusion


Appendix A: features by language and framework versions

About the Technology

If you're a .NET developer, you'll use C# whether you're building an advanced enterprise application or just pushing out a quick ASP.NET app. C# 5, 6 and 7 have added a host of new features to help you write better code with tuples, string interpolation, pattern matching, and more. To really succeed with these powerful new features, however, you need to learn them in depth. This book is your ticket!

What's inside

  • The latest changes and updates for C# 5, 6, and 7
  • How C# works and why
  • Using asynchronous functions
  • Simpler string formatting with interpolation
  • Composition with tuples
  • Decomposition and pattern matching

About the reader

If you're a C# developer who's comfortable working with the language and wants to really dig in deep, then this book is for you.

About the author

Jon Skeet is a senior software engineer at Google. He studied mathematics and computer science at Cambridge, is a recognized authority in Java and C#, and maintains the position of top contributor to Stack Overflow.

Manning Early Access Program (MEAP) Read chapters as they are written, get the finished eBook as soon as it’s ready, and receive the pBook long before it's in bookstores.
MEAP combo $49.99 pBook + eBook + liveBook
MEAP eBook $39.99 pdf + ePub + kindle + liveBook

FREE domestic shipping on three or more pBooks