Important "versioning" note
This review tackles the first printing, from November 2007. Since then, the book has undergone more printings, with errata being fixed in each printing. I believe most or possibly all of the errors listed below are now fixed – although I don’t yet know whether there are more lurking. I have a recent (late 2009) printing which I intend to review when I have the time – which means it’s likely to be in 2010Q2 at the earliest, and more likely later. I don’t know how much editing has been done in terms of best/bad practice. I have left the review as I originally wrote it, as it is a fair (to my mind) representation of that first printing. (This is something to bear in mind with all reviews, mind you – check when they are written, and ideally which version they’re written about.) I’m reluctant to go as far as recommending the latest printing without actually reading it, but I’m fairly confident it’s a lot better than the first printing.
You should also bear in mind that many C# books – including Head First C#, the Essential C# book referenced in the review and my own book – are currently being revised for C# 4. If the HFC# 4 book comes out before I’ve had time to review the latest printing of the previous edition, I will probably go straight for that instead.
This is a tough review to write. We already know I’m biased due to being in some way in competition with Andrew Stellman and Jennifer Greene (the authors), but I’m also not a huge fan of the Head First series in general. It doesn’t coincide with how I like to learn. I feel patronised by the pictures and crosswords rather than drawn into them, etc. However, I’m very aware that it’s really popular – lots of people swear by it, and I know that my own tastes are far from that of the majority. There’s also the fact that Head First C# really isn’t aimed at me at all – it’s aimed at people who don’t know C# to start with.
Funnily enough, that’s why I really, really wanted to like the book. It’s not actually competing with C# in Depth except for readers who have no idea what either book is like. I can’t imagine many people being in the situation where both books would be appropriate for them. I do want to find a good book for someone to learn C# from though, from scratch. My own book is completely unsuitable for that purpose. Essential C# by Mark Michaelis is my current favourite, I think – although I confess to not having read it all. It also doesn’t cover C# 3 – although I’m not sure whether I’d actually want to cover C# 3 for a reader who doesn’t know 1 or 2.
Anyway, I had hoped that Head First C# (HFC# from now on) would become a good recommendation – and part of this is because Andrew and Jennifer have certainly been very friendly on the blog and email. I don’t like being nasty, and I know how I’d feel reading a review like this of my book. Unfortunately, it falls a long way short of being worthy of recommendation, and I can’t really find a way of hiding that.
I "read" the whole book today. Now, it’s over 700 pages and I’ve been at work, so clearly I haven’t read every word of every page. I have mostly skimmed the code examples – vital for learning, I’ll gladly admit, but not hugely necessary for getting the gist of the book. I skimmed over the graphics section particularly quickly, being more interested in the language and core library elements than UI topics. With that in mind, let’s look at what I did and didn’t like:
This is going to be a broadly negative review, but it’s not like the book is without merit. Here’s what I liked:
- Many of the examples were very nicely chosen. I liked the party organizer (chapter 5) and the room topology (chapter 7) ones in particular.
- You really do get to create some nifty WinForms applications. I wouldn’t like to claim you really understand everything about them by the end of it, but I can see how they’re engaging.
- Annotations in listings are a good thing in general, and I do like the handwritten feel of them.
- Q&A is a good idea for a book like this. Predicting natural questions is an important part of
- After a slightly scary chapter 1 (building an addressbook using a database without actually knowing any C#) it does start from the real beginning, to some extent.
- The pictures in this book were actually not annoying, to my surprise. Some were even endearing. Even to me.
- Apparently other people really like this book. It’s got loads of 5-star reviews on Amazon, and apparently it’s been selling fantastically well. From the posts in the book’s forum, people are really getting engaged, which can only be a good thing.
I know the Head First series is all about its wacky style, etc – but I still find it can take a while to work out how you’re meant to navigate through the page. Often bits of the page do require a certain order, but that order isn’t always obvious.
My main problem with the formatting wasn’t nearly as general as that though, and I have to admit it’s a bit obsessive-compulsive. It’s the quotes in the code. They’re not straight. I’ve never seen an IDE which tries to work out "curly quotes" in code, and I hope I never do. When you’re used to seeing code in a real IDE, seeing curly quotes just looks wrong. It’s jarring and distracts from the business of learning.
Oh, and K&R bracing sucks. I know it makes the book shorter, but it makes it harder to read too. Just a personal opinion, of course :) (Having said which, the bracing style is inconsistent through the book anyway.)
I’m unashamedly a "bottom-up" person when it comes to learning. I like to get hold of several small building blocks, understand them to a significant degree, and then see what happens when I put them together. This book prefers the "show it all and explain some bits as we go along" approach, reasonably frequently mentioning how awful it is that most technical books try to start with console applications which don’t need lots of libraries before you even know what a library is.
I suspect this top-down way does indeed get people going much more quickly than my preferred style. (Remember, this is my preferred reading style, not just writing style. It’s no coincidence that I happen to write like I read though.) However, I believe there’s a great danger of people ending up as cargo-cult programmers. (I know I refer to that blog entry a lot. It happens to rock, and be relevant to much of why I write how/what I write.)
It’s true that top-down learning gets you doing flashy stuff more quickly than bottom-up. Whether that’s more fun or not depends on what appeals to you – I get a great sense of joy from thinking about a difficult topic and gradually understanding it, even if I have nothing to show for it beyond console apps which do little but sort numbers etc.
It feels like there ought to be a middle way, but I’ve no idea what it is yet. The "show something cool in chapter 1 and then go back over the details" approach favoured by the vast majority of technical books (including mine, to some extent) isn’t what I’m thinking of. Definitely something to think about there.
I hadn’t expected this book to be in great depth, despite the quote on the back cover: "If you want to learn C# in depth and have fun doing it, this is THE book for you." I’d expected a bit more than this, however.
When I said earlier on that HFC# wasn’t competing with C# in Depth, I mentioned audiences. There’s something to be said about material as well though. Let’s look at the bulk of my book – chapters 3-11, which deal with the new language features from C# 2 and 3. Here’s how much is covered in HFC#:
- Generics: generic collections get mentioned, but there’s no real explanation of how you’d write your own generic types. Generic methods aren’t mentioned. Type constraints, default(…), variance (or lack thereof), type inference – all absent.
- Nullable types: not mentioned as far as I can see, including an absence of the null-coalescing operator.
- Delegates: there’s a chapter on delegates which deals entirely with events and callbacks. No mention of their use in LINQ. No use of method group conversions, anonymous methods or support for variance. (In fact, there are some false claims around that, saying that the signature of an event handler has to match the delegate type exactly.)
- Iterator blocks: IEnumerable<T> is mentioned, but IEnumerator<T> is never shown as far as I remember, and iterator blocks certainly aren’t shown. It mentions that you could implement IEnumerable<T> yourself, but doesn’t give any hints as to how, or what would be required.
- Partial types: covered, albeit only mentioning classes. No sign of partial methods.
- Static classes: covered to some extent, but without explaining that they prevent you from attempting to use the class inappropriately, or other details like the absence of constructors (not even a default one).
- Separate getter/setter access: covered
- Namespace aliases: not covered
- Pragma directives: not covered
- Fixed size buffers: not covered
- InternalsVisibleTo: not covered (not really a language feature though)
- Automatically implemented properties: covered, but without mentioning (AFAICR) that a hidden backing field is generated for you
- Implicit typing: one call-out and a somewhat inaccurate Q&A
- Object/collection initializers: covered, but without noting that you can remove the brackets from parameterless constructor calls
- Implicitly typed arrays: not covered
- Anonymous types: mentioned in a single annotation, but inaccurately. Used in a few query expressions.
- Lambda expressions: not mentioned (in a book which "covers" C# 3.0. Wow.)
- Expression trees: not mentioned
- Changes to type inference/overloading: hard to explain a change to something which isn’t covered to start with
- Extension methods: covered
- Query expressions: covered to a very limited extent. No explanation of query translation. No explanation of query continuations (although grouping is always shown with continuations). No sign of multiple "from" statements or "join into".
See why I don’t think our books are really competing? Now, a lot of this really is absolutely fine. The details of generics don’t really belong in an introductory text – although some more information would have been welcome. Pragmas and fixed size buffers would have been completely out of place. Would it be too much to ask for some discussion of anonymous methods and lambda expressions though, particularly as lambda expressions really do make LINQ possible?
Maybe I’m being too harsh, looking at just C# 2 and 3 features (which is pretty much all my book does). Here are some things which would have counted as being missing had the book been published in 2002:
- Casting ("as" doesn’t count as a cast in my view – it’s an operator)
- Explicit interface implementation
- The conditional operator (x ? y : z)
- Hiding members with "new" instead of "override"
- The sealed modifier on methods (not just classes)
- ref/out/params modifiers for parameters
- continue, goto, and break (break is mentioned for switch/case, but only there)
Maybe going into the memory model would have been a bit much (without which volatile would be pretty pointless) but not to even mention threading (and lock) feels a little worrying – especially as Application.DoEvents is abused instead. Explicit interface implementation is relatively obscure – but readonly fields? typeof(…)?
Fine, it’s an introductory text – but that means it’s a bad idea to talk about "mastering" LINQ and claiming that "by the time you’re through you’ll be a proficient C# programmer, designing and coding large-scale applications". Those quotes probably aren’t the authors’ fault, to be honest – and marketing has a way of exaggerating things, as we all know. But no-one should be in any doubt that this is far from a complete guide to C#.
Errors (please see update at the end of the post, and note at top)
This is by far my biggest gripe with the book. It’s probably coloured the whole review – things which I could have forgiven otherwise have been judged more harshly than they would have been if the entire book had been accurate. Accuracy is what I demand from a book above all else, partly because it’s not obvious to the reader when it’s absent. No-one could reasonably read the book without realising that they’re getting a top-down approach, or what the formatting is like, or that there are going to be crosswords etc. However, a reader has little to benchmark accuracy against unless the book is internally consistent.
Now, I’m unfortunate enough to have the first edition (November 2007). The book is currently undergoing its third printing, i.e. it’s had two rounds of corrections. These are listed in the errata and I’ve tried to take them into account – although there’s no way that a carefully reviewed and edited book should need that many corrections in such a short space of time. I will concede that a Head First book is likely to be much harder to get right than a "normal" book though, due to all the funky formatting.
Typos don’t worry me too much. It’s core technical errors which really bother me. It’s almost as if someone had taken my list of classic "myths" and decided to taunt me. I half expected "objects are passed by reference" to be in there – but as ref/out parameters aren’t covered at all, it’s not. Here are some of the worst/most amusing culprits though:
- Claiming that string is a value type (in several places). Oh, and object, once.
- Claiming that the range of sbyte is -127 to 128 (instead of -128 to 127). Same kind of mistake with short.
- Constantly using field and property as if they were interchangable. They’re not, they’re really, really not. Just because they’re used in a similar way doesn’t mean you can be this loose with the terminology.
- Claiming that C# "marks objects for garbage collection". In fact, for the first 6/7ths of the book there’s a strong implication that garbage collection is done in a deterministic way; that objects are immediately collected when the last reference is lost. We do eventually find out that it’s non-deterministic (although that explanation is also flawed) but by then it may well be too later for the reader. More on this in a minute.
- Claiming that methods and statements always have to live in classes. Funny how structs can have behaviour too…
- Claiming that "objects are variables" (in a heading, no less). I know from experience that trying to accurately describe the interplay between objects, variables, and their values is tricky – but even so…
- Writing a hex dump utility using StreamReader – broken by definition, given that hex dump tools are used to show the binary contents of files, and StreamReader is meant to read text, decoding it as it goes.
- Claiming that structs always live on the stack.
- Expanding WPF as "Windows Presentation Framework"
These are all errors which have made it through not just technical review, but two rounds of post-publication editing. It’s possible that some of the errors on my list of about 60 (ignoring typos for the most part) are in the errata and I missed them (I did try to check them all) – but really, I shouldn’t have been able to find that many in the first place, even if they have been corrected. I’m worried if a C# book author believes that a char has 256 possible values, for instance. I know that the author is wrong, and to check the errata (this one has indeed been fixed) but I suspect many first edition readers will never look at the errata.
Now, there are errors and there are bad practices…
Bad practice through example
I know we don’t end up writing production code as book examples. Indeed, Eric mentioned this in chapter 1, where I’d left a few things out which I would normally consider as best practice: making a type sealed, making fields readonly etc. I left extra modifiers out for simplicity. I can understand that. I can also understand using public fields until properties have been explained but:
- There’s no reason to use poorly named variables/parameters, including Pascal-cased local variables
- Writing loops like for (int i=1; i <= 10; i++) instead of the more idiomatic for (int i=0; i < 10; i++). C# is 0-based in many ways, but often the authors seemed to really wish it were 1-based.
- Continuing to use public fields even after explaining how they’re not really a good idea. (Well, sort of explaining that. There’s a frequent implication that they’re not so bad if other classes really need to be able to access your data. It’s a very long way from my preferred policy of no non-private variables whatsoever.)
- String concatenation in loops with nary a mention of StringBuilder
- Bizarre combination of "is" and "as", using "as" to perform the conversion instead of casting. If you’re going to use "as", do it up front and compare with null to start with…
- Advising leaving out braces for single line for/if statements. The code which is left in these examples is unreadable, IMO. You have to really concentrate to see what’s in and what’s out.
- Advising to stick with the absolutely abhorrent "convention" (aka laziness, and leaving things as VS creates them) of naming event handlers with things like button1_Click. No. Name methods with what they do, then the event hookup code will make it obvious – and it makes it clearer where you can reuse a single method for multiple events.
- Repeatedly declaring enums within classes as if you couldn’t write them as top-level types. Oh, and messing up the naming conventions there, too.
- Showing a mutable struct without explaining that this should always be avoided is a bad idea.
I could go on. I’ve got pages of notes about this kind of thing (and this is only after owning the book for less than a day, don’t forget) but I think you get the message. Note: some of these things are definitely a matter of opinion, such as bracing style. Some other things are so widely regarded as a bad idea that I can’t see much defence for them.
Examples matter. I don’t expect to see production code, and I understand that sometimes for teaching purposes best practices will take second place – but where it wouldn’t hurt to use best practice, please do!
Likewise telling the truth from the start matters. It’s very hard to correct bad habits and incorrect impressions. If you state that "When we set lucky (a variable) to null, it’s no longer pointing at its object, so it gets garbage collected" then people will not only be potentially confused about whether it’s the variable or the object which gets garbage collected, but they’ll get the impression that it’s garbage collected immediately. Waiting 476 pages to correct that impression is a bad idea.
Public fields are another example. I’ve mentioned that I can see their usefulness before we’ve encountered properties – but even so, surely it would have been worth explaining immediately that we’re going to hide them as soon as possible.
You may have gathered by now that I’m not a fan of the book ;) I suspect a lot of this review has come off as a rant, which is a pity. That tends to happen when I get on my technical high horse, which I guess I’ve done here. The fact is, I’ve spent a lot of today feeling deeply saddened. I wouldn’t be surprised to find that this is the best-selling C# book of 2008 – which means we’ll get a lot more people on the newsgroup with some very odd ideas about how C# works. That’s the trouble – I’ve seen what happens when people are fed the "structs live on the stack" myth. I’ve seen how easily people can believe that strings are value types, and that it doesn’t really matter if you use a StreamReader for binary data and then cast chars to bytes. It causes trouble.
I’m reasonably sure the world could do with a good introductory book on C#. HFC# has convinced me that such a book could be fun and have pretty pictures. But HFC# isn’t quite it. (And no, I don’t plan on writing it either.)
I gave an advance copy of this review to Andrew, who has replied remarkably politely and pleasantly (and quickly). He’s a true gent, giving a really thorough reply when I suspect most authors (perhaps including myself) would either have given short shrift to a review like this, or possibly ignored it competely and hoped it would go away.
He believes I was looking too much for a complete reference rather than an introductory text. I would say I wasn’t looking for completeness, but a better judge of what should be in a C# book (I’d have preferred ref/out to be covered, but would be happy to lose the section on GDI+ double buffering, for instance). I specifically don’t want an actual reference book if I’m going to recommend it to people to learn from – but I may be biased towards a reference style as that’s what I personally tend to learn from.
It was really the errors that affected this review more than anything though, and while a very few of them could be debated (whether an implicit reference conversion to a base class counts as upcasting, for instance – I’d only include explicit upcasting) many others are undeniable and really shouldn’t have made it through the review process. It’s possible that I’ll come back to HFC# in a year’s time and be more impressed by it, but I suspect the aversion to errors will overcome any mellowing towards the style :(
Update (22nd March 2008)
Andrew continues to amaze me in terms of taking this review in his stride. He’s now looking through the errors I found, and many should be fixed in the next printing. Bear in mind that without a lot of the errors, I would have had a more positive view from the start.
In short, I’m still not quite convinced I’d recommend the book, but my opinion has certainly mellowed (anticipating the error fixing, of course).
10 thoughts on “Book review: Head First C#”
While this review excels in all aspects, it leaves me with only feeling: that this is the comedy routine where a Bergman lover reviews a romantic Hollywood comedy. The comedy in this routine, of course, is the irony of the expectations of the reviewer being very far from what should probably have been expected.
Because just from looking at the book’s cover, I could guess that my feelings about the book would probably match yours. And from reading your first paragraphs, about the book’s funky style, funky reading order, and so on – I envision Comic Sans as I read your review – it becomes sort of obvious what kind of book this is. Judgmental and prejudicial, sure, but the world of computers if filled to the brim with crappy make-a-fast-buck books, and this looks like it’s just one of them. I bet you could find 2000 books like this one just by browsing Amazon.
Now, the only thing that surprises is that o’Reilly has published this.
You know what I’m saying?
Wow, great review. I was looking for some books to teach some juniors java and C#. For C# this book *was* on my list. You picked the right time to review it ;)
Anonymous: don’t get me wrong. I wouldn’t categorise it as a “crappy make-a-fast-buck” book. I’d call it a serious attempt in a style and approach which I disagree with, which is unfortunately plagued with errors.
As I’ve just said in an email to Andrew, I do understand that writing for beginners is really hard. Much harder than writing for my target audience, who are likely to already be more receptive to technical terminology and definitions.
I don’t doubt Andrew and Jenny’s sincerity and effort on this book at all – I certainly don’t think they went into this to make a quick buck.
As it happens, it looks like it’s selling well – but technical writing is a really crummy way of making money unless you happen to be very lucky. I suspect I could have made more money by stacking shelves in a supermarket for 15 hours a week than I’ll make from C# in Depth – but I didn’t do it for the money, and I doubt that Andrew and Jenny did either.
None of this makes the book have fewer errors in it, of course, or diminish my concerns about the effects of those errors burrowing their way into thousands of newbie brains. It just means I think it was an unfortunate accident rather than laziness and disregard for the reader.
This is one of the best overall reviews of a book that I’ve read in a while.
I love that you took the time to explain what you liked, and what you didn’t. You also made clear your own biases in style and approach, and put for the review in that context.
The error list I am quite surprised about. I’ve dealt with more “String is a value type! It says to right here in this book!” arguments than I care to remember.
I will admit scratching my head on the “structs live on the stack” being wrong. I’m probably missing a specific use case, and I’ll have to check your book for it once it comes in.
Also amusing, I remember before I know Unicode at all, making similar mistakes to the streamreader example you mentioned. All that subtle interplay was completely lost on me until a few years back…
Great review, and I’ll look forward to seeing more from you!
(Not signed on ‘cos it’s my wife’s laptop.)
The point is that the data for value type variables lives wherever that variable lives. So if you have a class with an int field, that int field lives on the heap despite int being a struct. I know it seems obvious, but it really does cause confusion.
I’ve got a (fairly old) write-up of this at
It’s also myth #2 (IIRC) in the section about value types and reference types in C# in Depth :)
Although I agree with many of Jon’s criticisms, I disagree with the final verdict of “not recommended”.
In balancing up the pros and cons, it’s easy to overlook the overriding question: does the book’s teaching stategy *work*? The answer is a resounding yes – for most people. The reviews on Amazon back this up (as does my own assessment of the book). The fact that there are errors and omissions doesn’t invalidate this.
I’m certainly with Jon on his preference for bottom-up teaching in general – my own book is bottom-up and I think this stategy works very well for intermediate- and advanced-level books. For beginners, though, the danger of teaching bottom-up is that the pace will be too slow and the reader will get bored. And bored readers don’t learn as well. Therefore, I can totally understand taking more of a top-down approach with beginners.
This book goes to extreme lengths to make the learning process easy and fun – sometimes at the cost of technical imprecision. I know that the authors worked hard to address this at the technical review stage (I was one of the technical reviewers) but in the end, it can be hard to balance the two. For instance, to say that methods live in classes is technically wrong (as Jon points out) – they can also live in structs. But pointing this out to a beginner who will not learn about structs for many more chapters is sure to cause confusion.
This is not to say that the authors haven’t made mistakes that I trust will be corrected in reprints and subsequent editions. Not all of the feedback from tech review made it into print (nor did the tech reviewers pick up everything). But I believe the book’s limitations are nowhere near enough to justify not recommending it. Most beginners will get a much better outcome from reading HFC# than from reading a book that’s more rigorously correct – but unenjoyable.
For people that want to clean up and extend their knowledge after reading HFC#, this is exactly what the advanced books are for. In fact, all you need do is read the first four chapters of C# 3.0 in a Nutshell to fill in any gaps left from HFC#. I’m guessing the same would go for Jon’s book, too.
Put another way, I consider the head first approach ideal as an introduction to the intermediate and advanced books. I will certainly continue to recommend it to beginners – until a better book comes out (hopefully, edition 2 of HFC# :)
Author, C# 3.0 in a Nutshell
Just to correct one thing about Joe’s review: my own book wouldn’t really be a suitable next step from HFC# unless the reader also filled in some of the gaps from C# 1. Joe’s book (C# 3.0 in a Nutshell) apparently covers C# in its entirety (judging by its table of contents; my copy is on order), so will cover the bits of C# 1 that have been missed out by HFC#. (Unsafe code, out/ref/params, continue/goto, break in places out than switch/case etc.) My book *only* covers C# 2 and 3, admittedly with a revision chapter on a few aspects of C# 1.
There aren’t very many of these gaps (most of what isn’t in HFC# is in C# 2 and 3 rather than C# 1) but I wouldn’t want anyone to be under the impression that it would be a smooth transition.
I suspect that HFC# + a year’s experience (where you’re bound to meet things life ref/out) would lead someone to a suitable place to read C# in Depth though.
I had ordered this book through Amazon thinking that I had found a great C# book that already does with a textbook what I would do with it- write useful notes all over everything in it. I was impressed with what I saw at a local bookstore and loved the examples.
I was browsing through the Head First website forum the next day and noticed an odd post by the book’s author entitled “Use Cory White’s errata parser…” Being curious I went to the errata section for this book to take a look.
I clicked on the link so that I could skim through the corrections. What absolutely horrified me was when I noticed that the scroll bar on the right-hand side of my browser window seemed to almost disappear completely.
Page upon page of significant errors. Too many to even begin counting.
My Amazon order for the book was cancelled less than four minutes later.
I really wanted to buy this book since I think that the overall format is a remarkable approach. However, I really have to question ANY author and/or publisher that would print a book with this many errors. Atrocious is not a strong enough word to use here. It becomes almost total loss of credibility.
Get it together!
Jon, thanks for the spot-on review. I believe that much in the way of formatting and style can be forgiven if a book has a high level of technical accuracy (which HFC# does not). This book had enough technical stinkers to cause me to stop reading at chapter 5. My favorites from the Nov. 2007 printing:
(p. 26) A database requires a diagram in order for Visual Studio to access the data. (This one was not corrected until the 4th printing.)
(p. 198) this.SomeProperty = x; emits a call to the public set accessor, while
SomeProperty = x; (without “this”) emits a call to the private set accessor.
There may be more after chapter 5, but I wouldn’t know :(
Thanks for the review of this book, it is interesting to see it from you as the author of more advanced book on the language.
HFC# has a lot of flaws. I saw a lot of them still while reading it, and had a lot of blank spaces to cover(still have some).
But there was something about it’s style, which you can get into only if you read it throughly and do the exercises…Before i got the book i had a pair of years experience as a copy-paste web developer and was thinking that i chose my profession wrongly… I was trying to read other books on C# before HFC# (like the big red Wrox one), but i was getting more and more bored.
But after i followed HFC#, i felt like i reawakened and recalled why did i choose the profession, because it gives you fun in creatively solving the given problems. I started investing into it much more, got the job as C# developer, and am working on improving my skills ever since.
Of course, i’m sure that there are a lot of developers that have enough talent and drive not to need any motivation for learning. But then, there are some like me who could use a little push in the right direction, and for them i would definitely recommend this book. It gives not only knowledge good enough to start developing, but also the most important thing – drive.