While the advice is generally sound, I would not recommend this book.
Disappointments require expectations, and I admit, what I describe as this book's failures are partially my own. But before I belabor my own mental state, I try to summarize the good parts:
If you are not (yet) an experienced programmer, but know the basics, and have some C# experience, but not much, this book might help you avoid some gotchas which would otherwise have taken painful experience to learn about.
If you are an experienced C# programmer and know "CLR via C#", and you have as bad a memory like I do, you will find one or two points you might already have forgotten.
I personally (re-)learned: a trick using side effects in exception filters, interpolated strings degrade to 'string' instead of 'formattable' left of a '.' operator (wtf), interpolated strings box all their arguments, and all lambda expressions within a method are translated to a single capturing closure (really big WTF?!). This list is complete.
Doesn't sound too bad; I'd say I'm still the target audience.
But. (Now comes the part where I become overly or even unfairly negative).
I would have to lie saying that the two to six hours required to read this book are well spent. If you are a fast or voracious reader, go for it, but keep in mind that the good nuggets are well hidden. Why? The big part is bad editing, a good deal are bad examples, and then there's still insufficient content.
Readership: What's the target audience? It contains pages over pages for obvious basics, but then mentions subtle perils in nothing more than a remark of half a paragraph, without further explanation. So we get almost seven pages arguing for using `var`, but only "the logic in the compiler that determines whether it should create a `string` or a `FormattableString` would create a `string` instead of a `FormattableString` when the result is the left side of the "." operator", plus some pseudo-explanation that doesn't explain the reasoning behind the language team's choice at all.
Structure: This information about the extension method is important; in an in-house tutorial I've seen code -- and implicitly acknowledged it as correct -- that is actually wrong because of this behavior. And I'd almost have missed this rule, because it was hidden within two pages of boring public API doc copy. Why not a rule "Do not use FormattableString as `this` parameter for an extension method". Of course, the number of pages for a single guidelines is a free parameter, but some choices can be counterproductive.
Editing: The example sentence above (about the formattable string, again) provides a glimpse. It is notoriously difficult to be both precise and compact and have a fluent sentence structure, but I would have hoped that Addison-Wesley would provide support to make it work on their "Effective ... Series". Alas, no. We software engineers deserve good writing no less than detective story readers, or so I hope. A publishing house should take care of that.
Code Examples: This book will get an errata addendum for its code samples as long as all of them taken together. I exaggerate, of course, but less than you might hope. Sometimes code is repeated, interjected too early, or does not show the differences that are explained in the text. I soon started ignoring the code examples **completely**. _If_ you write a book that will also be approached by novices (or tired professionals at night for their self-education), you better don't confuse them with incorrectly copy-pasted code.
Code Examples, part 2: Code formatting in books is always a challenge, but this book's result is a new low (for me). Code Conventions introduced early are not used. The choice of coding style is practically unseen, because it would not work with Visual Studio's IntelliSense at all, for example placing the '.' of Linq methods at the end of a line, and starting with the plain method name in the next.
Obsolete interjections: If a new edition has been created not only to incorporate new language versions, but also to adapt to "the new world" where a reference to C++ is obsolete, why assume the reader knows about COM and details of its reference counting?
Examples: A good example (easy to understand, illustrating the point, and seen in real-world code) of showing the difference (and only that) between returning error values vs. throwing exceptions would be `dict[key]` vs. `dict.TryGetValue()`, and explain the relationship between post-conditions and return values. A bad example would be comparing apples with oranges, like in `File.Exists()` vs. `File.Open()`.
Missing stuff: For some reason, Effective C++ explained C++ specific issues so well that it also made you a better software developer in any language. Here, the author obviously has all the knowledge in his brain, but for some reason, most expositions w.r.t. design and code style choices are not enlightening for the reader -- ok, well, me. Learning how to avoid the pitfalls of C#'s and .NET's history is all it is. This is written on the cover of the book, so it's not really a valid complaint. But on the other hand, other books manage, and this one isn't a GC implementation deep dive, so ... whatever.
I have more complaints (free-form jumps between "good code" and "bad code", for instance...), but I think I already overdid it with this review.
I have become a grumpy old man, complaining about everything, and talking about the good old times where "Exceptional C++" was ruling the world, followed by "Practical Common Lisp" and "CLR via C#". Maybe the books back then were just as bad as the books are now, but the hell I don't think I would have grokked "strong exception safety" from that kind of exposition that Effective C# tried to throw at me.
I hope that publisher and author re-evaluate the effort that good writing needs, bite the bullet, and provide a reworked edition.
But for this edition, as it is, verdict: Avoid.