<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Jon Skeet: Coding Blog : Book reviews, Books, C#</title><link>http://msmvps.com/blogs/jon_skeet/archive/tags/Book+reviews/Books/C_2300_/default.aspx</link><description>Tags: Book reviews, Books, C#</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Book Review: Effective C# (2nd edition) by Bill Wagner</title><link>http://msmvps.com/blogs/jon_skeet/archive/2010/09/25/book-review-effective-c-2nd-edition-by-bill-wagner.aspx</link><pubDate>Sat, 25 Sep 2010 07:09:24 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1778719</guid><dc:creator>skeet</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1778719</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1778719</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2010/09/25/book-review-effective-c-2nd-edition-by-bill-wagner.aspx#comments</comments><description>&lt;h3&gt;Resources:&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.amazon.com/Effective-Covers-4-0-Specific-Development/dp/0321658701"&gt;Amazon&lt;/a&gt;, &lt;a href="http://search.barnesandnoble.com/Effective-C/Bill-Wagner/e/9780321658708"&gt;Barnes and Noble&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://srtsolutions.com/blogs/billwagner/"&gt;Bill Wagner&amp;#39;s blog&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Disclaimer&lt;/h3&gt;  &lt;p&gt;Just in case you&amp;#39;re unaware, I&amp;#39;m the author of another C# book, &lt;a href="http://manning.com/skeet2"&gt;C# in Depth&lt;/a&gt;. Although Effective C# is somewhat different to my book, they certainly share a target audience. To that extent, Bill and I are competitors. I try hard to stay unbiased in reviews, but it&amp;#39;s probably impossible. Bear this in mind while reading. I should also note that I didn&amp;#39;t buy my copy of Effective C#; it was kindly sent to me by Pearson, for the purpose of reviewing.&lt;/p&gt;  &lt;h3&gt;Content and target audience&lt;/h3&gt;  &lt;p&gt;Effective C# is a style guide for C# developers - but not at the low level of &amp;quot;put your braces here, use PascalCase for method names;&amp;quot; instead, it&amp;#39;s at the design level. As far as I can tell, the aim isn&amp;#39;t to be &lt;em&gt;complete&lt;/em&gt;, just the most important aspects of style. (Hey, otherwise there wouldn&amp;#39;t be any need for &lt;a href="http://www.amazon.com/dp/0321485890"&gt;More Effective C#&lt;/a&gt;, right?) There are 50 mostly-self-contained items, totalling about 300 pages to digest - which is a nice size of book, in my opinion. It&amp;#39;s not daunting, and the items can definitely be bitten off one at a time.&lt;/p&gt;  &lt;p&gt;Looking down the table of contents, the items are divided into six categories: &amp;quot;C# language idioms&amp;quot;, &amp;quot;.NET resource management&amp;quot;, &amp;quot;Expressing Designs in C#&amp;quot;, &amp;quot;Working with the Framework&amp;quot;, &amp;quot;Dynamic Programming in C#&amp;quot;, and &amp;quot;Miscellaneous&amp;quot;. Broadly speaking these contain the sorts of thing you&amp;#39;d expect - although it&amp;#39;s worth pointing out that a significant chunk of &amp;quot;Working with the Framework&amp;quot; is given over to Parallel Extensions, which may not be obvious from the title. (It&amp;#39;s a really good source of information on PFX, by the way.)&lt;/p&gt;  &lt;p&gt;This is &lt;em&gt;not&lt;/em&gt; a tutorial on C#. If you don&amp;#39;t know C# reasonably well already (including generics, lambda expressions and so on) you should read another book first, and then come back to Effective C# in order to get the most out of it.&lt;/p&gt;  &lt;p&gt;&lt;font color="#0000ff"&gt;Comment from Bill: generics and lambda expressions (and LINQ) are covered in some detail in More Effective C#. It&amp;#39;s a bit strange that as of the 2nd edition, Effective C# covers a newer version of the language than More Effective C#. I tried hard to make sure neither book expects a reader to have read the other, but the organization of both books as a whole does show the hazards of hitting a moving target.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;That&amp;#39;s not to say that there&amp;#39;s no explanation of C# - for example, Bill goes into a few details about the &amp;quot;dynamic&amp;quot; type from C# 4, as well as overloading and how optional parameters work. But these are meant to just cover some poorly-understood (or very new) aspects of the language, rather than teaching you from the beginning. The balance here feels just right to me - I believe most professional C# developers will learn details of C# they weren&amp;#39;t aware of before, but won&amp;#39;t be confused by the basics that Bill left out.&lt;/p&gt;  &lt;h3&gt;Accuracy, opinion and explanation&lt;/h3&gt;  &lt;p&gt;My copy of Effective C# has plenty of ink annotations now. They broadly fall into five categories:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&amp;quot;Ooh, I&amp;#39;d never thought of that&amp;quot; - aspects of C# which were genuinely new to me &lt;/li&gt;    &lt;li&gt;&amp;quot;Hell, yes!&amp;quot; - things I agree with 100%, and which will help developers a lot &lt;/li&gt;    &lt;li&gt;&amp;quot;Um, I disagree&amp;quot; - points where Bill and I would go probably different routes, presumably due to different experiences and having worked in different contexts. (It&amp;#39;s possible that when put in the &lt;em&gt;same&lt;/em&gt; context, we&amp;#39;d do the same thing, of course.) &lt;/li&gt;    &lt;li&gt;&amp;quot;No, that&amp;#39;s technically incorrect&amp;quot; - a few areas which are outright wrong, or were correct for previous versions of the framework/CLR, but aren&amp;#39;t correct now &lt;/li&gt;    &lt;li&gt;&amp;quot;That&amp;#39;s not what that term means&amp;quot; (or &amp;quot;that&amp;#39;s not the right term for the concept you&amp;#39;re trying to get across&amp;quot;) - it should come as no surprise to regular readers that I&amp;#39;m a bit of a pedant when it comes to terminology &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The majority of my annotations are of the third category - disagreements. That&amp;#39;s not because I disagree with most of the book; it&amp;#39;s just that the second category is reserved for &lt;em&gt;vehement&lt;/em&gt; agreement. I haven&amp;#39;t bothered to note every sentence that I&amp;#39;m just fine with.&lt;/p&gt;  &lt;p&gt;The good news is that in areas where we disagree, Bill does an admirable job of stating his case. I disagree with some of his arguments - or I can give counter-examples, or merely place different value on some of the pros and cons - but the important thing is that the reasoning is there. If it doesn&amp;#39;t apply to your context, evaluate the advice accordingly.&lt;/p&gt;  &lt;p&gt;It&amp;#39;s entirely reasonable for there to be quite a bit of disagreement, as much of the book is opinion. It&amp;#39;s obviously founded in a great deal of experience (and I should note that Bill has spent a lot more time as a professional C# developer than I have), but it&amp;#39;s still opinion. I rather wish that the book was a wiki, so that these items could be debated, amended etc, as per my &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/08/20/the-quot-dream-book-quot-for-c-and-net.aspx"&gt;dream book&lt;/a&gt; - I think that would make it even more valuable.&lt;/p&gt;  &lt;p&gt;There are relatively few absolutely incorrect statements, and even on the terminology front it&amp;#39;s usually two things which have bugged me repeatedly. Bill uses &amp;quot;implicit properties&amp;quot; for &amp;quot;automatically implemented properties&amp;quot;; I&amp;#39;ve usually heard developers use the abbreviated form &amp;quot;automatic properties&amp;quot; but &amp;quot;implicit&amp;quot; is new to me. Likewise the book talks about &amp;quot;overriding ==&amp;quot; instead of &amp;quot;overloading ==&amp;quot; reasonably frequently. It&amp;#39;s a shame I was too busy with my own book to participate in the technical review for Effective C#, as I suspect that on at least some of these points, Bill would have been happy to amend the text accordingly. I shall, of course, transcribe my comments and send them to him.&lt;/p&gt;  &lt;p&gt;&lt;font color="#0000ff"&gt;Comment from Bill: I&amp;#39;ll make those corrections for the subsequent printings.&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;What&amp;#39;s missing?&lt;/h3&gt;  &lt;p&gt;There are some areas which I wish Bill had touched on or emphasized more. Topics such as numbers, text and chronological values could have been given some space as they frequently confuse folks (and are full of pitfalls; see &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/11/02/omg-ponies-aka-humanity-epic-fail.aspx"&gt;Humanity: Epic Fail&lt;/a&gt; for more of my thoughts on this). I would personally have placed more importance on the mantra of &amp;quot;value types should be immutable&amp;quot; - it&amp;#39;s certainly talked about, but in the context of &amp;quot;preferring&amp;quot; atomic, immutable value types - and preferring value types over reference types in rather more situations than I&amp;#39;d personally use. In terms of importance in avoiding shooting yourself in the foot, making sure all structs are immutable comes near the top of the list in my view.&lt;/p&gt;  &lt;p&gt;&amp;quot;More Effective C#&amp;quot; doesn&amp;#39;t cover those areas as far as I can tell from the table of contents, but it does go into details about generics and various aspects of C# 3 and LINQ, which are clearly part of any modern C# developer&amp;#39;s toolkit. I certainly intend to get hold of the book to see what else I have to learn from Bill.&lt;/p&gt;  &lt;p&gt;I think it might have been nice to have a few sections at an even &lt;em&gt;higher&lt;/em&gt; level than the specific items in Effective C#. Topics such as:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Don&amp;#39;t trust me: I don&amp;#39;t know your context. Even the smartest folks can only give advice in fairly general terms in books. Don&amp;#39;t apply this advice blindly; weigh up the arguments presented and work out how they apply to your actual code. &lt;/li&gt;    &lt;li&gt;The importance of testing. It&amp;#39;s possible that this was mentioned, but I don&amp;#39;t recall it. Perhaps it&amp;#39;s a little on the opinionated side (see previous point...) but for significant code bases, testing should be deeply ingrained in whatever process you&amp;#39;re using. Note that although it&amp;#39;s worth trying to keep high standards in test code, it often has a very different look and feel to production code, and different &amp;quot;best practices&amp;quot; may apply. &lt;/li&gt;    &lt;li&gt;Encouraging &amp;quot;working with the language&amp;quot; - if you find yourself fighting the language, you may discover you can keep winning battles but losing the war. Typically changing your design to represent more idiomatic C# will make life more pleasant for everyone. &lt;/li&gt;    &lt;li&gt;Performance: how you might decide when and how much to care. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Very few of these would be C#-specific, of course - which may be why Bill left them out. You could easily fill a whole book like that, and it would probably be horrible to read - full of platitudes rather than concrete advice. I personally think there&amp;#39;s room for &lt;em&gt;some&lt;/em&gt; discussion of this kind though. &lt;/p&gt;  &lt;p&gt;&lt;font color="#0000ff"&gt;Comment from Bill: The ultimate goal was to have the book be that &amp;#39;nice size&amp;#39; you mention above. I agree that all of those concepts are important. I felt that many of these features were not C# specific (or even .NET specific) that I felt better covered elsewhere.&amp;#160; However, that &amp;#39;working with the language&amp;#39; was one area where I feel that I do cover.&amp;#160; There are only a small number of negative titles (e.g &amp;quot;avoid&amp;quot; something or &amp;quot;do not&amp;quot; do something). In those cases, I tried to recommend alternatives where you would find yourself &amp;quot;working with the language&amp;quot;.&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;I like Effective C# a lot. I like the fact that I&amp;#39;ve disagreed with a number of the points raised, and in disagreeing I&amp;#39;ve found myself thinking about &lt;em&gt;why&lt;/em&gt; I disagree and in what situations each point of view may be appropriate. I worry a &lt;em&gt;little&lt;/em&gt; about inexperienced readers who may be tempted to treat this (or any other book) as an ultimate truth to be quoted out of context and used to beat other developers into inappropriate solutions... but hopefully most readers won&amp;#39;t be like that.&lt;/p&gt;  &lt;p&gt;&lt;font color="#0000ff"&gt;Comment from Bill: I also hope that most readers avoid that. Thank you for pointing out that I&amp;#39;ve tried very hard to explain when my advice applies, and when it doesn&amp;#39;t.&amp;#160; That is critical.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;It&amp;#39;s definitely encouraged me to try to write a &lt;em&gt;somewhat&lt;/em&gt; similar book at some point... possibly not with the same organization, and probably dealing with some very different topics - but it&amp;#39;s good to see that it can work. Whether I can pull it off as well as Bill remains to be seen, of course.&lt;/p&gt;  &lt;p&gt;I&amp;#39;ll look forward to reading More Effective C# - although my pile of books to review is groaning somewhat, and I should probably go through another of those first :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1778719" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Book+reviews/default.aspx">Book reviews</category></item><item><title>Book Review: Programming C# 3.0 by Jesse Liberty and Donald Xie</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/09/28/book-review-programming-c-3-0-by-jesse-liberty-and-donald-xie.aspx</link><pubDate>Sun, 28 Sep 2008 00:59:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1649100</guid><dc:creator>skeet</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1649100</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1649100</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/09/28/book-review-programming-c-3-0-by-jesse-liberty-and-donald-xie.aspx#comments</comments><description>&lt;h3&gt;Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://oreilly.com/catalog/9780596527433/"&gt;The O&amp;#39;Reilly page&lt;/a&gt; (errata etc)  &lt;/li&gt;
&lt;li&gt;&lt;a href="http://71.248.178.27/LA/MyBooks.html"&gt;Jesse Liberty&amp;#39;s page for his various books&lt;/a&gt;  &lt;/li&gt;
&lt;li&gt;Buy it from &lt;a href="http://www.amazon.com/dp/0596527438"&gt;Amazon&lt;/a&gt; or &lt;a href="http://search.barnesandnoble.com/Programming-C-30/Jesse-Liberty/e/9780596527433/?itm=1"&gt;Barnes and Noble&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Disclaimer&lt;/h3&gt;
&lt;p&gt;One reader commented that a previous book review was too full of &amp;quot;this is only my personal opinion&amp;quot; and other such disclaimers. I think it&amp;#39;s still important to declare the situation, but I can see how it can get annoying if done throughout the review. So instead, I&amp;#39;ve lumped everything together here. Please bear these points in mind while reading the whole review:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Obviously this book competes with C# in Depth, although probably not very much.  &lt;/li&gt;
&lt;li&gt;I was somewhat prejudiced against the book by seeing that the sole 5-star review for it on Amazon was by Jesse Liberty himself. Yes, he wanted to explain why he wrote the book and why he&amp;#39;s proud of it, but giving yourself a review isn&amp;#39;t the right way to go about it.  &lt;/li&gt;
&lt;li&gt;I&amp;#39;ve seen a previous edition of the book (for C# 2.0) and been unimpressed at the coverage of some of the new features.  &lt;/li&gt;
&lt;li&gt;I&amp;#39;m a nut for technical accuracy, particularly when it comes to terminology. More on this later, but if you don&amp;#39;t mind reading (and then presumably using) incorrect terminology, you&amp;#39;re likely to have a lot better time with this book than I did.  &lt;/li&gt;
&lt;li&gt;I suspect I have higher expectations for established, prolific authors such as Jesse Liberty than for newcomers to the world of writing.  &lt;/li&gt;
&lt;li&gt;I&amp;#39;m really not the target market for this book.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Okay, with all that out of the way, let&amp;#39;s get cracking.&lt;/p&gt;
&lt;h3&gt;Contents and target audience&lt;/h3&gt;
&lt;p&gt;According to the preface, Programming C# 3.0 (PC# from now on) is for people learning C# for the first time, or brushing up on it. There&amp;#39;s an expectation that you probably already know another language - it wouldn&amp;#39;t be impossible to learn C# from the book without any prior development experience, but the preface explicitly acknowledges that it would be reasonably tough. That&amp;#39;s a fair comment - probably fair for &lt;em&gt;any&lt;/em&gt; book, in fact. I have yet to read anything which made me think it would be a wonderful way to teach someone to program from absolute scratch. Likewise the preface recommends C# 3.0 in a Nutshell for a more detailed look at the language, for more expert readers. Again, that&amp;#39;s reasonable - it&amp;#39;s clearly not aiming to go into the same level of depth as Accelerated C# 2008 or C# in Depth.&lt;/p&gt;
&lt;p&gt;The book is split into 4 parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The C# language: pretty much what you&amp;#39;d expect, except that not all of the language coverage is in this part (most of the new features of C# 3.0 are in the second part) and some non-language coverage is included (regular expressions and collections) - about 270 pages  &lt;/li&gt;
&lt;li&gt;C# and Data: LINQ, XML (the DOM API and a bit of LINQ to XML), database access (ADO.NET and LINQ to SQL) - about 100 pages  &lt;/li&gt;
&lt;li&gt;Programming with C#: introductions to ASP.NET, WPF and Windows Forms - about 85 pages  &lt;/li&gt;
&lt;li&gt;The CLR and the .NET Framework: attributes, reflection, threading, I/O and interop - about 110 pages&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you can tell, the bulk of it is in the language part, which is fine by me and reflects the title accurately. I&amp;#39;ll focus on that part of the book in this review, and the first chapter of part 2, which deals with the LINQ parts of C# 3.0. To be honest, I don&amp;#39;t think the rest of the book actually adds much value, simply because they skim over the surface of their topics &lt;em&gt;so&lt;/em&gt; lightly. Part 3 would make a reasonable series of videos - and indeed that&amp;#39;s how it&amp;#39;s written, basically in the style of &amp;quot;Open Visual Studio, start a new WinForms project, now drag a control over here&amp;quot; etc. I&amp;#39;ve never been fond of that style for a book, although it works well in screencasts.&lt;/p&gt;
&lt;p&gt;The non-LINQ database and XML chapters in part 2 seemed relatively pointless too - I got the feeling that they&amp;#39;d been present in older editions and so had just stayed in by default. With the extra space available from cutting these, a much better job could have been done on LINQ to SQL and LINQ to XML. The latter gets particularly short-changed in PC#, with a mere 4 pages devoted to it! (C# in Depth is much less of a &amp;quot;libraries&amp;quot; book but I still found over 6 pages to devote to it. Not a lot, I&amp;#39;ll grant you.)&lt;/p&gt;
&lt;p&gt;Part 4 has potential, and is more useful than the previous parts - reflection, threading, IO and interop are all important topics (although I&amp;#39;d probably drop interop in favour of internationalization or something similar) - but they&amp;#39;re just not handled terribly well. The threading chapter talks about using lock &lt;em&gt;or&lt;/em&gt; Monitor, but never states that &lt;code&gt;lock&lt;/code&gt; is just shorthand for &lt;code&gt;try&lt;/code&gt;/&lt;code&gt;finally&lt;/code&gt; blocks which use &lt;code&gt;Monitor&lt;/code&gt;; no mention is made of the memory model or volatility; aborting threads is demonstrated but not warned about; the examples always lock on &lt;code&gt;this&lt;/code&gt; without explaining that it&amp;#39;s generally thought to be a bad idea. The IO chapter uses &lt;code&gt;TextReader&lt;/code&gt; (usually via &lt;code&gt;StreamReader&lt;/code&gt;) but never mentions the &lt;em&gt;crucial&lt;/em&gt; topic of character encodings (it uses &lt;code&gt;Encoding.ASCII&lt;/code&gt; but without really explaining it) - and most damning of all, as far as I can tell there&amp;#39;s not a &lt;em&gt;single&lt;/em&gt; &lt;code&gt;using&lt;/code&gt; statement in the entire chapter. There are calls to &lt;code&gt;Close()&lt;/code&gt; at the end of each example, and there&amp;#39;s a very &lt;em&gt;brief&lt;/em&gt; mention saying that you should always explicitly close streams - but without saying that you should use a &lt;code&gt;using&lt;/code&gt; statement or &lt;code&gt;try&lt;/code&gt;/&lt;code&gt;finally&lt;/code&gt; for this purpose.&lt;/p&gt;
&lt;p&gt;Okay, enough on those non-language topics - let&amp;#39;s look at the bulk of the book, which is about the language.&lt;/p&gt;
&lt;h3&gt;Language coverage&lt;/h3&gt;
&lt;p&gt;PC# starts from scratch, so it&amp;#39;s got the whole language to cover in about 300 pages. It would be unreasonable to expect it to provide as much attention to detail as C# in Depth, which (for the most part) only looks at the new features of C# 2.0 and 3.0. (On the other hand, if the remaining 260 pages had been given to the language as well, a lot more ground could have been covered.) It&amp;#39;s also worth bearing in mind that the book is &lt;em&gt;not&lt;/em&gt; aimed at confident/competent C# developers - it&amp;#39;s written for newcomers, and delving into tricky issues like generic variance would be plain mean. However, I&amp;#39;m still not impressed with what&amp;#39;s been left out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There&amp;#39;s &lt;em&gt;no mention&lt;/em&gt; of nullable types as far as I can tell - indeed, the list of operators omit the null-coalescing operator (??).  &lt;/li&gt;
&lt;li&gt;Generics are really only talked about in the context of collections - despite the fact that to understand any LINQ documentation, you really will need to understand generic delegates. Generic constraints are only likewise only mentioned in the context of collections, and only what I call a &amp;quot;derivation type constraint&amp;quot; (e.g. &lt;code&gt;T : IComparable&amp;lt;T&amp;gt;&lt;/code&gt;) (as far as I can tell the spec doesn&amp;#39;t give this a name). There&amp;#39;s no coverage of &lt;code&gt;default(T)&lt;/code&gt; - although the &amp;quot;default value of a type&amp;quot; is mentioned elsewhere, with an incorrect explanation.  &lt;/li&gt;
&lt;li&gt;Collection initializers aren&amp;#39;t explained as far as I can tell, although I seem to recall seeing one in an example. They&amp;#39;re not mentioned in the index.  &lt;/li&gt;
&lt;li&gt;Iterator blocks (and the &lt;code&gt;yield&lt;/code&gt; contextual keyword) are likewise absent from the index, although there&amp;#39;s definitely one example of &lt;code&gt;yield return&lt;/code&gt; when &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is covered. The coverage given is minimal, with no mention of the completely different way that this executes compared with normal methods.  &lt;/li&gt;
&lt;li&gt;Query expression coverage is limited: although &lt;code&gt;from&lt;/code&gt;, &lt;code&gt;where&lt;/code&gt;, &lt;code&gt;select&lt;/code&gt;, &lt;code&gt;orderby&lt;/code&gt;, &lt;code&gt;join&lt;/code&gt; and &lt;code&gt;group&lt;/code&gt; are covered, there&amp;#39;s no mention of &lt;code&gt;let&lt;/code&gt;, the difference between &lt;code&gt;join&lt;/code&gt; and &lt;code&gt;join ... into&lt;/code&gt;, explicitly typed range variables, or query continuations. The translation process isn&amp;#39;t really explained clearly, and the text pretty much states that it will always use extension methods.  &lt;/li&gt;
&lt;li&gt;Expression trees aren&amp;#39;t referenced to my knowledge; there&amp;#39;s one piece of text which attempts to mention them but just calls them &amp;quot;expressions&amp;quot; - which are of course entirely different. We&amp;#39;ll come onto terminology in a minute.  &lt;/li&gt;
&lt;li&gt;Only the simplest (and admittedly most common by a &lt;i&gt;huge&lt;/i&gt; margin) form of &lt;code&gt;using&lt;/code&gt; directives is shown - no extern aliases, no namespace aliases, not even &lt;code&gt;using Foo = System.Console;&lt;/code&gt;  &lt;/li&gt;
&lt;li&gt;Partial methods aren&amp;#39;t mentioned.  &lt;/li&gt;
&lt;li&gt;Implicitly typed arrays aren&amp;#39;t covered.  &lt;/li&gt;
&lt;li&gt;Static classes may be mentioned in passing (not sure) but not really explained.  &lt;/li&gt;
&lt;li&gt;Object initializers are shown in one form only, ditto anonymous object initializer expressions  &lt;/li&gt;
&lt;li&gt;Only field-like events are shown. The authors spend several pages on an example of bad code which just has a public delegate variable, and then try to blame delegates for the problem (which is really having a public variable). The solution is (of course) to use an event, but there&amp;#39;s little to no explanation of the nature of events as pairs of methods, a bit like properties but with subscribe/unsubscribe behaviour instead of data fetch/mutate.  &lt;/li&gt;
&lt;li&gt;Anonymous methods and lambda expressions are covered, but with &lt;em&gt;very&lt;/em&gt; little text about the closure aspect of them. This is about it: &amp;quot;[...] and the anonymous method has access to the variables in the scope in which they are defined:&amp;quot; (followed by an example which doesn&amp;#39;t demonstrate the use of such variables at all).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I suspect there&amp;#39;s more, but you get the general gist. I&amp;#39;m not saying that all of these should have been covered and in great detail, but really - no mention of nullable types &lt;em&gt;at all&lt;/em&gt;? Is it really more appropriate &lt;em&gt;in a supposed language book&lt;/em&gt; to spend several pages building an asynchronous file server than to actually list all the operators accurately?&lt;/p&gt;
&lt;p&gt;Okay, I&amp;#39;m clearly beginning to rant by now. The limited coverage is annoying, but it&amp;#39;s not &lt;em&gt;that&lt;/em&gt; bad. Yes, I think the poor/missing coverage of generics and nullable types is a real problem, but it&amp;#39;s not enough to get me really cross. It&amp;#39;s the massive abuse of terminology which winds me up.&lt;/p&gt;
&lt;h3&gt;Accuracy&lt;/h3&gt;
&lt;p&gt;I&amp;#39;ll say this for PC# - if you ignore the terminology abuse, it&amp;#39;s &lt;em&gt;mostly&lt;/em&gt; accurate. There are definitely &amp;quot;saying something incorrect&amp;quot; issues (e.g. an implication that ref/out can only be used with value type parameters; the statement that reference types in an array aren&amp;#39;t initialized to their default value (they are - the default value is null); the claim that extension methods can only access public members of target types (they have the same access as normal - so if the extension method is in the same assembly as the target type, for instance, it could access internal members)) but the biggest problem is that of terminology - along with sloppy code, including its formatting.&lt;/p&gt;
&lt;p&gt;The authors confuse objects, values, variables, expressions, parameters, arguments and all kinds of other things. These have well-defined meanings, and they&amp;#39;re there for a reason. They do have footnotes explaining that they&amp;#39;re &lt;em&gt;deliberately&lt;/em&gt; using the wrong terminology - but that doesn&amp;#39;t make it any better. Here are the three footnotes, and my responses to them:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The terms &lt;em&gt;argument&lt;/em&gt; and &lt;em&gt;parameter&lt;/em&gt; are often used interchangably, though some programmers insist on differentiating between the parameter declaration and the arguments passed in when the method is invoked.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Just because others abuse terms doesn&amp;#39;t mean it&amp;#39;s right for a book to do so. It&amp;#39;s not that &lt;em&gt;programmers&lt;/em&gt; insist on differentiating between the two - the &lt;em&gt;specification&lt;/em&gt; does. Now, to lighten things up a bit I&amp;#39;ll acknowledge that this one isn&amp;#39;t always easy to deal with. There are plenty of times where I&amp;#39;ve tried really hard to use the right term and just not ended up with a satisfactory bit of wording. However, at least I&amp;#39;ve tried - and where it&amp;#39;s easy, I&amp;#39;ve done the right thing. I wish the authors had the same attitude. (They do the same with the conditional operator, calling it &amp;quot;the ternary operator&amp;quot;. It&amp;#39;s &lt;em&gt;a&lt;/em&gt; ternary operator. Having three operands is part of its nature - it&amp;#39;s not a description of its behaviour. Again, lots of other people get this wrong. Perhaps if all &lt;em&gt;books&lt;/em&gt; got it right, more developers would too.) Next up:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Throughout this book, I use the term &lt;em&gt;object&lt;/em&gt; to refer to reference and value types. There is some debate in the fact that Microsoft has implemented the value types as though they inherited from the root class Object (and thus, you may call all of Object&amp;#39;s methods on any value type, including the built-in types such as int.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To me, this pretty much reads as &amp;quot;I&amp;#39;m being sloppy, but I&amp;#39;ve got half an excuse.&amp;quot; It&amp;#39;s true that the C# specification isn&amp;#39;t clear on this point - although the CLI spec is crystal clear. Personally, it just feels &lt;em&gt;wrong&lt;/em&gt; to talk about the value 5 as an object. It&amp;#39;s an object when it&amp;#39;s boxed, of course (and if you call any &lt;code&gt;Object&lt;/code&gt; methods on a value type which haven&amp;#39;t been overridden by that type, it gets boxed at that point) but otherwise I really don&amp;#39;t think of it as an object. An &lt;em&gt;instance&lt;/em&gt; of the type, yes - but not an object. So yes, I&amp;#39;ll acknowledge that there&amp;#39;s a little wiggle room here - but I believe it&amp;#39;s going to confuse readers more than it helps them.&lt;/p&gt;
&lt;p&gt;It&amp;#39;s the &amp;quot;confusing readers more than it helps them&amp;quot; part which is important. I&amp;#39;m not above a little bit of shortcutting myself - in C# in Depth, I refer to automatically implemented properties as &amp;quot;automatic properties&amp;quot; (after explicitly saying what I&amp;#39;m doing) and I refer to the versions of C# as 1, 2 and 3 instead of 1.0, 1.2, 2.0 and 3.0. In both these cases, I believe it adds to the readability of the book without giving any room for confusion. That&amp;#39;s very different from what&amp;#39;s going on in PC#, in my view. I&amp;#39;ve saved the most galling example of this for last:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As noted earlier, &lt;code&gt;btnUpdate&lt;/code&gt; and &lt;code&gt;btnDelete&lt;/code&gt; are actually variables that refer to the unnamed instances on the heap. For simplicity, we&amp;#39;ll refer to these as the names of the objects, keeping in mind that this is just short-hand for &amp;quot;the name of the variables that refer to the unnamed instances on the heap.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This one&amp;#39;s the killer. It sounds &lt;em&gt;relatively&lt;/em&gt; innocuous until you see the results. Things like this (from P63):&lt;/p&gt;
&lt;div class="code"&gt;ListBox myListBox;&amp;nbsp; &lt;span class="InlineComment"&gt;// instantiate a ListBox object&lt;/span&gt; &lt;/div&gt;
&lt;p&gt;No, that code doesn&amp;#39;t instantiate anything. It &lt;em&gt;declares&lt;/em&gt; a &lt;em&gt;variable &lt;/em&gt;- and that&amp;#39;s all. The comment isn&amp;#39;t non-sensical - the idea of some code which &lt;em&gt;does&lt;/em&gt; instantiate a &lt;code&gt;ListBox&lt;/code&gt; object clearly makes sense - but it&amp;#39;s not what&amp;#39;s happening in &lt;em&gt;this&lt;/em&gt; code (in C# - it &lt;em&gt;would&lt;/em&gt; in C++, which makes it even more confusing). That&amp;#39;s just one example - the same awful sloppiness (which implies something &lt;em&gt;completely incorrect&lt;/em&gt;) permeates the whole book. Time and time again we&amp;#39;re told about instances being created when they&amp;#39;re not. From P261:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Clock class must then create an instance of this delegate, which it does on the following line:&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt; SecondChangeHandler SecondChanged; &lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why do I care about this so much? Because I see the results of it on the newsgroups, constantly. How can I blame developers for failing to communicate properly about the problems they&amp;#39;re having if their source of learning is so sloppy and inaccurate? How can they get an accurate mental model of the language if they&amp;#39;re being told that objects are being instantiated when they&amp;#39;re not? Communication and a clear mental model are &lt;em&gt;very&lt;/em&gt; important to me. They&amp;#39;re why I get riled up when people perpetuate myths about where structs &amp;quot;live&amp;quot; or how parameters are passed. PC# had me clenching my fists on a regular basis.&lt;/p&gt;
&lt;p&gt;These are examples where the authors apparently &lt;em&gt;knew&lt;/em&gt; they were abusing the terminology. There are other examples where I believe it&amp;#39;s a genuine mistake - calling anonymous methods &amp;quot;anonymous delegates&amp;quot; or &amp;quot;statements that evaluate to a value are called expressions&amp;quot; (statements are &lt;em&gt;made up of&lt;/em&gt; expressions, and expressions don&amp;#39;t have to return a value). I can certainly sympathise with this. Quite where they got the idea that HTML was derived from &amp;quot;Structured Query Markup Language&amp;quot; I don&amp;#39;t know - the word &amp;quot;Query&amp;quot;should have been a red flag - but these things happen.&lt;/p&gt;
&lt;p&gt;In other places the authors are just being sloppy without either declaring that they&amp;#39;re going to be, or just appearing to make typos. In particular, they&amp;#39;re bad at distinguishing between language, framework and runtime. For instance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;C# combines the power and complexity of regular expression syntax [...]&amp;quot; - no, C# itself neither knows nor cares about regular expressions. They&amp;#39;re in the framework.  &lt;/li&gt;
&lt;li&gt;(When talking about iterator blocks) &amp;quot;All the bookkeeping for keeping track of which element is next, resetting the iterator, and so forth is provided for you by the Framework.&amp;quot; - No, this time it &lt;em&gt;is&lt;/em&gt; the C# compiler which is doing all the work. (It doesn&amp;#39;t support reset though.)  &lt;/li&gt;
&lt;li&gt;&amp;quot;Strings can also be created using &lt;em&gt;verbatim&lt;/em&gt; string literals, which start the at (@) symbol. This tells the String constructor that the string should be used verbatim [...]&amp;quot; - No, the String constructor doesn&amp;#39;t know about verbatim string literals. They&amp;#39;re handled by the C# compiler.  &lt;/li&gt;
&lt;li&gt;&amp;quot;The .NET CLR provides isolated storage to allow the application developer to store data on a &lt;em&gt;per-user&lt;/em&gt; basis.&amp;quot; I very much doubt that the CLR code has any idea about this. I expect it to be in the framework libraries.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Again, if books don&amp;#39;t get this right, how do we expect developers to distinguish between the three? Admittedly sometimes it can be tricky to decide where responsibility lies - but there are plenty of clearcut cases where PC# is just wrong. I doubt that the authors really don&amp;#39;t know the difference - they just don&amp;#39;t seem to think it&amp;#39;s important to get it right.&lt;/p&gt;
&lt;h3&gt;Code&lt;/h3&gt;
&lt;p&gt;I&amp;#39;m mostly going to point out the shortcomings of the code, but on the plus side I believe almost all of it will basically work. There&amp;#39;s one point at which the authors have both a method and a variable with the same name (which is already in the unconfirmed errata) and a few other niggles, but they&amp;#39;re relatively rare. However:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The code frequently ignores naming conventions. Method and class names sometimes start with lower case, and there&amp;#39;s frequent use of horrible names beginning with &amp;quot;my&amp;quot; or &amp;quot;the&amp;quot;.  &lt;/li&gt;
&lt;li&gt;The authors often present several pages of code together, and then take them apart section by section. This isn&amp;#39;t the only book to do this by a long chalk, but I wonder - does anyone really benefit from having the whole thing in a big chunk? Isn&amp;#39;t it better to present small, self-contained examples?  &lt;/li&gt;
&lt;li&gt;As mentioned before, the uses of &lt;code&gt;using&lt;/code&gt; statements are few and far between.  &lt;/li&gt;
&lt;li&gt;The whitespace is all over the place. The indentation level changes all the time, and sometimes there are outdents in the middle of blocks. Occasionally newlines have actually been missed out, and in other cases (particularly at the start of class bodies) there are two blank lines for no reason at all. (The latter is very odd in a book, where vertical whitespace is seen as extremely valuable.) Sometimes there&amp;#39;s excessive (to my mind) spacing Just as an example (which is explicitly labelled as non-compiling code, so I&amp;#39;m not faulting it at all for that):
&lt;div class="code"&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Console;&lt;br /&gt;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Hello&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt; Main()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WriteLine(&lt;span class="String"&gt;&amp;quot;Hello World&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;} &lt;/div&gt;
I promise you that&amp;#39;s &lt;i&gt;exactly&lt;/i&gt; how it appears in the book. Now this may have started out as a fault of the type-setter, but the authors should have picked it up before publication, IMO. I could understand there being a &lt;i&gt;few&lt;/i&gt; issues like this (proof-reading code really is hard) but not nearly as many as there are.  &lt;/li&gt;
&lt;li&gt;There are examples of mutable structs (or rather, there&amp;#39;s at least one example), and &lt;em&gt;no warning at all&lt;/em&gt; that mutable value types are a really, really bad idea.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Again, I don&amp;#39;t want to give the impression I&amp;#39;m an absolute perfectionist when it comes to code in book. For the sake of keeping things simple, sometimes authors don&amp;#39;t seal types where they should, or make them immutable etc. I&amp;#39;m not really looking for production-ready code, and indeed I made this very point in &lt;a href="http://csharpindepth.com/ViewNote.aspx?NoteID=2"&gt;one of the notes&lt;/a&gt; for C# in Depth. However, I draw the line at &lt;code&gt;using&lt;/code&gt; statements, which are important and easy to get right without distracting the reader. Likewise giving variables good names - &lt;code&gt;counter&lt;/code&gt; rather than &lt;code&gt;ctr&lt;/code&gt;, and avoiding those &lt;code&gt;the&lt;/code&gt; and &lt;code&gt;my&lt;/code&gt; prefixes - makes a competent reader more comfortable and can transfer good habits to the novice via osmosis.&lt;/p&gt;
&lt;h3&gt;Writing style and content ordering&lt;/h3&gt;
&lt;p&gt;Time for some good news - when you look beyond the terminology, this is a really easy book to read. I don&amp;#39;t mean that everything in it is simplistic, but the style rarely gets in the way. It&amp;#39;s not dry, and some of the real-world analogies are very good. This may well be Jesse Liberty&amp;#39;s experience as a long-standing author making itself apparent.&lt;/p&gt;
&lt;p&gt;In common with many O&amp;#39;Reilly books, there are two icons which usually signify something worth paying special attention to: a set of paw prints indicating a hint or tip, and a mantrap indicating a commonly encountered issue to be aware of. Given the rest of the review, I suspect you&amp;#39;d be surprised if I agreed with all of the points made in these extra notes - and indeed there are some issues - but most of them are good.&lt;/p&gt;
&lt;p&gt;Likewise there are also notes for the sake of existing Java and C++ developers, which make sense and are useful.&lt;/p&gt;
&lt;p&gt;I don&amp;#39;t agree with some of the choices made in terms of how and when to present some concepts. I found the way of explaining query expressions confusing, as it interleaved &amp;quot;here&amp;#39;s a new part of query expressions&amp;quot; with &amp;quot;here&amp;#39;s a new feature (e.g. anonymous types, extension methods).&amp;quot; It will come as no surprise to anyone who&amp;#39;s read C# in Depth that I prefer the approach of presenting all the building blocks first, and then showing how query expressions use all those features. There&amp;#39;s a note explaining why the authors have done what they&amp;#39;ve done, but I don&amp;#39;t buy it. One important thing with the &amp;quot;building blocks first&amp;quot; approach is to present a preliminary example or two, to give an idea of where we&amp;#39;re headed. I&amp;#39;ve forgotten to do that in the past (in a talk) and regretted it - but I don&amp;#39;t regret the overall way of tackling the topic.&lt;/p&gt;
&lt;p&gt;On a &lt;em&gt;slightly&lt;/em&gt; different note, I would have presented some of the earlier topics in a different order too. For instance, I regard structs and interfaces as more commonly used and fundamental topics than operator overloading. (While C# developers tend not to create their own structs often, they &lt;em&gt;use&lt;/em&gt; them all the time. When was the last time you wrote a program without an int in it?) This is a minor nit - and one which readers may remember I also mentioned for Accelerated C# 2008.&lt;/p&gt;
&lt;p&gt;There&amp;#39;s one final point I&amp;#39;d like to make, but which doesn&amp;#39;t really fit anywhere else - it&amp;#39;s about Jesse Liberty&amp;#39;s dedication. Most people dedicate books to friends, colleages etc. Here&amp;#39;s Jesse&amp;#39;s:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This book is dedicated to those who come out, loud, and in your face and in the most inappropriate places. We will look back at this time and shake our heads in wonder. In 49 states, same-sex couples are denied the right to marry, though incarcerated felons are not. In 36 states, you can legally be denied housing just for being q-u-e-e-r. In more than half the states, there is no law protecting LGBT children from harassment in school, and the suicide rate among q-u-e-e-r teens is 400 percent higher than among straight kids. And, we are still kicking gay heroes out of the military despite the fact that the Israelis and our own NSA, CIA, and FBI are all successfully integrated. So yes, this dedication is to those of us who are out, full-time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(I&amp;#39;ve had to spell out q-u-e-e-r as otherwise the blog software replaces it with asterisks. Grr.) I&amp;#39;m straight, but I support Jesse&amp;#39;s sentiment 100%. I can&amp;#39;t remember when I first started taking proper notice of the homophobia in the world, but it was probably at university. This dedication does nothing to help or hinder the reader with C#, but to my mind it still makes it a better book.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;In short, I&amp;#39;m afraid I wouldn&amp;#39;t recommend Programming C# 3.0 to potential readers. There are much better books out there: ones which won&amp;#39;t make it harder for the reader to talk about their code with others, in particular. It&amp;#39;s not all bad by any means, but the mixture of sloppy use of terminology and poor printed code is enough of a problem to make me give a general thumbs down.&lt;/p&gt;
&lt;p&gt;Next up will be CLR via C#, by Jeffrey Richter.&lt;/p&gt;
&lt;h3&gt;Response from Jesse Liberty&lt;/h3&gt;
&lt;p&gt;As normal, I mailed the author (in this case just Jesse Liberty - I confess I didn&amp;#39;t look for Donald Xie&amp;#39;s email address) and very promptly received a nice response. He asked me to add the following as his reaction:&lt;/p&gt;
&lt;div class="reaction"&gt;I believe the book is very good for most real-world programmers and the publisher and I are dedicated to making the next revision a far better book, by correcting some of the problems you point out, and by beefing up the coverage of the newer features of the language. &lt;/div&gt;
&lt;p&gt;Also as normal, I&amp;#39;ll be emailing Jesse with a list of the errors I found, so hopefully they can be corrected for the next edition.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1649100" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Book+reviews/default.aspx">Book reviews</category></item><item><title>Book review: Accelerated C# 2008 by Trey Nash</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/08/01/book-review-accelerated-c-2008-by-trey-nash.aspx</link><pubDate>Fri, 01 Aug 2008 22:05:41 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1643045</guid><dc:creator>skeet</dc:creator><slash:comments>21</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1643045</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1643045</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/08/01/book-review-accelerated-c-2008-by-trey-nash.aspx#comments</comments><description>&lt;p&gt;Time for another book review, and this time it&amp;#39;s a due to a recommendation from a reader who has this one, C# in Depth &lt;em&gt;and&lt;/em&gt; Head First C#.&lt;/p&gt; &lt;h3&gt;Resources&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://www.amazon.com/dp/1590598733"&gt;Amazon&lt;/a&gt;  &lt;li&gt;&lt;a href="http://search.barnesandnoble.com/Accelerated-C-2008/Trey-Nash/e/9781590598733"&gt;Barnes and Noble&lt;/a&gt;  &lt;li&gt;&lt;a href="http://www.apress.com/book/view/1590598733"&gt;Publisher&amp;#39;s page (Apress)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;Introduction and disclaimer&lt;/h3&gt; &lt;p&gt;My normal book review disclaimer applies, but probably more so than ever before. Yes, Accelerated C# 2008 is a competitor to C# in Depth. They&amp;#39;re different in many ways, but many people would no doubt be in the target audience for both books. If you meet that criterion, please be aware that as the author of C# in Depth I can&amp;#39;t possibly be 100% objective when reviewing another C# book. That said, I&amp;#39;ll try to justify my opinions everywhere I can.&lt;/p&gt; &lt;h3&gt;Target audience and content overview&lt;/h3&gt; &lt;p&gt;Accelerated C# 2008 is designed to appeal to existing developers with experience in an OO language. As one of the Amazon reviews notes, you may struggle somewhat if you don&amp;#39;t have &lt;em&gt;any&lt;/em&gt; .NET experience beforehand - while it should be possible to read it knowing only Java or C++, there are various times where a certain base level of knowledge is assumed and you&amp;#39;ll want to refer to MSDN for some background material. If you come at the book with no OO experience at all, I expect you&amp;#39;ll have a hard time. Chapter 4 does cover the basics of OO in .NET (classes, structs, methods, properties etc) this isn&amp;#39;t really a beginner&amp;#39;s book.&lt;/p&gt; &lt;p&gt;In terms of actual content covered, Accelerated C# 2008 falls somewhere between C# in Depth (almost purely language) and C# 3.0 in a Nutshell (language and then core libraries). It doesn&amp;#39;t attempt to cover &lt;em&gt;all&lt;/em&gt; the core technologies (IO, reflection, security, interop etc are absent) but it goes into detail beyond the C# language when it comes to strings, exceptions, collections, threading and more. As well as purely factual information, there&amp;#39;s a lot of guidance as well, including a whole chapter entitled &amp;quot;In Search of C# Canonical Forms.&amp;quot;&lt;/p&gt; &lt;h3&gt;General impressions&lt;/h3&gt; &lt;p&gt;I&amp;#39;d like to make it clear to start with that I like the book. I have a number of criticisms, none of which I&amp;#39;m making up for the sake of being critical - but that in no way means it&amp;#39;s a bad book at all. It&amp;#39;s very unlikely that you know everything in here (I certainly didn&amp;#39;t) and the majority of the guidance is sound. The code examples are almost always self-contained (a big plus in my view) and Trey&amp;#39;s style is very readable. Where there are inaccuracies, they&amp;#39;re &lt;em&gt;usually&lt;/em&gt; pretty harmless, and the large amount of accurate and insightful material makes up for them.&lt;/p&gt; &lt;p&gt;Just as I often compare Java to C# in my book, so Trey often compares C++ to C# in his. While my balance of C# to C++ knowledge is such that these comments aren&amp;#39;t particularly useful to me, I can see them being good for a newcomer to C# from a C++ background. I thought there might have been a few too many comparisons (I understood the point about STL and lambdas/LINQ the first time round...) but that&amp;#39;s just a minor niggle.&lt;/p&gt; &lt;p&gt;Where C# in Depth is primarily a &amp;quot;read from start to finish&amp;quot; book and C# 3.0 in a Nutshell is primarily a reference book (both can be used the other way, of course) Accelerated C# 2008 falls between the two. It actually achieves the best of both worlds to a large extent, which is an impressive feat. The ordering could be improved (more on this later on) but the general feeling is very good.&lt;/p&gt; &lt;p&gt;One quick word about the size of the book in terms of content: if you&amp;#39;re one of those people who judges the amount of useful content in a book on its page count, it&amp;#39;s worth noting that the font in this book is pretty small. I would guess that it packs about 25% more text per page than C# in Depth does, taking its &amp;quot;effective&amp;quot; page count from around 500 to 625. Also, the content is certainly meaty - you&amp;#39;re unlikely to find yourself skimming over loads of simple stuff trying to get to the good bits. Speaking of &amp;quot;getting to the good bits&amp;quot; let&amp;#39;s tackle my first significant gripe.&lt;/p&gt; &lt;h3&gt;Material organisation&lt;/h3&gt; &lt;p&gt;If you look at the tables of contents for Accelerated C# 2008 and Accelerated C# 2005, you&amp;#39;ll notice that the exact same chapter titles in the 2005 edition carry over in the same order in the 2008 edition. There are three extra chapters in the new edition, covering extension methods, lambda expressions and LINQ. That&amp;#39;s not to say that the content of the &amp;quot;duplicate&amp;quot; chapters is the same as before - C# 3.0 features are introduced in the appropriate place within existing chapters. In terms of ordering the chapters, I think it would be have been much more appropriate to keep the last chapter of the old edition - &amp;quot;In Search of C# Canonical Forms&amp;quot; - as the last chapter of the new edition. Apart from anything else, that would allow it to include hints and tips involving the new C# 3 features which are currently covered later. It really feels like a &amp;quot;wrapping up&amp;quot; chapter, and deserves to be last.&lt;/p&gt; &lt;p&gt;That&amp;#39;s not the only time that the ordering felt strange, however. Advanced topics (at least ones which feel advanced to me) are mixed in with fairly basic ones. For instance, in the chapter on exceptions, there&amp;#39;s a section about &amp;quot;exception neutrality&amp;quot; which includes details about constrained execution regions and critical finalizers. All interesting stuff - even though I wish there were more of a prominent warning saying, &amp;quot;This is costly to both performance and readability: only go to these lengths when you really, really need to.&amp;quot; However, this comes &lt;em&gt;before&lt;/em&gt; a section about using &lt;code&gt;try&lt;/code&gt;/&lt;code&gt;finally&lt;/code&gt; blocks and the &lt;code&gt;using&lt;/code&gt; statement to make sure that resources are cleaned up however a block is exited. I can&amp;#39;t imagine anyone who knows enough C# to take in the exception neutrality material also &lt;em&gt;not&lt;/em&gt; knowing about try/finally or the using statement (or how to create your own custom exception class, which comes between these two topics).&lt;/p&gt; &lt;p&gt;Likewise the chapter which deals with collections, including generic ones, comes before the chapter on generics. If I were a reader who didn&amp;#39;t know generics already, I think I&amp;#39;d get very confused reading about &lt;code&gt;ICollection&amp;lt;T&amp;gt;&lt;/code&gt; without knowing what the &lt;code&gt;T&lt;/code&gt; meant. Now don&amp;#39;t get me wrong: ordering material so that you don&amp;#39;t get &amp;quot;circular references&amp;quot; is often hard if not impossible. I just think it could have been done better here.&lt;/p&gt; &lt;h3&gt;Aiming too deep?&lt;/h3&gt; &lt;p&gt;It&amp;#39;s not like me to criticise a book for being too deep, but I&amp;#39;m going to make an exception here. Every so often, I came away from a topic thinking that it would have been better covered a little bit more lightly. Sometimes this was because a running example became laborious and moved a long way from anything you were actually likely to want to do in real life. The sections on &amp;quot;borrowing from functional programming&amp;quot; and memoization/currying/anonymous recursion felt guilty of this. It&amp;#39;s not that they&amp;#39;re not interesting topics, but the examples picked didn&amp;#39;t quite work for me.&lt;/p&gt; &lt;p&gt;The other problem with going deep is that you really, really need to get things right - because your readers are less likely to spot the mistakes. I&amp;#39;ll give three examples here:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Trey works hard on a number of occasions to avoid boxing, and points it out each time. Without any experience in performance tuning, you&amp;#39;d be forgiven for thinking that boxing is the primary cause of poor performance in .NET applications based on this book. While I agree that it&amp;#39;s something to be avoided where it&amp;#39;s possible to do so without bending the design out of shape, it doesn&amp;#39;t deserve to be laboured as much as it is here. In particular, Trey gives an example of a complex number struct and how he&amp;#39;s written appropriate overloads etc to avoid boxing. Unfortunately, to calculate the magnitude of the complex number (used to implement IComparable in a manner which violates the contract, but that&amp;#39;s another matter) he uses &lt;code&gt;Math.Pow(real, 2) + Math.Pow(img, 2)&lt;/code&gt;. Using a quick and dirty benchmark, I found that using &lt;code&gt;real * real + img * img&lt;/code&gt; instead of Math.Pow made &lt;em&gt;far, far&lt;/em&gt; more difference than whether or not the struct was boxed. (I happen to think it&amp;#39;s more readable code too, but never mind.) There was nothing wrong with avoiding the boxing, but in chasing the small performance gains, the big ones were missed.&lt;/p&gt; &lt;li&gt; &lt;p&gt;In the chapter on threading, there are some demonstrations of lock-free programming (&lt;em&gt;before&lt;/em&gt; describing locking, somewhat oddly - and without describing the &lt;code&gt;volatile&lt;/code&gt; modifier). Now, personally I&amp;#39;d want to discourage people from attempting lock-free programming at all unless they&amp;#39;ve got a really good reason (with evidence!) to support that decision - but if you&amp;#39;re going to do it at all, you need to be hugely careful. One of the examples basically has a load of threads starting and stopping, updating a counter (correctly) using &lt;code&gt;Interlocked.Increment&lt;/code&gt;/&lt;code&gt;Decrement&lt;/code&gt;. Another thread monitors the count and periodically reports it - but unfortunately it uses this statement to do it:&lt;/p&gt; &lt;p&gt; &lt;div class="code"&gt;threadCount = Interlocked.Exchange(&lt;span class="MethodParameter"&gt;ref&lt;/span&gt; numberThreads, numberThreads); &lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;The explanation states: &amp;quot;Since the &lt;code&gt;Interlocked&lt;/code&gt; class doesn&amp;#39;t provide a method to simply read an &lt;code&gt;Int32&lt;/code&gt; value in an atomic operation, all I&amp;#39;m doing is swapping the &lt;code&gt;numberThreads&lt;/code&gt; variable&amp;#39;s value with its own value, and, as a side effect, the &lt;code&gt;Interlocked.Exchange&lt;/code&gt; method returns to me the value that was in the slot.&amp;quot; Well, not quite. It&amp;#39;s actually swapping the &lt;code&gt;numberThreads&lt;/code&gt; variable&amp;#39;s value with &lt;i&gt;a value evaluated at some point before the method call&lt;/i&gt;. If you rewrite the code like this, it becomes more obviously wrong:&lt;/p&gt; &lt;p&gt; &lt;div class="code"&gt;&lt;span class="ValueType"&gt;int&lt;/span&gt; tmp = numberThreads;&lt;br /&gt;Thread.Sleep(1000); &lt;span class="InlineComment"&gt;// What could possibly happen during this time, I wonder?&lt;/span&gt;&lt;br /&gt;threadCount = Interlocked.Exchange(&lt;span class="MethodParameter"&gt;ref&lt;/span&gt; numberThreads, tmp); &lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;The call to &lt;code&gt;Thread.Sleep&lt;/code&gt; is there to make it clear that &lt;code&gt;numberThreads&lt;/code&gt; can very easily change between the initial read and the call to &lt;code&gt;Interlocked.Exchange&lt;/code&gt;. The correct fix to the code is to use something like this:&lt;/p&gt; &lt;p&gt; &lt;div class="code"&gt;threadCount = Interlocked.CompareExchange(&lt;span class="MethodParameter"&gt;ref&lt;/span&gt; numberThreads, 0, 0); &lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;That sets &lt;code&gt;numberThreads&lt;/code&gt; atomically to the value 0 if (and only if) its value is &lt;i&gt;already&lt;/i&gt; 0 - in other words, it will never actually change the value, just report it. Now, I&amp;#39;ve laboured the explanation of why the code is wrong because it&amp;#39;s fairly subtle. Obvious errors in books are relatively harmless - subtle ones are much more worrying.&lt;/p&gt; &lt;li&gt; &lt;p&gt;As a final example for this section, let&amp;#39;s look at iterator blocks. Did you know that any parameters passed to methods implemented using iterator blocks become &lt;em&gt;public&lt;/em&gt; fields in the generated class? I certainly didn&amp;#39;t. Trey pointed out that this meant they could easily be changed with reflection, and that could be dangerous. (After looking with reflector, it appears that local variables within the iterator block are also turned into public fields.) Now, leaving aside the fact that this is &lt;em&gt;hugely&lt;/em&gt; unlikely to actually bite anyone (I&amp;#39;d be frankly amazed to see it as a problem in the wild) the suggested fix is very odd. &lt;/p&gt; &lt;p&gt;The example Trey gives is where originally a Boolean parameter is passed into the method, and used in two places. Oh no! The value of the field can be changed between those two uses, which could lead to problems! True. The supposed fix is to wrap the Boolean value in an immutable struct &lt;code&gt;ImmutableBool&lt;/code&gt;, and pass that in instead. Now, why would that be any better? Certainly you can&amp;#39;t change the value within the struct - but you can easily change the &lt;em&gt;field&lt;/em&gt;&amp;#39;s value to be a &lt;em&gt;completely different instance of ImmutableBool&lt;/em&gt;. Indeed, the breakage would involve &lt;em&gt;exactly&lt;/em&gt; the same code, just changing the type of the value. The other train of thought which suggests that this approach would fail is that &lt;code&gt;bool&lt;/code&gt; is &lt;i&gt;already&lt;/i&gt; immutable, so it can&amp;#39;t be the mutability of the &lt;i&gt;type&lt;/i&gt; of the field that causes problems. I&amp;#39;m sure there are much more useful things that Trey could have said in the two and a half pages he spent describing a broken fix to an unimportant problem.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Sorry, that was getting ranty for a bit... but I hope you understand why. Before concluding this review, let&amp;#39;s look at one chapter which is somewhat different to the rest, and which I&amp;#39;ve mentioned before:&lt;/p&gt; &lt;h3&gt;In Search of C# Canonical Forms (aka &amp;quot;Design and Implementation Guidelines&amp;quot; :)&lt;/h3&gt; &lt;p&gt;I&amp;#39;d been looking forward to this part of the book. I&amp;#39;m always interested in seeing what other people think the most important aspects of class design are. The book doesn&amp;#39;t go into much detail about abstract orientation (in this chapter, anyway - there&amp;#39;s plenty scattered through the book) but concentrates on core interfaces you might implement, etc. That&amp;#39;s fine. I&amp;#39;m still waiting for a C# book to be written to truly be on a par with &lt;a href="http://www.amazon.com/dp/0321356683"&gt;Effective Java&lt;/a&gt; (I have the second edition waiting to be read at work...) but I wasn&amp;#39;t expecting it all to be here. So, was this chapter worth the wait?&lt;/p&gt; &lt;p&gt;Somewhat. I was very glad to see that the first point around reference types was &amp;quot;Default to sealed classes&amp;quot; - I couldn&amp;#39;t agree more, and the arguments were well articulated. Many other guidelines were either entirely reasonable or at least I could go either way on. There were a few where I either disagreed or at least would have put things differently:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Implementing cloning with copy constructors: one point about cloning which wasn&amp;#39;t mentioned is that (to quote MSDN) &amp;quot;The resulting clone must be of the same type as or a compatible type to the original instance.&amp;quot; The suggested implementation of &lt;code&gt;Clone&lt;/code&gt; in the book is to use copy constructors. This means that &lt;i&gt;every&lt;/i&gt; subclass must override &lt;code&gt;Clone&lt;/code&gt; to call its own copy constructor, otherwise the instance returned will be of the wrong type. &lt;code&gt;MemberwiseClone&lt;/code&gt; always creates an instance of the same type. Yes, it means the constructor isn&amp;#39;t called - but frankly the example given (performing a database lookup in the constructor) is a pretty dodgy cloning scenario in the first place, in my view. If I create a clone and it doesn&amp;#39;t contain the same data as the original, there&amp;#39;s something wrong. Having said that, the caveats Trey gives around &lt;code&gt;MemberwiseClone&lt;/code&gt; are all valid in and of themselves - we just disagree about their importance. The advice to not actually implement &lt;code&gt;ICloneable&lt;/code&gt; in the first place is also present (and well explained).  &lt;li&gt;Implementing &lt;code&gt;IDisposable&lt;/code&gt;: Okay, so this is a tough topic, but I was slightly disappointed to see the recommendation that &amp;quot;it&amp;#39;s wise for any objects that implement the &lt;code&gt;IDisposable&lt;/code&gt; interface to also implement a finalizer [...]&amp;quot; Now admittedly on the same page there&amp;#39;s the statement that &amp;quot;In reality, it&amp;#39;s rare that you&amp;#39;ll ever need to write a finalizer&amp;quot; but the contradiction isn&amp;#39;t adequately resolved. A lot of people have trouble understanding this topic, so it would have been nice to see really crisp advice here. My 20 second version of it is: &amp;quot;Only implement a finalizer if you&amp;#39;re holding on to resources which won&amp;#39;t be cleaned up by their own finalizers.&amp;quot; That actually cuts out almost everything, unless you&amp;#39;ve got an &lt;code&gt;IntPtr&lt;/code&gt; to a native handle (in which case, use &lt;code&gt;SafeHandle&lt;/code&gt; instead).  &lt;ul&gt; &lt;li&gt;As a side note, Trey repeatedly claims that &amp;quot;finalizers aren&amp;#39;t destructors&amp;quot; which irks me somewhat as the C# spec (the MS version, anyway) uses the word &amp;quot;destructor&amp;quot; exclusively - a destructor is the way you implement a .NET finalizer in C#. It would be fine to say &amp;quot;destructors in C# aren&amp;#39;t deterministic, unlike destructors in C++&amp;quot; but I think it&amp;#39;s worth acknowledging that the word has a valid meaning in the context of C#. Anyway...&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Implementing equality comparisons: while this was largely okay, I was disappointed to see that there wasn&amp;#39;t much discussion of inheritance and how it breaks equality comparisons in a hard-to-fix way. There&amp;#39;s some mention of inheritance, but it doesn&amp;#39;t tackle the issue I think is thorniest: If I&amp;#39;m asking one square whether it&amp;#39;s equal to another square, is it enough to just check for everything I know about squares (e.g. size and position)? What about if one of the squares is actually a &lt;em&gt;coloured&lt;/em&gt; square - it has more information than a &amp;quot;basic&amp;quot; square. It&amp;#39;s very easy to end up with implementations which break reflexivity, simply because the question isn&amp;#39;t well-defined. You effectively need to be asking &amp;quot;are these two objects equal in &amp;lt;this&amp;gt; particular aspect&amp;quot; - but you don&amp;#39;t get to specify the aspect. This is an example where I remember Effective Java (first edition) giving a really thorough explanation of the pitfalls and potential implementations. The coverage in Accelerated C# 2008 is far from &lt;em&gt;bad&lt;/em&gt; - it just doesn&amp;#39;t meet the gold standard. Arguably it&amp;#39;s unfair to ask another book to compete at that level, when it&amp;#39;s trying to do so much else as well.  &lt;li&gt;Ordering: I mentioned earlier on that the complex number class used for a boxing example failed to implement comparisons appropriately. Unfortunately it&amp;#39;s used as the example specifically for &amp;quot;how to implement &lt;code&gt;IComparable&lt;/code&gt; and &lt;code&gt;IComparable&amp;lt;T&amp;gt;&lt;/code&gt;&amp;quot; as well. To avoid going into too much detail, if you have two instances &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; such that &lt;code&gt;x != y&lt;/code&gt; but &lt;code&gt;x.Magnitude == y.Magnitude&lt;/code&gt;, you&amp;#39;ll find &lt;code&gt;x.CompareTo(y) == y.CompareTo(x)&lt;/code&gt; (but with a non-zero result in both cases). What&amp;#39;s needed here is a completely different example - one with a more obvious ordering.  &lt;li&gt;Value types and immutability: Okay, so the last bullet on the value types checklist is &amp;quot;Should this struct be immutable? [...] Values are excellent candidates to be immutable types&amp;quot; but this comes &lt;em&gt;after&lt;/em&gt; &amp;quot;Need to boxed instances of value? Implement an interface to do so [...]&amp;quot; No! Just say no to mutable value types to start with! Mutable value types are bad, bad, bad, and should be avoided like the plague. There are a &lt;em&gt;very&lt;/em&gt; few situations where it &lt;em&gt;may&lt;/em&gt; be appropriate, but to my mind any advice checklist for implementing structs should make two basic points:  &lt;ul&gt; &lt;li&gt;Are you sure you really wanted a struct in the first place? (They&amp;#39;re rarely the right choice.)  &lt;li&gt;Please make it immutable! Pretty please with a cherry on top? Every time a struct is mutated, a cute kitten dies. Do you really want to be responsible for that?&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;At the risk - nay, certainty - of repeating myself, I&amp;#39;m going to say that I like the book despite the (sometimes subjective) flaws pointed out above. As Shakespeare wrote in Julius Caesar, &amp;quot;The evil men do lives after them. The good is oft interred with their bones.&amp;quot; So it is with book reviews - it&amp;#39;s a lot easier to give specific examples of problems than it is to report successes - but the book &lt;em&gt;does&lt;/em&gt; succeed, for the most part. Perhaps the root of almost all my reservations is that it tries to do too much - I&amp;#39;m not sure whether it&amp;#39;s possible to go into that much detail &lt;em&gt;and&lt;/em&gt; cater for those with little or no previous C# experience (even with Java/C++) &lt;em&gt;and&lt;/em&gt; keep to a relatively slim volume. It was a very lofty goal, and Trey has done very well to accomplish what he has. I would be interested to read a book by him (and hey, potentially even collaborate on it) which is &lt;em&gt;solely&lt;/em&gt; on well-designed classes and libraries.&lt;/p&gt; &lt;p&gt;In short, I recommend Accelerated C# 2008, with a few reservations. Hopefully you can judge for yourself whether my reservations would bother you or not. I think overall I &lt;em&gt;slightly&lt;/em&gt; prefer C# 3.0 in a Nutshell, but the two books are fairly different.&lt;/p&gt; &lt;h3&gt;Reaction&lt;/h3&gt; &lt;p&gt;I sent this to Trey before publishing it, as is my custom. He responded to all my points extremely graciously. I&amp;#39;m not sure yet whether I can post the responses themselves - stay tuned for the possibility, at least. My one problem with reviewing books is that I end up in contact with so many other authors who I&amp;#39;d like to work with some day, and that number has just increased again...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1643045" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Book+reviews/default.aspx">Book reviews</category></item><item><title>Judging a book by its cover (or title)</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/07/18/judging-a-book-by-its-cover-or-title.aspx</link><pubDate>Fri, 18 Jul 2008 19:50:24 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1641374</guid><dc:creator>skeet</dc:creator><slash:comments>19</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1641374</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1641374</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/07/18/judging-a-book-by-its-cover-or-title.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve ranted about versioning before (and indeed in C# in Depth). I still believe that Microsoft didn&amp;#39;t do the world any favours when they introduced a &lt;em&gt;relatively&lt;/em&gt; minor set of changes (just libraries, albeit important ones) with .NET 3.0 and a more major set of changes (languages, LINQ, core library improvements) with .NET 3.5. Using 2.5 and 3.0 would have made more sense, IMO. But never mind.&lt;/p&gt; &lt;p&gt;The fact is, people are confused about what version number applies to what. A number of people claim to be using C# 3.5 when they mean either C# 3.0 or .NET 3.5. (For a quick reference of what&amp;#39;s actually what, see my &lt;a href="http://csharpindepth.com/Articles/Chapter1/Versions.aspx"&gt;article on the issue&lt;/a&gt;.)&lt;/p&gt; &lt;p&gt;Okay, so far it&amp;#39;s the fault of Microsoft for being confusing and the fault of developers for not keeping up. Both of these are far more forgiveable in my view than being &lt;em&gt;flat out wrong&lt;/em&gt; as many books are at the moment. I don&amp;#39;t believe this is any indication on the quality of the book itself (Accelerated C# 2008 is pretty good so far, for example) but I still think it&amp;#39;s pretty awful to make a title so confusing. So, here are some bad titles and others which use version numbers appropriately. (I&amp;#39;ve left out titles like Head First C# and C# in Depth which don&amp;#39;t specify version numbers.)&lt;/p&gt; &lt;h4&gt;Bad&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Professional C# 2008 (Wrox)&lt;/li&gt; &lt;li&gt;Pro C# 2008 and the .NET 3.5 Platform (Apress) (only partly incorrect, of course)&lt;/li&gt; &lt;li&gt;Murach&amp;#39;s C# 2008 (Mike Murach and Associates)&lt;/li&gt; &lt;li&gt;Accelerated C# 2008 (Apress)&lt;/li&gt; &lt;li&gt;Illustrated C# 2008 (Apress)&lt;/li&gt; &lt;li&gt;Pro LINQ: Language Integrated Query in C# 2008 (APress) &lt;/li&gt; &lt;li&gt;Pro ASP.NET 3.5 in C# 2008 (Apress) (again, only partially incorrect)&lt;/li&gt; &lt;li&gt;Beginning C# 2008 (Apress)&lt;/li&gt; &lt;li&gt;Beginning C# 2008 Databases (Apress)&lt;/li&gt; &lt;li&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Good&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;C# 3.0 in a Nutshell (O&amp;#39;Reilly)&lt;/li&gt; &lt;li&gt;Programming C# 3.0 (O&amp;#39;Reilly)&lt;/li&gt; &lt;li&gt;C# 3.0 Cookbook (O&amp;#39;Reilly)&lt;/li&gt; &lt;li&gt;C# 3.0 Design Patterns (O&amp;#39;Reilly)&lt;/li&gt; &lt;li&gt;C# 3.0 Pocket Reference (O&amp;#39;Reilly)&lt;/li&gt; &lt;li&gt;Pro C# with .NET 3.0 (Apress)&lt;/li&gt; &lt;li&gt;Beginning C# 3.0 (Wrox)&lt;/li&gt; &lt;li&gt;C# 3.0 Unleashed: With the .NET Framework 3.5 (Sams)&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Okay&lt;/h4&gt; &lt;p&gt;This is the &amp;quot;well, just about&amp;quot; list - because they&amp;#39;re referring to &amp;quot;Microsoft Visual C# 2008&amp;quot; instead of C# 2008, it&amp;#39;s referring to the IDE instead of the language. I think it&amp;#39;s better to name a book after the language instead of the tool you use to write in the language, personally...&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Beginning Microsoft Visual C# 2008 (Wrox)&lt;/li&gt; &lt;li&gt;Microsoft Visual C# 2008 Step By Step (Microsoft)&lt;/li&gt; &lt;li&gt;Programming Microsoft Visual C# 2008 (Microsoft)&lt;/li&gt; &lt;li&gt;Microsoft Visual C# 2008 Express Edition: Build a Program Now! (Microsoft)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Notice a pattern? If anyone at Apress is reading this (unlikely, I know) - &lt;em&gt;there&amp;#39;s no such thing as &lt;/em&gt;&amp;quot;&lt;em&gt;C# 2008&lt;/em&gt;&amp;quot;.&lt;/p&gt; &lt;p&gt;Rant over for the moment. With any luck I might be able to finish reading Accelerated C# 2008 fairly soon, and give a proper book review.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1641374" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Book+reviews/default.aspx">Book reviews</category></item><item><title>Guest post: Joe Albahari reviews C# in Depth</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/06/06/guest-post-joe-albahari-reviews-c-in-depth.aspx</link><pubDate>Fri, 06 Jun 2008 16:22:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1632405</guid><dc:creator>skeet</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1632405</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1632405</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/06/06/guest-post-joe-albahari-reviews-c-in-depth.aspx#comments</comments><description>&lt;p&gt;Joe Albahari, co-author of the excellent &lt;a href="http://albahari.com/nutshell"&gt;C# 3.0 in a 
Nutshell&lt;/a&gt; (previously &lt;a href="http://msmvps.com/blogs/jon.skeet/archive/2008/03/31/book-review-c-3-0-in-a-nutshell.aspx"&gt;reviewed here&lt;/a&gt;) 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 &lt;a href="http://csharpindepth.com/Notes.aspx"&gt;C# in Depth notes page&lt;/a&gt; - it&amp;#39;s always good to include thoughtful feedback. (And I always welcome more, hint hint.)&lt;/p&gt;
&lt;p&gt;
Without further ado, here&amp;#39;s Joe&amp;#39;s review.
&lt;/p&gt;
&lt;h3&gt;C# in Depth: Review&lt;/h3&gt;
&lt;p&gt;After having been invited to 
review this book by two people at Manning—as well as Jon himself—I 
figure it&amp;#39;s about time I came forward! Bear in mind that I&amp;#39;m not 
a typical reader: I&amp;#39;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&amp;#39; work!). So I will do my best to compensate and 
strive to be fair. Please post a comment if you feel I&amp;#39;ve missed the 
mark!&lt;/p&gt;

&lt;h3&gt;Scope&lt;/h3&gt;

&lt;p&gt;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&amp;#39;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&amp;#39;t 
duplicate the books already out there, as well as giving more space 
for the language.&lt;/p&gt;

&lt;p&gt;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&amp;#39;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.&lt;/p&gt;

&lt;h3&gt;Organization and Style&lt;/h3&gt;


&lt;p&gt;The book is divided into three 
parts:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Preliminaries (delegates 
  and the type system)&lt;/li&gt;
  &lt;li&gt;Features new to 
  C# 2.0&lt;/li&gt;
  &lt;li&gt;Features new to 
  C# 3.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;C# in Depth is a tutorial that 
gradually builds one concept upon another and is designed primarily 
for sequential reading. The examples don&amp;#39;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.
&lt;/p&gt;
&lt;p&gt;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.
&lt;/p&gt;
&lt;p&gt;If I were to classify this 
book as beginner/intermediate/advanced, I&amp;#39;d say intermediate-to-advanced. 
It&amp;#39;s quite a bit more advanced than, say, Jesse&amp;#39;s tutorial “Programming 
C#”. &lt;/p&gt;
&lt;p&gt;The layout of the book is pleasing—I 
particularly like the annotations alongside the code listings.
&lt;/p&gt;
&lt;h3&gt;Content&lt;/h3&gt;

&lt;p&gt;In the first section, &amp;quot;Preparing 
for the Journey,&amp;quot; the book does cover a few C# 1 topics, namely delegates 
and C#&amp;#39;s type system. Jon&amp;#39;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 &amp;quot;Dispelling Myths&amp;quot;—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.
&lt;/p&gt;
&lt;p&gt;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&amp;#39;s generics and C++&amp;#39;s templates. Nullable types 
are covered similarly well, with suggested patterns of use, as are anonymous 
methods and iterators. &lt;/p&gt;
&lt;p&gt;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&amp;#39;s also a chapter called 
“LINQ Beyond Collections” which briefly introduces the LINQ to SQL, 
LINQ to DataSet and LINQ to XML APIs. &lt;/p&gt;

&lt;p&gt;Throughout the book, Jon goes 
to some lengths to explain not just “what”, but “why”. This 
book isn&amp;#39;t for people who want to get in and out quick so they can 
get their job done and out of the way—it&amp;#39;s for people who enjoy 
working elegantly with their tools, through a rich understanding of 
the language&amp;#39;s background, subtleties and nuances.
&lt;/p&gt;
&lt;p&gt;Of course, digesting all this 
is a bit of work (Chapter 3&amp;#39;s summary opens with the word &amp;quot;Phew!&amp;quot;). 
Despite this, I think Jon does a good job at explaining difficult things 
well. I don&amp;#39;t think I&amp;#39;ve seen any IL listings in the book, which is 
a good sign in general. I&amp;#39;m always wary when an author, in explaining 
a C# concept, says, &amp;quot;to understand XYZ, we must examine the IL&amp;quot;. 
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&amp;#39;t to saying looking at IL isn&amp;#39;t 
useful for a deeper understanding of the CLR—but only after first 
teaching C# concepts independently of IL. &lt;/p&gt;

&lt;h3&gt;What&amp;#39;s Missing&lt;/h3&gt;

&lt;p&gt;It was in Jon&amp;#39;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&amp;#39;re looking for a “delta” book, although, of course, 
it makes it less useful as a language reference. &lt;/p&gt;
&lt;p&gt;The book&amp;#39;s treatment of LINQ 
centres largely on LINQ to Objects. If you&amp;#39;re planning on learning 
C# 3.0 so that you can query databases through LINQ, the book&amp;#39;s focus 
is not ideal, if read in isolation. I personally prefer the approach 
of covering &amp;quot;remote&amp;quot; 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 &amp;quot;reproduce&amp;quot; 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&amp;#39;s LINQ in Action (this book is well-reviewed 
on Amazon, though I&amp;#39;ve not yet read it). &lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;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 &amp;quot;inside&amp;quot; 
tutorial on the features new to C# 2 and 3.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1632405" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Book+reviews/default.aspx">Book reviews</category></item><item><title>Programming "in" a language vs programming "into" a language</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/04/23/programming-quot-in-quot-a-language-vs-programming-quot-into-quot-a-language.aspx</link><pubDate>Wed, 23 Apr 2008 18:47:15 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1601545</guid><dc:creator>skeet</dc:creator><slash:comments>15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1601545</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1601545</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/04/23/programming-quot-in-quot-a-language-vs-programming-quot-into-quot-a-language.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;m currently reading Steve McConnell&amp;#39;s &lt;i&gt;Code Complete&lt;/i&gt; (for the first time - yes, I know that&amp;#39;s somewhat worrying) and there was one section was disturbed me a little. For those of you with a copy to hand, it&amp;#39;s in section 4.3, discussing the difference between programming &lt;i&gt;in&lt;/i&gt; a language and programming &lt;i&gt;into&lt;/i&gt; a language: &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Programmers who program &amp;quot;in&amp;quot; a language limit their thoughts to constructs that the language directly supports. If the language tools are primitive, the programmer&amp;#39;s thoughts will also be primitive. &lt;/p&gt; &lt;p&gt;Programmers who program &amp;quot;into&amp;quot; a language first decide what thoughts they want to express, and then they determine how to express those thoughts using the tools provided by their specific language. &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Now don&amp;#39;t get me wrong - I can see where he&amp;#39;s coming from, and the example he then provides (Visual Basic - keeping the forms simple and separating them from business logic) is fine, but he only seems to give one side of the coin. Here&amp;#39;s a different - and equally one-sided - way of expressing the same terms: &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Programmers who program &amp;quot;in&amp;quot; a language understand that language&amp;#39;s conventions and idioms. They write code which integrates well with other libraries, and which can be easily understood and maintained by other developers who are familiar with the language. They benefit from tools which have been specifically designed to aid coding in the supported idioms. &lt;/p&gt; &lt;p&gt;Programmers who program &amp;quot;into&amp;quot; a language will use the same ideas regardless of their target language. If their style does not mesh well with the language, they will find themselves fighting against it every step of the way. It will be harder to find libraries supporting their way of working, and tools may well prove annoying. Other developers who come onto the project later and who have experience in the language but not the codebase will find it hard to navigate and may well accidentally break the code when changing it.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;There is a happy medium to be achieved, clearly. You certainly shouldn&amp;#39;t restrict your thinking to techniques which are entirely idiomatic, but if you find yourself wanting to code in a radically different style to that encouraged by the language, consider changing language if possible!&lt;/p&gt; &lt;p&gt;If I were attacking the same problem in C# 1 and C# 3, I could easily end up with radically different solutions. Some data extraction using LINQ in a fairly functional way in C# 3 would probably be better solved in C# 1 by losing some of the functional goodness than by trying to back-port LINQ and then use it without the benefit of lambda expressions or even anonymous methods.&lt;/p&gt; &lt;h3&gt;Accents and Conventions&lt;/h3&gt; &lt;p&gt;That&amp;#39;s just between different versions of the same language. Between different actual languages, it can get much worse. If you&amp;#39;ve ever seen Java code written in a C++ style or vice versa, you&amp;#39;ll know what I mean. I&amp;#39;ve previously referred to this in terms of speaking a language with an accent - you can speak C# with a Java accent just as you can speak French with an English accent. Neither is pleasant. &lt;/p&gt; &lt;p&gt;At the lowest level, this is likely to be about conventions - and I&amp;#39;m pretty sure that when Steve writes &amp;quot;Invent your own coding conventions, standards, class libraries, and other augmentations&amp;quot; he doesn&amp;#39;t actually mean us to do it in a gratuitous fashion. It &lt;i&gt;can&lt;/i&gt; be worth deviating from the &amp;quot;platform favoured&amp;quot; conventions sometimes, particularly if those differences are invisible to clients, but it should always be done with careful consideration. In a Java project I worked on a few years ago, we took the .NET naming conventions for interfaces (an I prefix) and constants (CamelCasing instead of SHOUTY_CAPS). Both of these made the codebase feel slightly odd, particularly where Java constants were used near our constants - but I personally found the benefits to be worth the costs. Importantly, the whole team discussed it before making any decisions.&lt;/p&gt; &lt;h3&gt;Design Patterns&lt;/h3&gt; &lt;p&gt;At a slightly higher level, many design patterns are just supported much, much better by some languages than others. The iterator pattern is a classic example. Compare the support for it from Java 6 and C# 2. On the &amp;quot;client&amp;quot; side, both languages have specific syntax: the enhanced &lt;code&gt;for&lt;/code&gt; loop in Java and the &lt;code&gt;foreach&lt;/code&gt; loop in C#. However, there is one important difference: if the iterator returned by &lt;code&gt;GetEnumerator&lt;/code&gt; implements &lt;code&gt;IDisposable&lt;/code&gt; (which the generic form demands, in fact) C# will call &lt;code&gt;Dispose&lt;/code&gt; at the end of the loop, no matter how that occurs (reaching the end of the sequence, breaking early, an exception being thrown, etc). Java has no equivalent of this. Imagine that you want to write a class to iterate over the lines in a file. In Java, there&amp;#39;s just no safe way of representing it: you can make your iterator implement &lt;code&gt;Closeable&lt;/code&gt; but then callers can&amp;#39;t (safely) use the enhanced for&lt;/code&gt; loop. You can make your code close the file handle when it reaches the end, but there&amp;#39;s no guarantee that will happen. &lt;/p&gt; &lt;p&gt;Then consider the &amp;quot;server&amp;quot; side of the iterator - the code actually providing the data. Java is like C# 1 - there&amp;#39;s no specific support for implementing an iterator. In C# 2 and above, iterator blocks (i.e. methods with &lt;code&gt;yield&lt;/code&gt; statements) make life much, much easier. Writing iterators by hand can be a real pain. Reading a file line by line isn&amp;#39;t too bad, leaving aside the resource lifetime issue - but the complexity can balloon very quickly. Off by one errors are really easy to introduce. &lt;/p&gt; &lt;p&gt;So, if I were tackling a project which required reading text files line by line in various places, what would I do? In Java, I would take the reasonably small hit of a &lt;code&gt;while&lt;/code&gt; loop in each place I needed it. In C# I&amp;#39;d write a &lt;code&gt;LineReader&lt;/code&gt; class (if I didn&amp;#39;t already have one!) and use a more readable &lt;code&gt;foreach&lt;/code&gt; loop. The contortions involved in introducing that idea into Java just wouldn&amp;#39;t be worth the effort. &lt;/p&gt; &lt;p&gt;At a much higher level, we get into whole programming styles and paradigms. If your natural inclination is to write imperative code, you&amp;#39;re likely to create a mess (or get very frustrated) in a functional language. If the problem really does call for a functional language, find someone else to help you think in a more functional way. If the problem suits imperative programming just as well as it does functional programming, see if you can change the environment to something more familiar.&lt;/p&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;I&amp;#39;m not suggesting that Steve&amp;#39;s point isn&amp;#39;t valid - but he&amp;#39;s done his readers a disservice by only presenting one side of the matter. Fortunately, the rest of the book (so far) is excellent and humbling - to such a degree that this minor quibble stuck out like a sore thumb. In a book which had more problems, I would probably barely have even noticed this one. &lt;/p&gt; &lt;p&gt;There&amp;#39;s another possibility, of course - I could be competely wrong; maybe I&amp;#39;ve been approaching problems from a restrictive viewpoint all this time. How about you? &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1601545" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Book+reviews/default.aspx">Book reviews</category></item><item><title>Book review: C# 3.0 in a Nutshell</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/03/31/book-review-c-3-0-in-a-nutshell.aspx</link><pubDate>Mon, 31 Mar 2008 15:16:29 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1563839</guid><dc:creator>skeet</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1563839</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1563839</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/03/31/book-review-c-3-0-in-a-nutshell.aspx#comments</comments><description>&lt;h3&gt;Resources:&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://www.albahari.com/nutshell/"&gt;Book&amp;#39;s web site&lt;/a&gt; (includes various tools such as LINQPad)  &lt;li&gt;&lt;a href="http://www.amazon.com/3-0-Nutshell-Desktop-Reference-OReilly/dp/0596527578"&gt;Amazon&lt;/a&gt;  &lt;li&gt;&lt;a href="http://www.oreilly.com/catalog/9780596527570/errata/"&gt;Errata&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;Introduction&lt;/h3&gt; &lt;p&gt;The original C# in a Nutshell was the book I cut my C# teeth on, so to speak. Basically I read it (well, the bits which weren&amp;#39;t just reproductions of MSDN - gone in this edition, thankfully), played around in Visual Studio, and then started to answer questions on the C# newsgroup. (That&amp;#39;s a great way of learning useful things, by the way - find another person&amp;#39;s problem which sounds like it&amp;#39;s one you &lt;em&gt;might&lt;/em&gt; face in the future, then research the answer.)&lt;/p&gt; &lt;p&gt;Five and a half years later (Google groups suggests I cut my teeth in the C# newsgroup in August 2002) I&amp;#39;ve just been reading C# 3.0 in a Nutshell, by Joe and Ben Albahari (who are brothers, in case anyone&amp;#39;s wondering). Unsurprisingly, there&amp;#39;s rather a lot more in this version :) I bought the book with a fairly open mind, and as you&amp;#39;ll see, I was quite impressed...&lt;/p&gt; &lt;p&gt;For the purposes of this review, I&amp;#39;ll use the &amp;quot;Nutshell&amp;quot; to mean &amp;quot;C# 3.0 in a Nutshell&amp;quot;. It&amp;#39;ll just make life a bit easier.&lt;/p&gt; &lt;h3&gt;Scope&lt;/h3&gt; &lt;p&gt;Nutshell covers:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;C# 1.0 to 3.0 (i.e. it&amp;#39;s &amp;quot;from scratch&amp;quot;)  &lt;li&gt;Core framework (serialization, assemblies, IO, strings, regex, reflection, threading etc)  &lt;li&gt;LINQ to XML  &lt;li&gt;A bit of LINQ to SQL while discussing LINQ in general&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;It explicitly &lt;em&gt;doesn&amp;#39;t&lt;/em&gt; try to be a &amp;quot;one stop shop for every .NET technology&amp;quot;. You won&amp;#39;t find much about WinForms, WPF, WCF, ASP.NET etc - to which my reaction is &amp;quot;hoorah!&amp;quot;. I&amp;#39;ve probably said it before on this blog, but if you&amp;#39;re going to use any of those technologies in any depth, you really need to study that topic in isolation. One chapter in a bigger book just isn&amp;#39;t going to cut it.&lt;/p&gt; &lt;p&gt;That&amp;#39;s the scope of the book. The scope of my review is slightly more limited. I&amp;#39;ve read the C# stuff reasonably closely, and dipped into some of the framework aspects - particularly those I&amp;#39;m fairly knowledgeable about. The idea was to judge the accuracy and depth of coverage, which would be hard to do for topics which I&amp;#39;m relatively inexperienced in.&lt;/p&gt; &lt;h3&gt;Format and style&lt;/h3&gt; &lt;p&gt;Nutshell is a reference book which goes to some lengths to be readable in a &amp;quot;cover to cover&amp;quot; style. It&amp;#39;s worth mentioning the contrast here with C# in Depth, which is a &amp;quot;cover to cover&amp;quot; book which attempts to be useful as a reference too. I&amp;#39;d expect the index of Nutshell to be used much more than the index of C# in Depth, for example - but both books &lt;em&gt;can&lt;/em&gt; be used in either way.&lt;/p&gt; &lt;p&gt;As an example of the difference in style, each section of Nutshell stands on its own: there&amp;#39;s little in the way of segues from one section to the next. That&amp;#39;s not to say that there are &lt;em&gt;no&lt;/em&gt; segues, or indeed that there&amp;#39;s no flow: the order in which topics are introduced is pretty logical and &lt;em&gt;sometimes&lt;/em&gt; there&amp;#39;s an explicit &amp;quot;having looked at X we&amp;#39;ll now look at Y&amp;quot; - but it feels to me like there&amp;#39;s less attempt to keep the reader going. That&amp;#39;s absolutely right for a reference book, and it doesn&amp;#39;t &lt;em&gt;prevent&lt;/em&gt; the book from being read from cover to cover - it just doesn&amp;#39;t particularly encourage it.&lt;/p&gt; &lt;p&gt;There are lots of little callout notes, both in terms of &amp;quot;look here for more depth&amp;quot; and &amp;quot;be careful - here be dragons&amp;quot;. These are very welcome, and call attention to a lot of important points.&lt;/p&gt; &lt;p&gt;The layout is perfectly pleasant, in a &amp;quot;normal book&amp;quot; kind of way - it&amp;#39;s neither the alternating text/code/text/code style of the King/Eckel book, nor the &amp;quot;pictures everywhere&amp;quot; Head First format. In that sense it&amp;#39;s reasonably close to C# in Depth, although it uses comments instead of arrows for annotations. The physical format is slightly shorter and narrower than most technical books. This gives a different feeling which is hard to characterize somehow, but definitely present.&lt;/p&gt; &lt;h3&gt;Accuracy and Depth&lt;/h3&gt; &lt;p&gt;The main problem I had with Head First C# was the inaccuracies (which, I have to stress, are hopefully going to be fixed to a large extent in a future printing). While there &lt;em&gt;are&lt;/em&gt; inaccuracies in Nutshell, they are generally fewer and further between, and less important. In short, I&amp;#39;m certainly not worried about developers learning bad habits and incorrect truths from Nutshell. Again, I&amp;#39;ve sent my list of potential corrections to the authors, who have been very receptive. (It&amp;#39;s also worth being skeptical about some of the errata which have been submitted - I&amp;#39;ve taken issue with several of them.)&lt;/p&gt; &lt;p&gt;The level of depth is very well chosen, given the scope of the book. As examples, the threading section goes into the memory model and the string section talks a bit about surrogates. It would be nice to see a little bit more discussion about internationalisation (with reference to the &lt;a href="http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html"&gt;Turkey test&lt;/a&gt;, for example) as well as more details of the differences between decimal and float/double - but these are all a matter of personal preference. By way of recommendation, I&amp;#39;d say that if every professional developer working in .NET knew and applied the contents of Nutshell, we&amp;#39;d be in a far better state as a development community and industry.&lt;/p&gt; &lt;p&gt;The coverage of C# is very good in terms of &lt;em&gt;what&lt;/em&gt; it does - again, appropriate for a reference work. I&amp;#39;d like to think that C# in Depth goes into more detail of &lt;em&gt;how&lt;/em&gt; and &lt;em&gt;why&lt;/em&gt; the language is designed that way, because that&amp;#39;s a large part of the book&amp;#39;s &lt;i&gt;raison d&amp;#39;être&lt;/i&gt;. It would be a pretty sad indictment of C# in Depth if Nutshell were a complete superset of its material, after all.&lt;/p&gt; &lt;h3&gt;Competitive Analysis&lt;/h3&gt; &lt;p&gt;So, why would you buy one book and not the other? Or should you buy both? Well...&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Nutshell covers C# 1 as well as 2 and 3. The 3.0 features are clearly labelled, and there&amp;#39;s an overview page of what&amp;#39;s new for C# 3.0 - but if you know C# 1 and just want to learn what&amp;#39;s in 2 and 3, C# in Depth will take you on that path more smoothly. On the other hand, if you want to look up aspects of C# 1 for reference, Nutshell is exactly what you need. I wouldn&amp;#39;t really recommend either of them to learn C# from scratch - if you know Java to start with, then Nutshell might be okay, but frankly getting a &amp;quot;basics&amp;quot; tutorial style book is a better starting point.  &lt;li&gt;Nutshell covers the .NET framework as well as the language. C# in Depth looks at LINQ to Objects, rushes through LINQ to SQL/XML/DataSet, and has a bit of a look at generic collections - it&amp;#39;s not in the same league on this front, basically.  &lt;li&gt;Nutshell aims to be a reference book, C# in Depth aims to be a teaching book. Both work to a pretty reasonable extent at doing the reverse.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;To restate this in terms of people:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If you&amp;#39;re an existing C# 1 developer (or C# 2 wanting more depth) who wants to learn C# 2 and 3 in great detail without wading through a lot of stuff you already know, get C# in Depth.  &lt;li&gt;If you want a C# and .NET reference book, get Nutshell.  &lt;li&gt;If you want to learn C# from scratch, buy a &amp;quot;tutorial&amp;quot; book about C# before getting &lt;em&gt;either&lt;/em&gt; Nutshell or C# in Depth.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Clearly Nutshell and C# in Depth &lt;em&gt;are&lt;/em&gt; in competition: there will be plenty of people who only want to buy one of them, and which one will be more appropriate for them will depend on the individual&amp;#39;s needs. However, I believe there are actually &lt;em&gt;more&lt;/em&gt; developers who would benefit greatly from having both books. I&amp;#39;m certainly pleased to have Nutshell on my desk (and indeed it answered a colleague&amp;#39;s question just this morning) - and I hope the Albahari brothers will likewise gain something from reading C# in Depth.&lt;/p&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;C# 3.0 in a Nutshell is really good, and will benefit many developers. It doesn&amp;#39;t make me feel I&amp;#39;ve in any way wasted my time in writing C# in Depth, and the two make good companion books, even though the material is clearly overlapping. Obviously I&amp;#39;d like all my readers to buy C# in Depth in preference if you can only buy one - but it really does make sense to have both.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1563839" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Book+reviews/default.aspx">Book reviews</category></item><item><title>Book review: Head First C#</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/03/21/book-review-head-first-c.aspx</link><pubDate>Fri, 21 Mar 2008 08:30:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1549256</guid><dc:creator>skeet</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1549256</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1549256</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/03/21/book-review-head-first-c.aspx#comments</comments><description>&lt;h3&gt;Important &amp;quot;versioning&amp;quot; note&lt;/h3&gt;  &lt;p&gt;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&amp;#39;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&amp;#39;s likely to be in 2010Q2 at the earliest, and more likely later. I don&amp;#39;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&amp;#39;re written about.) I&amp;#39;m reluctant to go as far as &lt;em&gt;recommending&lt;/em&gt; the latest printing without actually reading it, but I&amp;#39;m fairly confident it&amp;#39;s a lot better than the first printing.&lt;/p&gt;  &lt;p&gt;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&amp;#39;ve had time to review the latest printing of the previous edition, I will probably go straight for that instead.&lt;/p&gt;  &lt;h3&gt;Resources&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.oreilly.com/catalog/9780596514822/"&gt;Book&amp;#39;s web site&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/Head-First-C-Brain-Friendly-Guides/dp/0596514824"&gt;Amazon page&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.oreilly.com/catalog/9780596514822/errata/"&gt;Errata&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p&gt;This is a tough review to write. We already know I&amp;#39;m biased due to being in some way in competition with Andrew Stellman and Jennifer Greene (the authors), but I&amp;#39;m also not a huge fan of the Head First series in general. It doesn&amp;#39;t coincide with how &lt;i&gt;I&lt;/i&gt; like to learn. I feel patronised by the pictures and crosswords rather than drawn into them, etc. However, I&amp;#39;m very aware that it&amp;#39;s really popular - lots of people swear by it, and I know that my own tastes are far from that of the majority. There&amp;#39;s also the fact that Head First C# really isn&amp;#39;t aimed at me at all - it&amp;#39;s aimed at people who don&amp;#39;t know C# to start with.&lt;/p&gt;  &lt;p&gt;Funnily enough, that&amp;#39;s why I really, really wanted to like the book. It&amp;#39;s not &lt;i&gt;actually&lt;/i&gt; competing with C# in Depth except for readers who have no idea what either book is like. I can&amp;#39;t imagine many people being in the situation where both books would be appropriate for them. I &lt;i&gt;do&lt;/i&gt; want to find a good book for someone to learn C# from though, from scratch. My own book is completely unsuitable for that purpose. &lt;a href="http://www.amazon.com/Essential-2-0-Microsoft-NET-Development/dp/0321150775"&gt;Essential C# by Mark Michaelis&lt;/a&gt; is my current favourite, I think - although I confess to not having read it all. It also doesn&amp;#39;t cover C# 3 - although I&amp;#39;m not sure whether I&amp;#39;d actually &lt;i&gt;want&lt;/i&gt; to cover C# 3 for a reader who doesn&amp;#39;t know 1 or 2.&lt;/p&gt;  &lt;p&gt;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&amp;#39;t &lt;i&gt;like&lt;/i&gt; being nasty, and I know how I&amp;#39;d feel reading a review like this of &lt;i&gt;my&lt;/i&gt; book. Unfortunately, it falls a long way short of being worthy of recommendation, and I can&amp;#39;t really find a way of hiding that.&lt;/p&gt;  &lt;p&gt;I &amp;quot;read&amp;quot; the whole book today. Now, it&amp;#39;s over 700 pages &lt;i&gt;and&lt;/i&gt; I&amp;#39;ve been at work, so clearly I haven&amp;#39;t read every word of every page. I have &lt;i&gt;mostly&lt;/i&gt; skimmed the code examples - vital for learning, I&amp;#39;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&amp;#39;s look at what I did and didn&amp;#39;t like:&lt;/p&gt;  &lt;h3&gt;The Good&lt;/h3&gt;  &lt;p&gt;This is going to be a broadly negative review, but it&amp;#39;s not like the book is without merit. Here&amp;#39;s what I liked:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Many of the examples were very nicely chosen. I liked the party organizer (chapter 5) and the room topology (chapter 7) ones in particular. &lt;/li&gt;    &lt;li&gt;You really do get to create some nifty WinForms applications. I wouldn&amp;#39;t like to claim you really understand everything about them by the end of it, but I can see how they&amp;#39;re engaging. &lt;/li&gt;    &lt;li&gt;Annotations in listings are a good thing in general, and I do like the handwritten feel of them. &lt;/li&gt;    &lt;li&gt;Q&amp;amp;A is a good idea for a book like this. Predicting natural questions is an important part of &lt;/li&gt;    &lt;li&gt;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. &lt;/li&gt;    &lt;li&gt;The pictures in this book were actually not annoying, to my surprise. Some were even endearing. Even to me. &lt;/li&gt;    &lt;li&gt;Apparently other people really like this book. It&amp;#39;s got loads of 5-star reviews on Amazon, and apparently it&amp;#39;s been selling fantastically well. From the posts in the book&amp;#39;s forum, people are really getting engaged, which can only be a good thing.&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;The Bad...&lt;/h3&gt;  &lt;h3&gt;Formatting&lt;/h3&gt;  &lt;p&gt;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&amp;#39;re meant to navigate through the page. Often bits of the page &lt;i&gt;do&lt;/i&gt; require a certain order, but that order isn&amp;#39;t always obvious.&lt;/p&gt;  &lt;p&gt;My main problem with the formatting wasn&amp;#39;t nearly as general as that though, and I have to admit it&amp;#39;s a bit obsessive-compulsive. It&amp;#39;s the quotes in the code. They&amp;#39;re not straight. I&amp;#39;ve &lt;i&gt;never&lt;/i&gt; seen an IDE which tries to work out &amp;quot;curly quotes&amp;quot; in code, and I hope I never do. When you&amp;#39;re used to seeing code in a real IDE, seeing curly quotes &lt;i&gt;just looks wrong&lt;/i&gt;. It&amp;#39;s jarring and distracts from the business of learning.&lt;/p&gt;  &lt;p&gt;Oh, and K&amp;amp;R bracing sucks. I know it makes the book shorter, but it makes it harder to read too. Just a personal opinion, of course :)&amp;#160; (Having said which, the bracing style is inconsistent through the book anyway.)&lt;/p&gt;  &lt;h3&gt;&amp;quot;Top-down&amp;quot; learning&lt;/h3&gt;  &lt;p&gt;I&amp;#39;m unashamedly a &amp;quot;bottom-up&amp;quot; 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 &amp;quot;show it all and explain some bits as we go along&amp;quot; approach, reasonably frequently mentioning how awful it is that most technical books try to start with console applications which &lt;i&gt;don&amp;#39;t&lt;/i&gt; need lots of libraries before you even know what a library is.&lt;/p&gt;  &lt;p&gt;I suspect this top-down way does indeed get people going much more quickly than my preferred style. (Remember, this is my preferred &lt;i&gt;reading&lt;/i&gt; style, not just &lt;i&gt;writing&lt;/i&gt; style. It&amp;#39;s no coincidence that I happen to write like I read though.) However, I believe there&amp;#39;s a great danger of people ending up as &lt;a href="http://blogs.msdn.com/EricLippert/archive/2004/03/01/82168.aspx"&gt;cargo-cult programmers&lt;/a&gt;. (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.)&lt;/p&gt;  &lt;p&gt;It&amp;#39;s true that top-down learning gets you doing &lt;i&gt;flashy&lt;/i&gt; stuff more quickly than bottom-up. Whether that&amp;#39;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.&lt;/p&gt;  &lt;p&gt;It feels like there ought to be a middle way, but I&amp;#39;ve no idea what it is yet. The &amp;quot;show something cool in chapter 1 and then go back over the details&amp;quot; approach favoured by the vast majority of technical books (including mine, to some extent) isn&amp;#39;t what I&amp;#39;m thinking of. Definitely something to think about there.&lt;/p&gt;  &lt;h3&gt;Incompleteness&lt;/h3&gt;  &lt;p&gt;I hadn&amp;#39;t expected this book to be in great depth, despite the quote on the back cover: &amp;quot;If you want to learn C# in depth and have fun doing it, this is THE book for you.&amp;quot; I&amp;#39;d expected a bit more than this, however.&lt;/p&gt;  &lt;p&gt;When I said earlier on that HFC# wasn&amp;#39;t competing with C# in Depth, I mentioned audiences. There&amp;#39;s something to be said about material as well though. Let&amp;#39;s look at the bulk of my book - chapters 3-11, which deal with the new language features from C# 2 and 3. Here&amp;#39;s how much is covered in HFC#:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Generics: generic collections get mentioned, but there&amp;#39;s no real explanation of how you&amp;#39;d write your own generic types. Generic methods aren&amp;#39;t mentioned. Type constraints, default(...), variance (or lack thereof), type inference - all absent. &lt;/li&gt;    &lt;li&gt;Nullable types: not mentioned as far as I can see, including an absence of the null-coalescing operator. &lt;/li&gt;    &lt;li&gt;Delegates: there&amp;#39;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.) &lt;/li&gt;    &lt;li&gt;Iterator blocks: IEnumerable&amp;lt;T&amp;gt; is mentioned, but IEnumerator&amp;lt;T&amp;gt; is never shown as far as I remember, and iterator blocks certainly aren&amp;#39;t shown. It mentions that you could implement IEnumerable&amp;lt;T&amp;gt; yourself, but doesn&amp;#39;t give any hints as to how, or what would be required. &lt;/li&gt;    &lt;li&gt;Partial types: covered, albeit only mentioning classes. No sign of partial methods. &lt;/li&gt;    &lt;li&gt;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). &lt;/li&gt;    &lt;li&gt;Separate getter/setter access: covered &lt;/li&gt;    &lt;li&gt;Namespace aliases: not covered &lt;/li&gt;    &lt;li&gt;Pragma directives: not covered &lt;/li&gt;    &lt;li&gt;Fixed size buffers: not covered &lt;/li&gt;    &lt;li&gt;InternalsVisibleTo: not covered (not really a language feature though) &lt;/li&gt;    &lt;li&gt;Automatically implemented properties: covered, but without mentioning (AFAICR) that a hidden backing field is generated for you &lt;/li&gt;    &lt;li&gt;Implicit typing: one call-out and a somewhat inaccurate Q&amp;amp;A &lt;/li&gt;    &lt;li&gt;Object/collection initializers: covered, but without noting that you can remove the brackets from parameterless constructor calls &lt;/li&gt;    &lt;li&gt;Implicitly typed arrays: not covered &lt;/li&gt;    &lt;li&gt;Anonymous types: mentioned in a single annotation, but inaccurately. Used in a few query expressions. &lt;/li&gt;    &lt;li&gt;Lambda expressions: not mentioned (in a book which &amp;quot;covers&amp;quot; C# 3.0. Wow.) &lt;/li&gt;    &lt;li&gt;Expression trees: not mentioned &lt;/li&gt;    &lt;li&gt;Changes to type inference/overloading: hard to explain a change to something which isn&amp;#39;t covered to start with &lt;/li&gt;    &lt;li&gt;Extension methods: covered &lt;/li&gt;    &lt;li&gt;Query expressions: covered to a very limited extent. No explanation of query translation. No explanation of query continuations (although grouping is &lt;i&gt;always&lt;/i&gt; shown with continuations). No sign of multiple &amp;quot;from&amp;quot; statements or &amp;quot;join into&amp;quot;.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;See why I don&amp;#39;t think our books are really competing? Now, a lot of this really is absolutely fine. The &lt;i&gt;details&lt;/i&gt; of generics don&amp;#39;t really belong in an introductory text - although &lt;i&gt;some&lt;/i&gt; 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?&lt;/p&gt;  &lt;p&gt;Maybe I&amp;#39;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:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;typeof(...) &lt;/li&gt;    &lt;li&gt;Casting (&amp;quot;as&amp;quot; doesn&amp;#39;t count as a cast in my view - it&amp;#39;s an operator) &lt;/li&gt;    &lt;li&gt;lock &lt;/li&gt;    &lt;li&gt;volatile &lt;/li&gt;    &lt;li&gt;Explicit interface implementation &lt;/li&gt;    &lt;li&gt;The conditional operator (x ? y : z) &lt;/li&gt;    &lt;li&gt;Hiding members with &amp;quot;new&amp;quot; instead of &amp;quot;override&amp;quot; &lt;/li&gt;    &lt;li&gt;readonly &lt;/li&gt;    &lt;li&gt;The sealed modifier on methods (not just classes) &lt;/li&gt;    &lt;li&gt;ref/out/params modifiers for parameters &lt;/li&gt;    &lt;li&gt;continue, goto, and break (break is mentioned for switch/case, but only there)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Maybe going into the memory model would have been a bit much (without which volatile would be pretty pointless) but not to even &lt;i&gt;mention&lt;/i&gt; threading (and lock) feels a little worrying - especially as Application.DoEvents is abused instead. Explicit interface implementation is relatively obscure - but readonly fields? typeof(...)?&lt;/p&gt;  &lt;p&gt;Fine, it&amp;#39;s an introductory text - but that means it&amp;#39;s a bad idea to talk about &amp;quot;mastering&amp;quot; LINQ and claiming that &amp;quot;by the time you&amp;#39;re through you&amp;#39;ll be a proficient C# programmer, designing and coding large-scale applications&amp;quot;. Those quotes probably aren&amp;#39;t the authors&amp;#39; 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 &lt;i&gt;complete&lt;/i&gt; guide to C#.&lt;/p&gt;  &lt;h3&gt;Errors (please see update at the end of the post, and note at top)&lt;/h3&gt;  &lt;p&gt;This is by far my biggest gripe with the book. It&amp;#39;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&amp;#39;s not obvious to the reader when it&amp;#39;s absent. No-one could reasonably read the book without realising that they&amp;#39;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.&lt;/p&gt;  &lt;p&gt;Now, I&amp;#39;m unfortunate enough to have the first edition (November 2007). The book is currently undergoing its third printing, i.e. it&amp;#39;s had two rounds of corrections. These are listed in the &lt;a href="http://www.oreilly.com/catalog/9780596514822/errata/"&gt;errata&lt;/a&gt; and I&amp;#39;ve tried to take them into account - although there&amp;#39;s no way that a carefully reviewed and edited book should need &lt;i&gt;that&lt;/i&gt; many corrections in such a short space of time. I will concede that a Head First book is likely to be &lt;i&gt;much&lt;/i&gt; harder to get right than a &amp;quot;normal&amp;quot; book though, due to all the funky formatting.&lt;/p&gt;  &lt;p&gt;Typos don&amp;#39;t worry me too much. It&amp;#39;s core technical errors which really bother me. It&amp;#39;s almost as if someone had taken my list of classic &amp;quot;myths&amp;quot; and decided to taunt me. I half expected &amp;quot;objects are passed by reference&amp;quot; to be in there - but as ref/out parameters aren&amp;#39;t covered at all, it&amp;#39;s not. Here are some of the worst/most amusing culprits though:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Claiming that string is a value type (in several places). Oh, and object, once. &lt;/li&gt;    &lt;li&gt;Claiming that the range of sbyte is -127 to 128 (instead of -128 to 127). Same kind of mistake with short. &lt;/li&gt;    &lt;li&gt;&lt;i&gt;Constantly&lt;/i&gt; using field and property as if they were interchangable. They&amp;#39;re not, they&amp;#39;re really, really not. Just because they&amp;#39;re used in a similar way doesn&amp;#39;t mean you can be this loose with the terminology. &lt;/li&gt;    &lt;li&gt;Claiming that C# &amp;quot;marks objects for garbage collection&amp;quot;. In fact, for the first 6/7ths of the book there&amp;#39;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&amp;#39;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. &lt;/li&gt;    &lt;li&gt;Claiming that methods and statements always have to live in classes. Funny how structs can have behaviour too... &lt;/li&gt;    &lt;li&gt;Claiming that &amp;quot;objects are variables&amp;quot; (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... &lt;/li&gt;    &lt;li&gt;Writing a hex dump utility using StreamReader - broken by definition, given that hex dump tools are used to show the &lt;i&gt;binary&lt;/i&gt; contents of files, and StreamReader is meant to read &lt;i&gt;text&lt;/i&gt;, decoding it as it goes. &lt;/li&gt;    &lt;li&gt;Claiming that structs always live on the stack. &lt;/li&gt;    &lt;li&gt;Expanding WPF as &amp;quot;Windows Presentation Framework&amp;quot;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;These are all errors which have made it through not just technical review, but two rounds of post-publication editing. It&amp;#39;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&amp;#39;t have been able to find that many in the first place, even if they &lt;i&gt;have&lt;/i&gt; been corrected. I&amp;#39;m worried if a C# book author believes that a char has 256 possible values, for instance. &lt;i&gt;I&lt;/i&gt; 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.&lt;/p&gt;  &lt;p&gt;Now, there are errors and there are bad practices...&lt;/p&gt;  &lt;h3&gt;Bad practice through example&lt;/h3&gt;  &lt;p&gt;I know we don&amp;#39;t end up writing production code as book examples. Indeed, Eric mentioned this in chapter 1, where I&amp;#39;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 &lt;i&gt;until&lt;/i&gt; properties have been explained but:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;There&amp;#39;s no reason to use poorly named variables/parameters, including Pascal-cased local variables &lt;/li&gt;    &lt;li&gt;Writing loops like for (int i=1; i &amp;lt;= 10; i++) instead of the more idiomatic for (int i=0; i &amp;lt; 10; i++). C# is 0-based in many ways, but often the authors seemed to really wish it were 1-based. &lt;/li&gt;    &lt;li&gt;Continuing to use public fields even after explaining how they&amp;#39;re not really a good idea. (Well, sort of explaining that. There&amp;#39;s a frequent implication that they&amp;#39;re not so bad if other classes really need to be able to access your data. It&amp;#39;s a very long way from my preferred policy of no non-private variables whatsoever.) &lt;/li&gt;    &lt;li&gt;String concatenation in loops with nary a mention of StringBuilder &lt;/li&gt;    &lt;li&gt;Bizarre combination of &amp;quot;is&amp;quot; and &amp;quot;as&amp;quot;, using &amp;quot;as&amp;quot; to perform the conversion instead of casting. If you&amp;#39;re going to use &amp;quot;as&amp;quot;, do it up front and compare with null to start with... &lt;/li&gt;    &lt;li&gt;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&amp;#39;s in and what&amp;#39;s out. &lt;/li&gt;    &lt;li&gt;Advising to stick with the absolutely abhorrent &amp;quot;convention&amp;quot; (aka laziness, and leaving things as VS creates them) of naming event handlers with things like button1_Click. No. Name methods with what they &lt;i&gt;do&lt;/i&gt;, then the event hookup code will make it obvious - and it makes it clearer where you can reuse a single method for multiple events. &lt;/li&gt;    &lt;li&gt;Repeatedly declaring enums within classes as if you couldn&amp;#39;t write them as top-level types. Oh, and messing up the naming conventions there, too. &lt;/li&gt;    &lt;li&gt;Showing a mutable struct without explaining that this should always be avoided is a bad idea.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I could go on. I&amp;#39;ve got pages of notes about this kind of thing (and this is only after owning the book for less than a day, don&amp;#39;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&amp;#39;t see much defence for them.&lt;/p&gt;  &lt;p&gt;Examples matter. I don&amp;#39;t expect to see production code, and I understand that sometimes for teaching purposes best practices will take second place - but where it wouldn&amp;#39;t hurt to use best practice, &lt;i&gt;please&lt;/i&gt; do!&lt;/p&gt;  &lt;p&gt;Likewise telling the truth from the start matters. It&amp;#39;s very hard to correct bad habits and incorrect impressions. If you state that &amp;quot;When we set &lt;i&gt;lucky&lt;/i&gt; (a variable) to null, it&amp;#39;s no longer pointing at its object, so it gets garbage collected&amp;quot; then people will not only be potentially confused about whether it&amp;#39;s the variable or the object which gets garbage collected, but they&amp;#39;ll get the impression that it&amp;#39;s garbage collected immediately. Waiting 476 pages to correct that impression is a bad idea.&lt;/p&gt;  &lt;p&gt;Public fields are another example. I&amp;#39;ve mentioned that I can see their usefulness before we&amp;#39;ve encountered properties - but even so, surely it would have been worth explaining immediately that we&amp;#39;re going to hide them as soon as possible.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;You may have gathered by now that I&amp;#39;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&amp;#39;ve done here. The fact is, I&amp;#39;ve spent a lot of today feeling deeply saddened. I wouldn&amp;#39;t be surprised to find that this is the best-selling C# book of 2008 - which means we&amp;#39;ll get a lot more people on the newsgroup with some very odd ideas about how C# works. That&amp;#39;s the trouble - I&amp;#39;ve seen what happens when people are fed the &amp;quot;structs live on the stack&amp;quot; myth. I&amp;#39;ve seen how easily people can believe that strings are value types, and that it doesn&amp;#39;t really matter if you use a StreamReader for binary data and then cast chars to bytes. It causes trouble.&lt;/p&gt;  &lt;p&gt;I&amp;#39;m reasonably sure the world could do with a good introductory book on C#. HFC# has convinced me that such a book&lt;i&gt; could&lt;/i&gt; be fun and have pretty pictures. But HFC# isn&amp;#39;t quite it. (And no, I don&amp;#39;t plan on writing it either.)&lt;/p&gt;  &lt;h3&gt;Feedback&lt;/h3&gt;  &lt;p&gt;I gave an advance copy of this review to Andrew, who has replied &lt;i&gt;remarkably&lt;/i&gt; politely and pleasantly (and quickly). He&amp;#39;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.&lt;/p&gt;  &lt;p&gt;He believes I was looking too much for a complete reference rather than an introductory text. I would say I wasn&amp;#39;t looking for completeness, but a better judge of what should be in a C# book (I&amp;#39;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&amp;#39;t want an actual reference book if I&amp;#39;m going to recommend it to people to learn from - but I may be biased towards a reference style as that&amp;#39;s what I personally tend to learn from.&lt;/p&gt;  &lt;p&gt;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&amp;#39;d only include explicit upcasting) many others are undeniable and really shouldn&amp;#39;t have made it through the review process. It&amp;#39;s possible that I&amp;#39;ll come back to HFC# in a year&amp;#39;s time and be more impressed by it, but I suspect the aversion to errors will overcome any mellowing towards the style :(&lt;/p&gt;  &lt;h3&gt;Update (22nd March 2008)&lt;/h3&gt;  &lt;p&gt;Andrew continues to amaze me in terms of taking this review in his stride. He&amp;#39;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.&lt;/p&gt;  &lt;p&gt;In short, I&amp;#39;m still not quite convinced I&amp;#39;d recommend the book, but my opinion has certainly mellowed (anticipating the error fixing, of course).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1549256" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Book+reviews/default.aspx">Book reviews</category></item><item><title>Book review/preview: "C# Query Expressions And Supporting Features in C# 3.0" (Eckel/King)</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/03/17/book-review-preview-quot-c-query-expressions-and-supporting-features-in-c-3-0-quot-eckel-king.aspx</link><pubDate>Mon, 17 Mar 2008 00:40:04 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1544662</guid><dc:creator>skeet</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1544662</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1544662</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/03/17/book-review-preview-quot-c-query-expressions-and-supporting-features-in-c-3-0-quot-eckel-king.aspx#comments</comments><description>&lt;h3&gt;Introduction&lt;/h3&gt; &lt;p&gt;Let me make one thing very clear before anything else: &lt;em&gt;this is a preview&lt;/em&gt;. Bruce Eckel has made the preview of what appears to be part of a bigger book &lt;a href="http://www.mindviewinc.com/Books/CSharp/Index.php"&gt;available free&lt;/a&gt; from his website. The book is by Bruce Eckel and Jamie King, and the preview available (1.0 at the time of writing) covers the following topics:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Extension methods  &lt;li&gt;Implicitly typed local variables  &lt;li&gt;Automatic properties  &lt;li&gt;Implicitly-typed arrays  &lt;li&gt;Object initializers  &lt;li&gt;Collection initializers  &lt;li&gt;Anonymous types  &lt;li&gt;Lambda expressions  &lt;li&gt;Query expression translation&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;For obvious reasons, this had me slightly worried when I first looked at it - it&amp;#39;s clearly a reasonably direct competitor to &lt;a href="http://www.manning.com/affiliate/idevaffiliate.php?id=876_112"&gt;C# in Depth&lt;/a&gt;. There&amp;#39;s not a lot of C# 3 which isn&amp;#39;t covered here. I can only think of these things off-hand:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Expression trees &lt;li&gt;Object initializers setting properties of embedded objects &lt;li&gt;New type inference rules  &lt;li&gt;New overload resolution rules&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I was surprised to see expression trees not get even a mention. I&amp;#39;m sure they&amp;#39;ll be covered elsewhere in the full book, but I personally think it&amp;#39;s worth introducing them at the around same time as lambda expressions. (It would be odd for me to have any other view, given the location in C# in Depth!) I don&amp;#39;t know whether the new rules for type inference and overload resolution will be covered elsewhere. If they&amp;#39;re going to be covered but the authors haven&amp;#39;t done the writing yet, we should all feel sympathy for them. That section (9.4) was the hardest one in the whole book for me. It may be possible to describe all of the rules in a way which doesn&amp;#39;t make both reader and writer want to tear their hair out, but I have yet to see it.&lt;/p&gt; &lt;p&gt;I don&amp;#39;t know exactly what the bigger book will cover, or how it will be published, or whether it will be available in preview form, etc. From here on in, when I say &amp;quot;the book&amp;quot; I mean &amp;quot;the preview bit&amp;quot;.&lt;/p&gt; &lt;h3&gt;Format&lt;/h3&gt; &lt;p&gt;After the TOC and introductory material, the book basically consists of 4 things:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Headings (occasional)  &lt;li&gt;Explanatory text  &lt;li&gt;Code  &lt;li&gt;Exercises&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;There are no diagrams or tables as far as I can see. The main body of the book (P7-137) sets exercises quite frequently (there are 54 of them), and the answers form P138-233, including brief explanations.&lt;/p&gt; &lt;p&gt;The code is always complete, including using directives, a Main method (for non-library classes) and output. A lot of the time the code essentially forms unit tests to demonstrate the features (a technique we used in Groovy in Action, by the way). The authors have their own build system which not only runs the tests, but also allows comments to express pieces of code which &lt;em&gt;shouldn&amp;#39;t&lt;/em&gt; compile. The output is also checked, i.e. that running the code produces the output in the book.&lt;/p&gt; &lt;p&gt;There are pros and cons to this approach. For those who haven&amp;#39;t read any of my book (what are you waiting for? The first chapter is free!) I personally use a tool I wrote called &amp;quot;Snippy&amp;quot; which allows me to include short but complete examples without using directives and Main declarations appearing everywhere. My comments on this book&amp;#39;s approach:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I&amp;#39;d be surprised to see any misleading/broken examples. (There&amp;#39;s one piece of code which doesn&amp;#39;t go quite as far as I believe it should, but that&amp;#39;s a different matter.)  &lt;li&gt;It encourages unit testing.  &lt;li&gt;It leads to longer code with repetition (Main etc).  &lt;li&gt;The build system leads to non-standard comments, like //c! to indicate a non-compiling line and //e! to indicate where an exception should be thrown. &lt;li&gt;There&amp;#39;s a little too much text dealing with the build system - it&amp;#39;s distracting&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The &amp;quot;long code&amp;quot; issue has been dealt with by squeezing a lot of code into short spaces - K&amp;amp;R bracing and very little whitespace. Personally I find this really quite tricky to read, to the extent that I ended up skipping a lot of the code examples. I&amp;#39;ve tried to keep all &lt;em&gt;my&lt;/em&gt; code examples pretty short, and none of them are over a page. (That was an unstated goal at the start of the project, in fact.)&lt;/p&gt; &lt;p&gt;Now, how much code do you like to see in a book? That&amp;#39;s very much a personal decision. I happen to like quite a lot of explanatory text - so that&amp;#39;s how I write, too. In this book I reckon (and it&amp;#39;s only a complete guess) about 50% of the book is code, 35% is prose and 15% is exercise. This quite possibly pose a challenge for me as a reader if I didn&amp;#39;t already know the topic. However, for other readers it&amp;#39;s probably spot on.&lt;/p&gt; &lt;p&gt;What this book &lt;em&gt;doesn&amp;#39;t&lt;/em&gt; have (fortunately) is lots of examples which go on for pages and pages, producing a complete application with little explanation. I&amp;#39;ve seen that too often - and a lot of the code simply doesn&amp;#39;t teach me anything. I&amp;#39;ve never particularly liked the &amp;quot;build a complete application&amp;quot; approach to books, partly because it doesn&amp;#39;t actually mean that all the bases are covered (you don&amp;#39;t see every issue in every app) and it &lt;em&gt;does&lt;/em&gt; mean there&amp;#39;s a lot of turn-the-handle code which isn&amp;#39;t relevant to the topic being taught. It can be a useful technique in &lt;em&gt;some&lt;/em&gt; situations, but I like it when irrelevant code is omitted (and is just available for download).&lt;/p&gt; &lt;p&gt;The other personal question is whether or not you like exercises. I certainly believe in trying out new things as you read about them, but exercises don&amp;#39;t really fill that need in an ideal way &lt;em&gt;for me&lt;/em&gt;. I like to try to apply a new technique to an existing bit of code, or an existing database for instance - and obviously the author has no way of knowing that. Now, that only says something about me, not about the value of exercises. This book has been used for teaching in a university, and I suspect the exercises have been appropriate in that setting. Note for future consideration (and reader feedback): should I include exercises in any future books I might write? Should I create some for the &lt;a href="http://csharpindepth.com"&gt;C# in Depth web site&lt;/a&gt;?&lt;/p&gt; &lt;h3&gt; Style&lt;/h3&gt; &lt;p&gt;(Some of this might reasonably count as format as well - it&amp;#39;s a blurry line.)&lt;/p&gt; &lt;p&gt;I have a consciously &amp;quot;light&amp;quot; style. I write in the first person and try to include opinion and the occasional joke or at least lighthearted comment. (Footnote 1 in chapter 3 is my favourite, for reference.)&lt;/p&gt; &lt;p&gt;Eckel and King&amp;#39;s book is more like a textbook. The authors haven&amp;#39;t allowed their personalities to come through in the text at all - and it&amp;#39;s clearly a deliberate decision. Good or bad? Hard to say - it depends on the context. The word &amp;quot;textbook&amp;quot; is the key here, for me - I can&amp;#39;t remember textbooks having any personality when I was a student, so if they&amp;#39;re going for that market it&amp;#39;s spot on. In the &amp;quot;professional developer&amp;quot; market it may have a harder time. Again, personally I&amp;#39;m a fan of a bit of personality peeping through the text - although it has to be firmly controlled, and it&amp;#39;s better to err on the side of caution. I&amp;#39;ve read some books which seem to be &lt;em&gt;all&lt;/em&gt; about the author&amp;#39;s personality, without letting the subject matter have a look-in.&lt;/p&gt; &lt;p&gt;I do think more headings (of varying sizes, if you see what I mean) and the occasional diagram would be helpful, though. It&amp;#39;s a pretty unrelenting code-text-code-text-exercise-code-text-code-text mix. The code is all just &amp;quot;there&amp;quot; with no headings, nothing to visually break things up. (It&amp;#39;s not actually run-on with the text - it&amp;#39;s clear where text stops and code starts, and there&amp;#39;s even a helpful vertical line down the side of the code - it&amp;#39;s just that there&amp;#39;s nothing to make you take a mental breath.) This could be due to it being a preview - it&amp;#39;s possible that more formatting will occur later on. If that wasn&amp;#39;t the plan, I&amp;#39;d encourage the authors to at least consider it. (Wow, see how easy it is to slip into arrogance? Must make a memo to give Joel Spolsky some notes on writing later ;)&lt;/p&gt; &lt;h3&gt;Content&lt;/h3&gt; &lt;p&gt;The content is pretty full-on, and &lt;em&gt;very&lt;/em&gt; language-focused. As an example, I suspect few books on C# 3 will go into any detail about transparent identifiers in query expressions. In my book I explain them for one particular clause (&amp;quot;let&amp;quot;) and then just mention when the compiler will introduce one for other clauses. Eckel and King&amp;#39;s book gives &lt;em&gt;full&lt;/em&gt; exampes of translation for all the clauses available, as far as I can tell.&lt;/p&gt; &lt;p&gt;That&amp;#39;s just an example - and possibly an extreme one - but this book does go into a reasonable amount of depth when it comes to the facts. (There were also two items I wasn&amp;#39;t aware of: the option of &lt;a href="http://csharpindepth.com/ViewNote.aspx?NoteID=93"&gt;explicitly stating that an ordering is ascending&lt;/a&gt;, and the ability to create &amp;quot;&lt;a href="http://csharpindepth.com/ViewNote.aspx?NoteID=92"&gt;extension delegates&lt;/a&gt;&amp;quot;. They&amp;#39;re not huge omissions in my text (and at least I&amp;#39;ve now got notes for them), but the fact that I missed them and these guys didn&amp;#39;t is (to me) an indication of their thoroughness.&lt;/p&gt; &lt;p&gt;Now, having dealt with the plain facts, there&amp;#39;s not a lot of &lt;em&gt;opinion&lt;/em&gt; in the book - pieces of text which encourage the reader to think about &lt;em&gt;why&lt;/em&gt; C# has changed the way it has, or the best way to take advantage of those changes. Again, this is a valid approach for a textbook - especially one used in conjunction with a course where the lecturer can talk about these things - but I suspect the non-academic market likes guidance.&lt;/p&gt; &lt;p&gt;The accuracy level seemed pretty high to me. Not perfect, but then I don&amp;#39;t expect mine is either, even with Eric&amp;#39;s thorough eye. In everyone&amp;#39;s interests, I&amp;#39;ve mailed the authors my specific comments and nitpicks - as the book is still at a preview stage, corrections can be made relatively easily, I expect.&lt;/p&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;Obviously I can only comment on the book as I&amp;#39;ve seen it so far - I&amp;#39;ve no idea whether the other chapters will be more framework-focused. However, it&amp;#39;s good to see another book that tries to &amp;quot;go deep&amp;quot; like mine does. While this clearly makes it competition in many ways, I think we&amp;#39;re aiming at different audiences. If I&amp;#39;m right in my assumption that this is trying to be a textbook, there may be little overlap in potential market. (I suspect the same will be true of Head First C#, which is likely to be my next review - but for the opposite reason. I suspect I&amp;#39;ll find that HFC# is more aimed at beginners - something that certainly couldn&amp;#39;t be said of this book or mine.)&lt;/p&gt; &lt;p&gt;Overall this is a very solid text, in many senses. It&amp;#39;s not the easiest book to follow due to its style, but it&amp;#39;s detailed and accurate. Given a choice between the latter and the former, I&amp;#39;d always choose the latter for anything I&amp;#39;d want to refer back to - and this book certainly counts as a good reference for query expressions. Obviously I&amp;#39;m hoping people find my style appealing &lt;em&gt;and&lt;/em&gt; that I&amp;#39;m detailed and accurate, but I can&amp;#39;t give that judgement.&lt;/p&gt; &lt;p&gt;As a final word - if you haven&amp;#39;t downloaded it yet, why not? It&amp;#39;s a totally free download of only just over a meg. I don&amp;#39;t think I even had to register anywhere to get it. Reading other work is useful for me as a writer, but there&amp;#39;s no need for you to trust my judgement, nor indeed would it be wise to do so. If you missed it before, I&amp;#39;ll even save you scrolling up for the &lt;a href="http://www.mindviewinc.com/Books/CSharp/Index.php"&gt;download link&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;I&amp;#39;d be interested to hear whether your opinions coincide with mine. If you&amp;#39;ve read my book and can compare and contrast, so much the better. I&amp;#39;ve let the authors know that this review is coming, so I suspect they&amp;#39;ll be checking here for feedback. (They&amp;#39;d be foolish not to, and I have no reason to believe they&amp;#39;re fools.)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1544662" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Book+reviews/default.aspx">Book reviews</category></item></channel></rss>