Errata - 5th Edition
[TYPO] Acknowledgments: Extra “that”
A minor typo (grammar-o), but in the acknowledgments, it says:
I might have even called this edition 4.1 if that were that a thing books did.
That that should be removed and it should just say:
I might have even called this edition 4.1 if that were a thing books did.
[TYPO] Page 30: Extraneous )
On page 30, there’s the following sentence:
The second example is awkward but has its uses, such as when commenting out code that you want to ignore temporarily).
The )
is a mistake, and shouldn’t be there.
[TYPO] Page 43: Extraneous )
On page 43, there’s this sentence:
The console window doesn’t even know how to display the baseball character above.)
The )
should not be there.
[CORRECTION] Page 44: Smallest size of a float
The prose on this page states:
A
float
can store numbers as small as 3.4×10⁻⁴⁵…
In the table farther down the page, it indicates that the smallest it can store is 1.0×10⁻⁴⁵.
The table is correct, and the prose is wrong.
(Though the practical scenarios where this difference matters is virtually non-existent.)
[TYPO] Page 44: Missing “the end”
The text reads:
Appending an
m
orM
onto makes it into adecimal
literal.
That should read:
Appending an
m
orM
onto the end…
[TYPO] Page 63: Extra comma
The section called The Write Method begins with this:
Aside from
Console.Write
, another method calledWrite
, does all…
The second comma is misplaced.
[CORRECTION] Page 72: Incorrect sentence about scope
There is a sentence that says:
If we want to use
grade
outside of the method, we must declare it outside of the block.
This inadvertently refers to methods. It should only refer to blocks and should say:
If we want to use
grade
outside of the block, then we must declare it outside of the block.
[TYPO] Page 79: Missing semicolon
In the Speedrun, the default
code is missing a semicolon after DoStuff()
and should be:
default: DoStuff(); break;
[SIMPLIFICATION] Page 82: Made all costs divisible by 2
I’ve worked with enough people on the Buying Inventory and Discounted Inventory challenges to have found a problem that people struggle with that isn’t worth the struggle: dealing with items that cost an odd amount of gold (in the mathematical sense) and struggling with how to deal with it when giving a 50% discount in Discounted Inventory.
When rope costs 15 coins, do you use integer division and charge 7 gold? Or do you charge 8 gold? Or do you use floating-point division? If you use floating-point division, is it actually correct to use fractional gold? There is no indication that you can work with fractional values. If you stick with integer division, then what about the items that cost only 1 gold (water and food)? Those end up costing 0 gold!
These questions have been asked by readers on multiple occasions.
Ultimately, the point here isn’t about nitpicking the costs, but about being able to apply switches to a problem. It is also about being able to extend a program into something a little bigger.
You can handle these questions in any way you want, and it will be fine, since it is outside of the goals of the challenge.
However, my suggestion is to just make all the costs multiples of 2 and sidestep the issue entirely. This is the approach I plan on applying in future updates to the book.
Torches become 16 gold, climbing equipment is 24, food supplies are 2, and clean water is 2.
[TYPO] Page 174: Minor extra word
At the bottom of the first page in Level 22, there’s a sentence that reads:
You have probably not have encountered it yet…
There’s an extra “have” in there, and it should read:
You have probably not encountered it yet…
[TYPO] Page 177: Minor typo or grammar mistake
In the Null Coalescing Operator section, there is a sentence that reads:
It takes an expression that might be null and provide a value…
That’s missing an ‘s’ on “provides”:
It takes an expression that might be null and provides a value…``
[TYPO] Page 205: “Ad properties to Pack
”
One of the objectives in the “Packing Inventory” challenge starts with:
Ad properties to
Pack
…
It should be:
Add properties to
Pack
…
This looks like it might have been a typo added in 5.0.1 somehow, because the 5.0.0 print edition does not show it.
[TYPO] Page 218: Extra )
There is an extra )
at the end of the sentence that says:
You can add fields, properties, methods, and constructors, along with some other member types we have not discussed yet).
[MINOR CORRECTION] Page 230: Record struct properties
In the section called Struct- and Class-Based Records is the following sentence:
A record struct creates properties slightly different from class-based structs.
The context makes it relatively clear what the intent here is, but this should actually say:
A record struct creates properties slightly different from class-based records.
There’s no such thing as a class-based struct; the two are mutually exclusive.
[CORRECTION] Page 249: Erroneous direction in the Robot Pilot challenge
In the Answer this question part of this challenge, it asks:
How might you use inheritance… to allow the game to be either a single player (the computer randomly chooses the starting location and direction) or two players (the second human determines the starting location and direction)?
There was a time in early access (of 4th Edition) where the Hunting the Manticore challenge allowed the Manticore to move. But that did not make it into the final version because it made things more complicated than I had wanted. It was removed in the Hunting the Manticore challenge, but was not cleaned up here, half the book later.
Ignore the direction entirely, and focus on just the location.
[TYPO] Page 250: TotalMillseconds
The book says:
Another set of properties capture the entire timespan in the unit requested: …
TotalMillseconds
.
“Millseconds” is misspelled and the correct name of this property is TotalMilliseconds
.
[TYPO] Page 264: Missing “in”
There is a sentence which reads:
But most of the types we have used… all live specific namespaces.
This is missing an “in” and should read:
But most of the types we have used… all live in specific namespaces.
[TYPO] Page 264: Repeated Random
There’s a sentence that is listing the things in System
that happens to list it twice:
The
System
namespace contains the most foundational and common types, including…Math/
MathF,
Random,
Random,
DateTime`…
There obviously only needs to be a single occurrence of Random
.
[TYPO] Page 268: “its” should be “their”
There is a sentence which reads:
Aside from the file containing your main method, most files lump all of its types…
This should be:
Aside from the file containing your main method, most files lump all of their types…
[TYPO] Page 290: “Exepti’s Game”
The title of the challenge, “Excepti’s Game” is misspelled as “Exepti”. It’s a made-up word that shouldn’t matter at any practical level, but for consistency, this should be “Excepti’s Game” instead.
[TYPO] Page 296: ThingHappend
In the Speedrun, there is code that refers to a ThingHappened
event that, in one spot, leaves out an e
, and just says ThingHappend
. This should be ThingHappened
, to get it to compile correctly.
[CORRECTION] Page 323: Usage of type pattern instead of declaration pattern
In the section about the is
keyword, there is a code block followed by a comment that says:
We are not just limited to the declaration pattern…
Except the example is actually of the type pattern instead.
We are not just limited to the type pattern…
The philosophical point that all patterns can be used with is
is still correct.
[CLARIFICATION] Page 327: Types involved in the indexer
In the printed version of the book, the properties, First
and Second
are of the type int
, while the indexer’s type is double
.
The mismatch in types makes this code not compile.
To fix it, either (1) the properties need to be changed to double
to match the indexer’s type, (2) the indexer needs to be changed to an int
to match the property type, or (3) there needs to be a cast to convert double
to int
.
I don’t like that third option (losing data if you use the indexer, but not if you use the property seems wrong). The other two are both reasonable.
I got into this mess in the first place by intentionally picking a second type that wasn’t int
to reduce confusion about types. The type of the indexer itself and the type of the indexing variables (like index
) do not need to match. So to complete the change, I like changing the First
and Second
properties to be double
, like this:
public double First { get; set; }
public double Second { get; set; }
That change should be sufficient to get it to compile, while also showing that it is possible for an indexer to have a type of double
(or anything, really) while its indexing variables (like index
) can be other types. They don’t need to match.
[CORRECTION] Page 328: Inconsistency of names of index variable
In the example that uses a char
for the index type, the setter is using a variable called name
that doesn’t exist.
This was meant to be the index variable letter
.
This could be fixed by changing the setter to this:
set
{
if (letter == 'a') First = value;
else Second = value;
}
It could alternatively work to change the index variable to be called name
, and update the getter to match.
(I’m not sure I see a compelling reason to pick name
over letter
or vice versa. Neither is a great name, but that comes with the territory when you’re writing overly-general purpose code merely for illustrative purposes.)
[CLARITY] Page 337 and 339: Integer and floating-point division
As the book defines it, the types used in most of these samples use int
for HP
and MaxHP
.
The samples on page 337 and 339 perform division between these.
However, this will be integer division, resulting in a value of 0 unless HP is somehow above MaxHP
or below 0, which doesn’t make sense.
While this is largely irrelevant to the material being covered in this chapter, to be more correct, it would make sense to cast HP
, MaxHP
, or both to a float
or a double
so that you can actually get fractional values like 0.8 or 0.22.
The alternative would be to make MaxHP
and HP
use a float
or double
to get floating-point division automatically.
I expect future editions of the book will use the second solution, even though you wouldn’t typically think of hit points as being something that supports fractional values. That’s because these divisions are a part of a very complex expression, and injecting casts into the middle makes it even more cumbersome. I’d rather avoid complexity in these code samples that doesn’t directly support the material being covered.
[CORRECTION] Page 362: text += Math.PI;
actually works
In an attempt to point out that dynamic
variables are not checked at compile time but invalid operations will be caught at runtime, I inadvertently picked the line below, which actually works without an exception:
text += Math.PI;
text
’s type is dynamic
, but strings support +=
because they support +
.
This results in string concatenation, rather than arithmetic, but contrary to what the book states, this does not throw an exception.
I got unlucky in what I picked.
Strings don’t support other math operations.
So imagine this text says text -= Math.PI;
instead of the +=
, and you’ll get the exception the book predicts.
[TYPO] Page 377: “world Attribute
”
In the Attributes are Classes subsection, it says “Their names typically also end with the world Attribute
.” This should say, “… end with the word Attribute
” instead.
[SIMPLIFICATION] Page 451: Removal of first question in the knowledge check
The first question in the knowledge check asks if it is possible to attach a debugger in release mode.
The answer to this is that, yes, you can, but it results in a degraded debugging experience, and is probably not something you really want in most cases.
The catch is that this chapter doesn’t actually explain that! Which makes it a poor question for and end-of-chapter knowledge check.
I’ll be removing this question in future updates, leaving the knowledge check with just the last two questions. You should feel free to skip this question yourself.
Submit a Problem
If you think you may have found an error (large or small) in the C# Player’s Guide, please let me know about it so that I can get it fixed.
One great approach is to submit an issue or discussion on the book’s GitHub page.
Other ways to reach out are found on the contact page, and they will all get the job done as well.