It's dangerous to code alone! Take this.

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 or M onto makes it into a decimal literal.

That should read:

Appending an m or M onto the end…

[TYPO] Page 63: Extra comma

The section called The Write Method begins with this:

Aside from Console.Write, another method called Write, 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.