Joe Albahari, co-author of the excellent C# 3.0 in a Nutshell (previously reviewed here) kindly agreed to review C# in Depth. Not only has he provided the review below, but he also supplied several pages of notes made while he was reading it. Many of those notes have been incorporated into the C# in Depth notes page – it’s always good to include thoughtful feedback. (And I always welcome more, hint hint.)
Without further ado, here’s Joe’s review.
C# in Depth: Review
After having been invited to review this book by two people at Manning—as well as Jon himself—I figure it’s about time I came forward! Bear in mind that I’m not a typical reader: I’m an author, and this makes me more critical than most. This is especially true given that I wrote C# 3.0 in a Nutshell with a coauthor (imagine two people constantly searching for ways to improve each others’ work!). So I will do my best to compensate and strive to be fair. Please post a comment if you feel I’ve missed the mark!
While most other C# books cover the language, the CLR and at least some aspects of the Framework, C# in Depth concentrates largely on just the language. You won’t find discussions on memory management, assemblies, streams and I/O, security, threading, or any of the big APIs like WPF or ASP.NET. This is good in that doesn’t duplicate the books already out there, as well as giving more space for the language.
You might expect that a book focusing on the C# language itself would cover all of it. But interestingly, the book covers only about a quarter of the C# language, namely the features new to C# 2 and C# 3. This sets its target audience: programmers who already know C# 1, but have not yet switched to C# 2 and 3. This creates a tight focus, allowing it to devote serious space to topics such as generics, nullable types, iterators and lambda expressions. It’s no exaggeration to say that this book covers less than one tenth of the ground of most other C# books, but gives that ground ten times as much attention.
Organization and Style
The book is divided into three parts:
- Preliminaries (delegates and the type system)
- Features new to C# 2.0
- Features new to C# 3.0
I like this organization: it presents topics in an order roughly similar to how I teach when giving tutorials on LINQ—starting with the foundations of delegates and generics, before moving on to iterators and higher-order functions, and then finally LINQ. Sometimes the routes are a little circuitous and involve some huffing and puffing, but the journey is worthwhile and helps to solidify concepts.
C# in Depth is a tutorial that gradually builds one concept upon another and is designed primarily for sequential reading. The examples don’t drag on over multiple sections, however, so you can jump in at any point (assuming you understand the preceding topics). The examples are all fairly short, too, which is very much in my taste. In fact, I would say Jon and I think very much alike: when he expresses an opinion, I nearly always agree wholeheartedly.
A big trap in writing tutorials, is assuming knowledge of topics that you teach later. This book rarely falls victim to this. The writer is also consistent in his use of terminology—and sticks with the C# Language Specification which I think sets a good example to all authors. Jon is not sloppy with concepts and is careful in his wording to avoid misinterpretation. One thing that comes through is that Jon really understands the material deeply himself.
If I were to classify this book as beginner/intermediate/advanced, I’d say intermediate-to-advanced. It’s quite a bit more advanced than, say, Jesse’s tutorial “Programming C#”.
The layout of the book is pleasing—I particularly like the annotations alongside the code listings.
In the first section, “Preparing for the Journey,” the book does cover a few C# 1 topics, namely delegates and C#’s type system. Jon’s handling of these topics is excellent: his discussion of static, explicit and safe typing is clear and helpful, as is the section on value types versus reference types. I particularly liked the section “Dispelling Myths”—this is likely to be of use even to experienced developers. This chapter, in fact, leaves the reader pining for more advanced C# 1 material.
The C# 2 features are very well covered. The section on generics includes such topics as their handling by the JIT compiler, the subtleties of type inference, a thorough discussion on constraints, covariance/contravariance limitations, and comparisons with Java’s generics and C++’s templates. Nullable types are covered similarly well, with suggested patterns of use, as are anonymous methods and iterators.
The C# 3 features are also handled well. I like how Jon introduces expression trees—first building them programmatically, and then showing how the compiler provides a shortcut via lambda expressions. The book covers query expressions and the basics of LINQ, and includes a brief explanation of each of the standard query operators in an appendix. There’s also a chapter called “LINQ Beyond Collections” which briefly introduces the LINQ to SQL, LINQ to DataSet and LINQ to XML APIs.
Throughout the book, Jon goes to some lengths to explain not just “what”, but “why”. This book isn’t for people who want to get in and out quick so they can get their job done and out of the way—it’s for people who enjoy working elegantly with their tools, through a rich understanding of the language’s background, subtleties and nuances.
Of course, digesting all this is a bit of work (Chapter 3′s summary opens with the word “Phew!”). Despite this, I think Jon does a good job at explaining difficult things well. I don’t think I’ve seen any IL listings in the book, which is a good sign in general. I’m always wary when an author, in explaining a C# concept, says, “to understand XYZ, we must examine the IL”. I take issue with this: rarely, if ever, does one need to look at IL to understand C#, and doing so creates unnecessary complication by choosing the wrong level of abstraction. That isn’t to saying looking at IL isn’t useful for a deeper understanding of the CLR—but only after first teaching C# concepts independently of IL.
It was in Jon’s design critieria not build a tome—instead to write a small(ish) book that complements rather than replaces books such as C# 3.0 in a Nutshell. Most things missing from C# in Depth are consistent with its focus (such as the CLR, threading, .NET Framework, etc.) The fact that C# in Depth excludes the features of C# that were introduced prior to version 2 is a good thing if you’re looking for a “delta” book, although, of course, it makes it less useful as a language reference.
The book’s treatment of LINQ centres largely on LINQ to Objects. If you’re planning on learning C# 3.0 so that you can query databases through LINQ, the book’s focus is not ideal, if read in isolation. I personally prefer the approach of covering “remote” query architecture earlier and in more detail (in conjunction with the canonical API, LINQ to SQL) – so that when it comes time to teach query operators such as SelectMany, Group and Join, they can be demonstrated in the context of both local and database queries. I also strive, when writing on LINQ, to cover enough querying ground that readers can “reproduce” their SQL queries in LINQ—even though it means having to get sidetracked with API practicalities. Of course, getting sidetracked with API practicalities is undesirable for a language-centric book such as C# in Depth, and so the LINQ to Objects focus is understandable. In any case, reading Chapters 8-10 of C# 3.0 in a Nutshell would certainly fill in the gaps. Another complementary book would be Manning’s LINQ in Action (this book is well-reviewed on Amazon, though I’ve not yet read it).
This book is well written, accurate and insightful, and complements nearly every other book out there. I would recommend it to anyone wanting a thorough “inside” tutorial on the features new to C# 2 and 3.