It's dangerous to code alone! Take this.

Errata - 5th Edition

[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 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 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.

[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…

[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. This does, technically, compile, and it could work. But it makes more sense for these to match types, given that the indexer is sort of “overlaid” on the top of the normal properties. You could make the properties use double or the indexer use int, but I remember changing the type here to make it abundantly clear that the indexer’s return type and the type for the index itself do not need to match. So I think, to fix the consistency issue while still showing that, it would be better for the First and Second properties to look like this:

public double First { get; set; }
public double Second { get; set; }

[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:

    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.