Skip to content

Latest commit

 

History

History
223 lines (145 loc) · 14.8 KB

File metadata and controls

223 lines (145 loc) · 14.8 KB

Errata (15 items)

If you find any mistakes, then please raise an issue in this repository or email me at markjprice (at) gmail.com.

Warning! Avoid copying and pasting links that break over multiple lines and include hyphens or dashes because your PDF reader might remove a hyphen thinking that it being helpful but break the link! Just click on the links and they will work. Or carefully check that your PDF reader has not removed a hyphen after pasting into your web browser address bar. See an example of this issue here.

Online docs

Thanks to Donald Maisey for raising this issue on January 12, 2026.

The link to an online topic about async/await was moved in the book from Chapter 2 to Chapter 4, but the online files and link were not. These have now been moved to where they should be. Also, some links to online topics were missing from the docs README.md file. These have now been added.

Page 12 - Installing other extensions

Thanks to Eduardo Almeidabr for raising this issue on April 19, 2026.

Table 1.1 VS Code extensions for .NET development includes a row for Polyglot Notebooks ms-dotnettools.dotnetinteractive-vscode, and Polyglot Notebooks are referenced in two other sections of the book, Explore Polyglot Notebooks on page 38, and C# 101 notebooks on page 169.

However, in February 2026, the .NET Interactive team officially announced the deprecation of this extension:

  • The Polyglot Notebooks Extension became deprecated on March 27th, 2026.
  • .NET Interactive became deprecated on April 24th, 2026.

The team knows notebooks are very unique and nothing can directly replace a notebook. However, for the use case we are continuing to invest in (a lightweight scratch pad for quick experiments, testing code, trying NuGet packages, etc.) file-based apps will provide that path going forward.

Important notes:

  • The Polyglot Notebooks extension will not be disabled or uninstalled from your VS Code.
  • You can continue using the extension as is after its deprecation date if you don't uninstall it, but future VS Code updates may eventually break it.
  • No new features will be added to Polyglot Notebooks or .NET Interactive.
  • Bugs for Polyglot Notebooks or .NET Interactive will not be fixed.
  • Any security vulnerabilities reported for both Polyglot Notebooks and .NET Interactive after their respective deprecation dates will not be addressed.

Recommended Action: Uninstall the Polyglot Notebooks extension and/or uninstall .NET Interactive from your machine once you've migrated to another solution.

In the next edition, all references to Polyglot Notebooks will be removed.

Page 70 - Raw string literals

Thanks to Paul Marangoni for raising this issue on November 19, 2025.

In the book, the following example is wrong:

Wrong indentation for final quotes

It should be:

Correct indentation for final quotes

Page 71 - Raw string literals

Thanks to mushobeti for raising this issue on November 29, 2025.

The following code example mistakenly indents the last three-quotes by one space:

string json = $$"""
{
  "first_name": "{{person.FirstName}}",
  "age": {{person.Age}},
  "calculation": "{{ 1 + 2 }}"
}
 """;

This causes the compiler to give Error CS8999: Line does not start with the same whitespace as the closing line of the raw string literal.

To fix this error, delete the extra space at the start of the last statement, as shown in the following code:

string json = $$"""
{
  "first_name": "{{person.FirstName}}",
  "age": {{person.Age}},
  "calculation": "{{ 1 + 2 }}"
}
""";

This code example was correct in earlier editions so must have been accidently introduced during the editing process. I apologize for missing it.

Page 84 - Storing dynamic types

Thanks to iheartdotnet for raising this issue on August 2, 2025 and to Chris Alberty for noticing that I had missed fixing it in the 10th edition.

In the last paragraph of this section, I wrote, "Dynamic types are most useful when interoperating with non-.NET systems. For example, you might need to work with a class library written in F#, Python, or some JavaScript. You might also need to interop with technologies like the Component Object Model (COM), for example, when automating Excel or Word."

I included F# in the list of languages after giving the example of dynamic being useful when interoperating with non-.NET systems. This accidently implies that F# is not a .NET language when it is. In the next edition, I will change "non-.NET systems" to "other .NET languages and non-.NET systems".

Page 88 - What does new do?

Thanks to CalebFord who raised this issue on March 31, 2026.

I wrote, "Consider the following code, which declares some local variables:"

short age; // Allocates 2 bytes of memory on the stack to store a System.Int16 value.

Below the code block I wrote, "Note the following about the preceding code:

  • age has a value of 0 and 2 bytes of memory have been allocated in stack memory"

But value-type variables that you have not explicitly set are uninitialized because they do not officially have a value yet, even though internally they will have a value of zero. To protect you from assumptions, the compiler will show an error like Use of unassigned local variable 'age' if you try to access the variable.

In the next edition, I will change the bullet to read:

  • age has not been assigned a value (so the compiler with show an error if you attempt to access it) and 2 bytes of memory have been allocated in stack memory

Page 103 - Getting key input from the user

Thanks to mushobeti for raising this issue on November 30, 2025.

In Steps 2 and 4, the output of the Modifiers should be None instead of 0. To output the integer value of the Modifiers enum, we would use arg2: (int)key.Modifiers.

Page 317 - Comparing objects when sorting

Thanks to Nick Johnston for raising this issue on December 27, 2025.

