Worst. Best Practices Book. Ever.
As you may or may not know, I generally critisize things on a daily basis. But this post is much different than my normal (hopefully witty) commentary on bad code. Today I'm pointing out some serious flaws in a book I came acrossed called Practical Guidelines and Best Practices for Microsoft Visual Basic and Visual C# Developers that make the book not only bad (which I can live with) but dangerous for an inexperienced developer. Not only does it fall short of "best practices," but it actually advocates bad practices. In summary, DO NOT BUY THIS BOOK. And if an enlarged & emboldened statement isn't enough, read on ...
Although Balena and Dimauro are MSDN Regional Directors (a prestegious title, I think), they are no where near "IT legend" status (unlike Don Knuth [pdf], Andrew Tanenbaum, Ed Yourdon, etc.). You would think they would supplement their lack of credibility with cold hard facts and research, but no, they just seem to make up arbitrary figures (pp 139, "avoid methods longer than 50 executable statements") and shove them in the book. And what's with 50? Why not 60? Why not 45? Look at a good book (Code Complete by Steve McConnell') and see that Steve backed up his best practice on method length with six different studies. SIX!! You won't find a single reference in this book.
On to the content, the authors use the words "always" and "never" way too much. The architects behind the .NET Framework didn't put in "forbidden fruit" that looks tempting but should never be used. For example, on page 325, they say that you should never catch the ThreadAbortException. What they don't mention is that catching ThreadAbortException (and ThreadInterruptedException for that matter) is the *only* way to gracefully clean up and exit from a sleeping background thread using unmanaged resources. This happens more often than you'd think; if you're interfacing directly with specialized hardware that takes a long time to do process (like a printer), you would put that in a background thread that waits for the printer to finish. If the user closes the application (and the background thread doesn't catch the Thread exceptions), you're hardware could be hung up.
Another example, on page 191: "All events must define two parameters. The first parameter is an Object named sender; the second parameter is an instance of the EventArgs type (or a type that derives from EventArgs) and must be named e." Wrong, wrong, wrong! An event can have any number parameters of any type with any name. That may be the way *most* events are handled, but it's certainly not what you *must* handle events. A lot of times there is no need for a sender reference or event arguments.
They also seem to really like the words "right"/"wrong" and "correct"/"incorrect". Let's take a look at page 140:
' *** Wrong: uses incorrect casing, type is embedded in parameter name.
Sub PerformTask(ByVal UserName as String, ByVal boolIsAdmin as Boolean)
' *** Correct
Sub PerformTask(ByVal userName as String, ByVal isAdmin as Boolean)
Their way is neither correct nor incorrect. It's simply a preference, it also happens to be the same preference that Microsoft spells out in MSDN, but they actually use the term "preference." Ironically, on the very next page (pp 141), they use a class named "frmMain." This is one of many examples where their preference doesn't line up with Microsoft's preference. MSDN prefers MainForm.
Next, the authors focus on "speed and efficiency" as if it's 1963 and a few CPU hours cost as much as a car. In the world of BILLIONS (1,000,000,000's) of cycles per second (Ghz), it really is ok to "waste" a few cycles on making sure your code is easier to read and maintain. You wouldn't get that impression from reading this book as a beginner:
pp 127: "the as operator ... speeds up execution"
pp 149: "Return keyword enables the compiler to optimize your code more efficiently."
pp 251: "language specific functions perform worse"
pp 253: "the ChrW function is faster"
pp 257: "the CompareOrdinal static method ... is typically faster"
They did not drive the point of maintainability over speed. 100 clock cycles will make ZERO difference on a 10 millisecond request.
I've also found that some parts of the book are hopelessly out of date. It would appear that the authors have not yet fully entered the world of .NET themselves. Take for example page 408, where they provide a rather "Classic ASP" method of setting the page title: <title><%=GetTitle()%></title>. The ".NET" way of doing this would be either using a literal <title><asp:literal id=pageTitle runat=server></title>) or making the title tag a server tag (<title runat=server id=Title/>).
It would also appear that the authors have little to no knowledge of relational database design. On page 380 they say "Don't use primary keys that have meaning for the end user, such as invoice number or the ISBN value." This is beyond absurd and defeats the whole purpose of "relational databases". Don't take my word for it, of course; ask any "Database 101" student or read it straight from the creators of relational databases (EF Codd and CJ Date). The authors' technique is as close to a COBOL-mainframe-flatfile method of development you can possibly get and is, ironically, what relational databases were designed to fix.
And on top of all of this, they're inconsistent in following their own "best practices." On page 251 they say "don't use Visual Basic-specific string functions, such as Len, Left, and Mid." Flip the page (pp 253) to another tip and see "favor the ChrW function over the Chr function." No mention about using "Convert.ToInt16," which they suggested as a replacement just on the previous page. And speaking of using "Int16", they didn't follow their own advise of "Use 32-bit integer variables" as suggested on page 240. And why int32? Because they're faster!
I really do hate to be so negative about this book. Yes, it does have some decent tips that will help an inexperienced developer. But at the same time it has some absolutely horrendous tips and there is absolutely no way that an inexperienced developer could distinguish between the good and bad. Stay clear of this book. Buy McConnel's Code Complete instead.