In Step 5, I wrote, "In Person.cs, after inheriting from object, add a comma and enter IComparable<Person?>,"

Inheriting from object was shown in Chapter 5. I should have written, "In Person.cs, after Person, enter : IComparable<Person?>," and the code highlighting should include the colon.

Page 319 - Implicit and explicit interface implementations

Thanks to Clint Mayers who emailed me about this issue on May 20, 2026.

In the code example, I wrote comments about explicit interfaces:

// Explicit implementation can be any access modifier.
void IGamePlayer.Lose() // Defaults to private.
{
  // Implement losing a game.
  WriteLine("Implementation for losing a game.");
}

After the code example, I added some notes:

Although the implementation of IGamePlayer.Lose in Human is private, the IGamePlayer.Lose member itself has an access modifier of public, so if we cast the Human instance into the interface type, then that Lose implementation is accessible.

Warning! Method access modifiers in an implementation type must match the method definition in the interface. For example, the Lose method in the interface is public, so the method implementation in the class must also be public.

But what I wrote is confusing because you cannot set any modifier on explicit interfaces. As Microsoft say, "An explicit interface implementation doesn't have an access modifier since it isn't accessible as a member of the type it's defined in. Instead, it's only accessible when called through an instance of the interface. If you specify an access modifier for an explicit interface implementation, you get compiler error CS0106." This is what I clumsily tried to say in my first note.

In the next edition, I will rewrite this section, and include a link to the official documentation: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/explicit-interface-implementation

Page 515 - Understanding Entity Framework Core

On February 10, 2026, the EF Core team published packages for EF Core 11 Preview 1, and a page for what's new: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-11.0/whatsnew

It includes an important note: "EF11 requires the .NET 11 SDK to build and requires the .NET 11 runtime to run. EF11 will not run on earlier .NET versions, and will not run on .NET Framework."

In my book, I wrote: "EF Core 10 targets .NET 10 or later, and EF Core 11 will also target .NET 10 because the EF Core team wants as many developers as possible to benefit from new features in future releases, even if you must target only long-term support releases of .NET. This means that you can use all the new features of EF Core 11 with either .NET 10 or .NET 11."

In the past, the EF Core team often targeted the latest LTS .NET so you could adopt the new EF Core STS version without moving your whole app runtime. Microsoft’s own “Supported .NET implementations” page even states that as the general approach: “In general, we target the latest LTS release of .NET… There may be exceptions… as runtime features sometimes get added that require us to depend on the latest version of .NET.” From: https://learn.microsoft.com/en-us/ef/core/miscellaneous/platforms

But EF Core 11 is now explicitly saying that it requires the .NET 11 SDK to build and the .NET 11 runtime to run, and it won’t run on earlier .NET versions.

Why? The EF team’s own platform guidance acknowledges that sometimes they must depend on the latest .NET due to runtime features. In practice, “won’t run on earlier .NET” usually means they’re compiling against and taking dependencies on assemblies/APIs that simply are not present (or not the same versions) on earlier runtimes, and the team has decided not to carry the extra compatibility shims or multi-targeting.

Net result: EF Core 11 only running on .NET 11 is the documented requirement. If you want to stay on .NET 10 LTS, EF Core 10 is the ceiling. If you move to .NET 11 (STS), EF Core 11 becomes available.

Page 521 - Managing the Northwind sample database with SQLiteStudio, Page 628 - Creating the Northwind database

Thanks to Amar Jamal for raising this issue on November 4, 2025.

On page 521, in Step 6, I wrote, "You will see the 10 tables..." but there are only 8 tables. For many editions there were 10, but recently I simplified the script to only create 8 tables by removing the unneeded Territories and EmployeeTerritories tables.

On page 628, I wrote, "The script for SQLite is a simplified version that only creates 10 tables..." Again, this should be 8 tables.

Page 677 - Using shared layouts with Blazor static SSR pages

Thanks to Amar Jamal for raising this issue on November 19, 2025.

In Step 3, the markup includes the following to link to the Suppliers page:

<NavLink class="nav-link" href="suppliers">
  Suppliers
</NavLink>

To prevent broken links, it would be better to use a forward-slash / prefix for the href, as shown in the following link:

<NavLink class="nav-link" href="/suppliers">
  Suppliers
</NavLink>

The same applies when you add a link for the Customers page in Exercise 13.2.

Page 710 - Abstracting a service for a Blazor component

Thanks to Amar Jamal for raising this issue on December 3, 2025.

In Step 6, the existing reference to the data context project starts the path with ..\ when it should be ..\..\, as shown in the following markup:

<ProjectReference Include="..\..\Northwind.DataContext.Sqlite\Northwind.DataContext.Sqlite.csproj" />

Page 735 - Creating an ASP.NET Core Minimal API project

Thanks to hungvuongvo for raising this issue on February 22, 2026.

In Step 4, I wrote, "Build the Northwind.WebApi project." And then in Step 5, I tell the reader to remove the Version attribute from the package. These steps should be swapped otherwise you will get a compile error on Step 4.

Appendix B - Setting Up Your Development Environment

Page 833 - Creating the Northwind sample database locally

Thanks to José Luis García for emailing me about this on November 16, 2025.

In Step 7, Northwind4SQLServer.sql should be Northwind4SqlServerLocal.sql.