Skip to content

Everyday C#: Null safety tutorials#53542

Open
BillWagner wants to merge 21 commits into
dotnet:mainfrom
BillWagner:null-safety-tutorials
Open

Everyday C#: Null safety tutorials#53542
BillWagner wants to merge 21 commits into
dotnet:mainfrom
BillWagner:null-safety-tutorials

Conversation

@BillWagner
Copy link
Copy Markdown
Member

@BillWagner BillWagner commented May 4, 2026

Fixes #52838

If you review commit-by-commit, the 4th commit is updating links, and can be skimmed.

Note for reviewers

The following files had the major changes. Others were updating links:

  • docs/csharp/fundamentals/null-safety/nullable-reference-types.md (Markdown, Preview)
  • docs/csharp/fundamentals/null-safety/resolve-warnings.md (Markdown, Preview)
  • docs/csharp/advanced-topics/update-applications/nullable-migration-strategies.md (Markdown, Preview)
  • docs/csharp/fundamentals/tutorials/nullable-reference-types.md‎ Markdown, Preview

Note that the migration strategies moved out from fundamentals. It's not meant for new C# developers.

Plan: PR 9 — Null safety: NRT, warnings, migration, tutorial

Consolidate the existing NRT concept article + tutorial into a fundamentals-style concept + tutorial pair, and split nullable-migration-strategies.md into two new fundamentals concept articles. Add redirects, update docs/csharp/toc.yml. Depends on PR 8 (#53509) landing the Null safety toc node first.

Phases

Phase 1 — Concept articles (parallel-safe)

  1. fundamentals/null-safety/nullable-reference-types.md — apply template-concept.md. Body from docs/csharp/nullable-references.md, with conceptual prose lifted from the existing tutorial. 4-tier audience tip, ms.topic: concept-article, ai-usage: ai-assisted. All code via :::code::: snippet refs.
  2. fundamentals/null-safety/resolve-warnings.md — concept article. Pull "Understand contexts and warnings" / "Address warnings" / "Enable type annotations" / "Attributes extend type annotations" sections from docs/csharp/nullable-migration-strategies.md. Frame as 5 resolution techniques with worked examples (NOT a per-CS86xx catalog). Cross-link to docs/csharp/language-reference/compiler-messages/nullable-warnings.md for per-warning lookup.
  3. fundamentals/null-safety/migration-strategies.md — concept article. Pull "Plan your migration" / "Next steps" / intro from docs/csharp/nullable-migration-strategies.md. Cover the four default-context strategies and recommended phased order.

Phase 2 — Tutorial (depends on Phase 1 cross-links)

  1. fundamentals/tutorials/nullable-reference-types.md — apply template-tutorial.md. Source: docs/csharp/tutorials/nullable-reference-types.md. Restructure to template (checklist, Prerequisites, numbered task H2s, "Get the code", "Next step"). Trim concept-duplicating prose; replace with cross-links.

Phase 3 — Snippets (parallel-safe with Phases 1–2)

  1. New snippet projects under docs/csharp/fundamentals/null-safety/snippets/{nullable-reference-types,resolve-warnings,migration-strategies}/. Each minimal .csproj, <Nullable>enable</Nullable>, latest TFM. Build + execute per docs copilot-instructions.md.
  2. Move docs/csharp/tutorials/snippets/NullableIntroduction/docs/csharp/fundamentals/tutorials/snippets/NullableIntroduction/. Update tutorial :::code::: source paths.

Phase 4 — TOC + redirects + deletes (depends on Phases 1–3)

  1. docs/csharp/toc.yml: remove lines 205–206 (legacy tutorial) and 293–296 (legacy concepts); add 4 new entries inside the Null safety node from PR 8.
  2. .openpublishing.redirection.csharp.json: add 3 new redirects (alphabetical insertion); repoint existing redirects on lines 3126, 5389, 5447 (currently target /dotnet/csharp/nullable-migration-strategies) to new fundamentals URL to avoid chains. Run sort-redirects skill.
  3. Delete docs/csharp/nullable-references.md, docs/csharp/nullable-migration-strategies.md, docs/csharp/tutorials/nullable-reference-types.md.

Phase 5 — Cross-link cleanup (depends on Phase 4)

  1. Repoint inbound links across docs/. Critical: docs/csharp/language-reference/compiler-messages/nullable-warnings.md has multiple links to moved files.

Verification

  1. Each new snippet project builds: dotnet build; tutorial sample runs: dotnet run.
  2. git grep -n "nullable-references.md\|nullable-migration-strategies.md\|tutorials/nullable-reference-types.md" returns 0 hits in docs/.
  3. python -m json.tool .openpublishing.redirection.csharp.json validates JSON.
  4. Visual confirmation of TOC ordering against project map.
  5. Every new/edited article has ai-usage: ai-assisted; no F1/helpviewer keywords; 4-tier audience tip near top.
  6. Spot-check 2–3 samples per article for Everyday C# saturation (file-scoped namespaces, primary constructors, collection expressions, raw strings, var).
  7. After PR opens, resolve any OpenPublishing.Build warnings introduced.

Decisions

  • Split confirmed: planning content → migration-strategies.md; address-warnings/contexts → resolve-warnings.md. Reference page stays untouched.
  • resolve-warnings.md is concept-level (5 techniques) — does not duplicate the per-CS86xx catalog; cross-links to it.
  • Move + revise in same PR per overall plan.
  • ~14 files total — slightly above the ~10 guideline, acceptable per project guideline ("guideline, not a strict rule").

Further considerations

  1. PR 8 merge ordering. Recommendation: wait for PR 8 to merge, then rebase PR 9 onto it (avoids toc conflicts). Alternative: include the Null safety toc node creation in PR 9 (would conflict with PR 8 at merge).
  2. Snippet reuse. Recommendation: do NOT share with language-reference/compiler-messages/snippets/null-warnings/. Create fresh, smaller fundamentals-style snippets so reference vs. fundamentals can evolve independently.
  3. Tutorial vs concept article overlap. Recommendation: trim concept-duplicating prose from the tutorial and add a short "Before you start, see Nullable reference types" pointer near the top.

Internal previews

Toggle expand/collapse
📄 File 🔗 Preview link
docs/core/compatibility/sdk/6.0/csharp-template-code.md C# code in templates not supported by earlier versions
docs/core/extensions/windows-service.md Create Windows Service using BackgroundService
docs/core/whats-new/dotnet-5.md What's new in .NET 5
docs/core/whats-new/dotnet-core-3-0.md What's new in .NET Core 3.0
docs/csharp/advanced-topics/update-applications/nullable-migration-strategies.md Nullable migration strategies
docs/csharp/fundamentals/null-safety/index.md docs/csharp/fundamentals/null-safety/index
docs/csharp/fundamentals/null-safety/null-operators.md C# null operators
docs/csharp/fundamentals/null-safety/nullable-reference-types.md Nullable reference types
docs/csharp/fundamentals/null-safety/nullable-value-types.md Nullable value types: C# Fundamentals
docs/csharp/fundamentals/null-safety/resolve-warnings.md Resolve nullable warnings
docs/csharp/fundamentals/tutorials/nullable-reference-types.md Tutorial: Express your design intent with nullable and non-nullable reference types
docs/csharp/language-reference/attributes/nullable-analysis.md docs/csharp/language-reference/attributes/nullable-analysis
docs/csharp/language-reference/builtin-types/arrays.md Arrays
docs/csharp/language-reference/builtin-types/nullable-reference-types.md "Nullable reference types"
docs/csharp/language-reference/compiler-messages/interface-implementation-errors.md Resolve errors and warnings related to members that implement an interface
docs/csharp/language-reference/compiler-messages/nullable-warnings.md Nullable reference type warnings
docs/csharp/language-reference/compiler-options/language.md "Compiler Options - language feature rules"
docs/csharp/language-reference/keywords/where-generic-type-constraint.md where (generic type constraint) (C# Reference)
docs/csharp/language-reference/operators/null-forgiving.md docs/csharp/language-reference/operators/null-forgiving
docs/csharp/toc.yml Taken from https://github.com/dotnet/roslyn/wiki/Samples-and-Walkthroughs
docs/csharp/tour-of-csharp/tips-for-java-developers.md Tips for Java Developers
docs/csharp/tour-of-csharp/tips-for-javascript-developers.md Roadmap for JavaScript and TypeScript developers learning C#
docs/csharp/tour-of-csharp/tips-for-python-developers.md Python
docs/framework/debug-trace-profile/code-contracts.md docs/framework/debug-trace-profile/code-contracts
docs/fundamentals/code-analysis/style-rules/ide0370.md Remove unnecessary suppression (IDE0370)
docs/fundamentals/syslib-diagnostics/syslib1026.md SYSLIB1026 error

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR restructures the C# nullable reference types (NRT) documentation into a Fundamentals “null safety” concept + tutorial set, moves/creates supporting snippet projects, and updates inbound links and TOC entries to point at the new locations.

Changes:

  • Adds new Fundamentals null-safety concept articles (NRT overview, warning resolution, and migration strategies) plus a Fundamentals tutorial and snippet projects.
  • Removes legacy C# NRT concept/tutorial pages and updates docs/csharp/toc.yml accordingly.
  • Repoints links across C#, Core, Framework, and analyzer docs to the new Fundamentals URLs.

Reviewed changes

Copilot reviewed 39 out of 42 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
docs/fundamentals/syslib-diagnostics/syslib1026.md Updates NRT link target to the new Fundamentals article.
docs/fundamentals/code-analysis/style-rules/ide0370.md Updates NRT link target to the new Fundamentals article.
docs/framework/debug-trace-profile/code-contracts.md Updates guidance link to point at the new Fundamentals NRT article.
docs/csharp/tutorials/snippets/NullableIntroduction/SurveyQuestion.cs Removes legacy tutorial snippet file as part of moving the tutorial snippets.
docs/csharp/tutorials/nullable-reference-types.md Removes legacy tutorial page in favor of the new Fundamentals tutorial.
docs/csharp/tour-of-csharp/tips-for-python-developers.md Repoints “Nullable types” link to the new Fundamentals NRT article.
docs/csharp/tour-of-csharp/tips-for-javascript-developers.md Repoints nullable types link to the new Fundamentals NRT article.
docs/csharp/tour-of-csharp/tips-for-java-developers.md Repoints nullable types links to the new Fundamentals NRT article.
docs/csharp/toc.yml Removes legacy tutorial entry and adds a “Null safety” section pointing at new Fundamentals pages.
docs/csharp/nullable-references.md Removes legacy NRT concept page replaced by Fundamentals content.
docs/csharp/nullable-migration-strategies.md Removes legacy migration strategies page replaced by Fundamentals content.
docs/csharp/language-reference/operators/null-forgiving.md Updates links to the new Fundamentals tutorial and NRT overview.
docs/csharp/language-reference/keywords/where-generic-type-constraint.md Updates nullable context link to point at the new Fundamentals NRT overview.
docs/csharp/language-reference/compiler-options/language.md Updates nullable contexts/migration links to new Fundamentals pages.
docs/csharp/language-reference/compiler-messages/nullable-warnings.md Updates links to new Fundamentals NRT overview and migration page.
docs/csharp/language-reference/compiler-messages/interface-implementation-errors.md Updates NRT link to the new Fundamentals NRT overview.
docs/csharp/language-reference/builtin-types/nullable-reference-types.md Updates migration strategies link to new Fundamentals page.
docs/csharp/language-reference/builtin-types/arrays.md Updates NRT links to the new Fundamentals NRT overview (including known pitfalls anchor).
docs/csharp/language-reference/attributes/nullable-analysis.md Updates generics section link to the new Fundamentals NRT overview.
docs/csharp/fundamentals/tutorials/snippets/NullableIntroduction/SurveyRun.cs Adds moved tutorial snippet code for SurveyRun.
docs/csharp/fundamentals/tutorials/snippets/NullableIntroduction/SurveyResponse.cs Updates moved tutorial snippet code (uses primary constructor and snippet markers).
docs/csharp/fundamentals/tutorials/snippets/NullableIntroduction/SurveyQuestion.cs Adds moved tutorial snippet code for SurveyQuestion.
docs/csharp/fundamentals/tutorials/snippets/NullableIntroduction/Program.cs Adds moved tutorial snippet code for the top-level program and snippet markers.
docs/csharp/fundamentals/tutorials/snippets/NullableIntroduction/NullableIntroduction.csproj Updates tutorial snippet project to net10.0.
docs/csharp/fundamentals/tutorials/nullable-reference-types.md Adds new Fundamentals tutorial page for nullable reference types.
docs/csharp/fundamentals/null-safety/snippets/resolve-warnings/resolve-warnings.csproj Adds new snippet project for the “Resolve warnings” article.
docs/csharp/fundamentals/null-safety/snippets/resolve-warnings/project-snippet.xml Adds minimal XML snippet used to show <Nullable>enable</Nullable>.
docs/csharp/fundamentals/null-safety/snippets/resolve-warnings/Program.cs Adds runnable examples backing the “Resolve warnings” article snippets.
docs/csharp/fundamentals/null-safety/snippets/nullable-reference-types/project-snippet.xml Adds minimal XML snippet used to show <Nullable>enable</Nullable>.
docs/csharp/fundamentals/null-safety/snippets/nullable-reference-types/Program.cs Adds runnable examples backing the “Nullable reference types” article snippets.
docs/csharp/fundamentals/null-safety/snippets/nullable-reference-types/nullable-reference-types.csproj Adds new snippet project for the NRT overview article.
docs/csharp/fundamentals/null-safety/snippets/migration-strategies/project-snippet.xml Adds minimal XML snippet for migration strategy examples.
docs/csharp/fundamentals/null-safety/snippets/migration-strategies/Program.cs Adds runnable examples backing the migration strategies article snippets.
docs/csharp/fundamentals/null-safety/snippets/migration-strategies/migration-strategies.csproj Adds new snippet project for the migration strategies article.
docs/csharp/fundamentals/null-safety/resolve-warnings.md Adds new Fundamentals concept article describing warning-resolution techniques.
docs/csharp/fundamentals/null-safety/nullable-reference-types.md Adds new Fundamentals concept article for nullable reference types.
docs/csharp/fundamentals/null-safety/migration-strategies.md Adds new Fundamentals concept article for migration strategies.
docs/core/whats-new/dotnet-core-3-0.md Updates tutorial link to the new Fundamentals tutorial location.
docs/core/whats-new/dotnet-5.md Updates NRT link to the new Fundamentals NRT overview.
docs/core/extensions/windows-service.md Updates NRT link to the new Fundamentals NRT overview.
docs/core/compatibility/sdk/6.0/csharp-template-code.md Updates NRT link to the new Fundamentals NRT overview.

Comment thread docs/csharp/fundamentals/null-safety/nullable-reference-types.md
Comment thread docs/csharp/language-reference/operators/null-forgiving.md Outdated
Comment thread docs/csharp/language-reference/keywords/where-generic-type-constraint.md Outdated
Comment thread docs/csharp/language-reference/compiler-options/language.md Outdated
Comment thread docs/csharp/language-reference/compiler-messages/nullable-warnings.md Outdated
Comment thread docs/csharp/fundamentals/null-safety/resolve-warnings.md
Comment thread docs/csharp/fundamentals/null-safety/snippets/resolve-warnings/Program.cs Outdated
@BillWagner BillWagner force-pushed the null-safety-tutorials branch from 13fb2be to 08fa13e Compare May 8, 2026 18:55
@BillWagner BillWagner marked this pull request as ready for review May 8, 2026 19:45
@BillWagner BillWagner requested review from a team and gewarren as code owners May 8, 2026 19:45
@BillWagner
Copy link
Copy Markdown
Member Author

Note for reviewers:

During a rebase, the redirection file got quite mangled. The diffs look better if you hide whitespace, but Copilot still decided to sort all the entries so the diffs are much larger than expected. I did verify the substantive changes by hand.

Comment thread docs/csharp/fundamentals/null-safety/nullable-reference-types.md Outdated
Comment thread docs/csharp/fundamentals/null-safety/nullable-reference-types.md Outdated
Comment thread docs/csharp/fundamentals/null-safety/nullable-reference-types.md Outdated
Comment thread docs/csharp/fundamentals/null-safety/nullable-reference-types.md
Comment thread docs/csharp/fundamentals/null-safety/nullable-reference-types.md Outdated
Comment thread docs/csharp/fundamentals/null-safety/nullable-reference-types.md Outdated
Comment thread docs/csharp/fundamentals/null-safety/nullable-reference-types.md Outdated
Comment thread docs/csharp/fundamentals/null-safety/nullable-reference-types.md Outdated
Comment thread docs/csharp/fundamentals/null-safety/nullable-reference-types.md Outdated
Comment thread docs/csharp/fundamentals/null-safety/nullable-reference-types.md Outdated
BillWagner added a commit that referenced this pull request May 14, 2026
Several themes came through this review. Update the prompts to match.
@BillWagner
Copy link
Copy Markdown
Member Author

@adegeo

I finished updates based on your recommendations. I have one question on this article: - docs/csharp/fundamentals/null-safety/resolve-warnings.md (Markdown, Preview)

Should it stay in fundamentals, or would it be better if I moved it into the language reference section? It doesn't feel like it belongs here, but it should continue to be published.

BillWagner added a commit that referenced this pull request May 20, 2026
Several themes came through this review. Update the prompts to match.
1. `fundamentals/null-safety/nullable-reference-types.md` — apply `template-concept.md`. Body from [docs/csharp/nullable-references.md](docs/csharp/nullable-references.md), with conceptual prose lifted from the existing tutorial. 4-tier audience tip, `ms.topic: concept-article`, `ai-usage: ai-assisted`. All code via `:::code:::` snippet refs.
2. `fundamentals/null-safety/resolve-warnings.md` — concept article. Pull "Understand contexts and warnings" / "Address warnings" / "Enable type annotations" / "Attributes extend type annotations" sections from [docs/csharp/nullable-migration-strategies.md](docs/csharp/nullable-migration-strategies.md). Frame as **5 resolution techniques** with worked examples (NOT a per-CS86xx catalog). Cross-link to [docs/csharp/language-reference/compiler-messages/nullable-warnings.md](docs/csharp/language-reference/compiler-messages/nullable-warnings.md) for per-warning lookup.
3. `fundamentals/null-safety/migration-strategies.md` — concept article. Pull "Plan your migration" / "Next steps" / intro from [docs/csharp/nullable-migration-strategies.md](docs/csharp/nullable-migration-strategies.md). Cover the four default-context strategies and recommended phased order.
4. `fundamentals/tutorials/nullable-reference-types.md` — apply `template-tutorial.md`. Source: [docs/csharp/tutorials/nullable-reference-types.md](docs/csharp/tutorials/nullable-reference-types.md). Restructure to template (checklist, Prerequisites, numbered task H2s, "Get the code", "Next step"). Trim concept-duplicating prose; replace with cross-links.
. New snippet projects under `docs/csharp/fundamentals/null-safety/snippets/{nullable-reference-types,resolve-warnings,migration-strategies}/`. Each minimal `.csproj`, `<Nullable>enable</Nullable>`, latest TFM. Build + execute per docs `copilot-instructions.md`.
6. Move `docs/csharp/tutorials/snippets/NullableIntroduction/` → `docs/csharp/fundamentals/tutorials/snippets/NullableIntroduction/`. Update tutorial `:::code:::` source paths.
[docs/csharp/toc.yml](docs/csharp/toc.yml): remove lines 205–206 (legacy tutorial) and 293–296 (legacy concepts); add 4 new entries inside the `Null safety` node from PR 8.
8. [.openpublishing.redirection.csharp.json](.openpublishing.redirection.csharp.json): add 3 new redirects (alphabetical insertion); repoint existing redirects on lines 3126, 5389, 5447 (currently target `/dotnet/csharp/nullable-migration-strategies`) to new fundamentals URL to avoid chains. Run `sort-redirects` skill.
9. Delete [docs/csharp/nullable-references.md](docs/csharp/nullable-references.md), [docs/csharp/nullable-migration-strategies.md](docs/csharp/nullable-migration-strategies.md), [docs/csharp/tutorials/nullable-reference-types.md](docs/csharp/tutorials/nullable-reference-types.md).
***When reviewing commit-by-commit, this can be skimmed***

10. Repoint inbound links across `docs/`. Critical: [docs/csharp/language-reference/compiler-messages/nullable-warnings.md](docs/csharp/language-reference/compiler-messages/nullable-warnings.md) has multiple links to moved files.
Review the drafts, make several changes in style, tone and substance.
…ions

Relocate the migration article out of fundamentals/null-safety into a new Advanced topics > Update existing apps subsection. Rename to nullable-migration-strategies.md, repath snippets, update inbound links from sibling articles and language-reference, repoint redirects, and add a redirect from the vacated path.
BillWagner and others added 12 commits May 20, 2026 17:35
Rename language-reference compiler-messages H1 'Resolve nullable warnings' to 'Nullable reference type warnings' to avoid collision with the new fundamentals article. Rename the H2 'Enable nullable reference types' to 'Nullable context' so existing inbound bookmarks #nullable-context resolve.
Co-authored-by: Andy (Steve) De George <67293991+adegeo@users.noreply.github.com>
Restore the details on nullable contexts.
The latest update to the prompts provided new themes for actions in this section. Run those to see how much it picks up.

In addition, move a couple sections from fundamentals into the language reference. They were too deep for fundamentals, but were necessary in the reference section.
Fix build warnings.
I ran the new prompts, and it caught a couple more things.
@BillWagner BillWagner force-pushed the null-safety-tutorials branch from b88c9ab to 74d9428 Compare May 20, 2026 21:36
Copy link
Copy Markdown
Contributor

@adegeo adegeo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved! I think everything is in a pretty good state. There are some improvements that can be made though. Because this is close to the finish line, I'm approving so you can merge when you're happy with it.

Great job!

Comment on lines +33 to +36
- **Disable as the default.** Add `#nullable enable` at the top of each file as you migrate it. Existing files stay nullable-oblivious until you touch them. This option has the lowest friction for stable libraries because new feature work is rare.
- **Enable as the default.** Set `<Nullable>enable</Nullable>` and add `#nullable disable` at the top of every file you haven't migrated yet. Every new file is nullable-aware from the start, so the migration backlog can only shrink. This choice is better when development is active.
- **Warnings as the default.** Choose this default for a two-phase migration: address warnings while every reference type is still treated as oblivious, then turn on annotations. The two-phase split keeps each step's diff focused.
- **Annotations as the default.** Start by annotating your public API (`?` on members that allow `null`) before chasing warnings. The compiler doesn't emit warnings yet, so you can settle the API surface without distraction.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses two different styles. The second item says Set <Nullable>...</Nullable>, but the others don't. I would use that in each strategy item so it's clear what they set in the project.

| `warnings` | off | on | Two-phase migration: address warnings first, annotate later. |
| `annotations` | on | off | Annotate the public API before fixing the internal warnings. |

Pick the strategy that makes the next file you create do the right thing automatically:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't sound accurate I think because of the way this is phrased. It's indicating that the following items happen automatically, but they don't necessarily. The first two items require you to set a directive in the file manually.

Comment on lines +73 to +74
1. **Phase 1 — Add annotations.** Set the project default to `annotations`. Reference types become non-nullable by default, but the compiler doesn't emit warnings, so the noise stays out of your way. Walk the public API and add `?` to every member that may legitimately return or accept `null`. Tighten the signatures that shouldn't. Because warnings are off, you can settle the API shape in focused commits without untangling the implementation at the same time.
1. **Phase 2 — Address warnings.** Switch the project default to `enable`. The annotations you added in phase 1 now feed null-state analysis, so the warnings the compiler emits are higher quality from the start—each one points at code whose behavior doesn't match the contract you already published. Resolve them with the techniques in [Resolve nullable warnings](../../fundamentals/null-safety/resolve-warnings.md).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe em dash should have spaces around them.

Comment on lines +66 to +67
1. **Phase 1 — Address warnings.** Set the project default to `warnings`. Reference types remain nullable-oblivious, so the type system doesn't change yet. The compiler emits warnings everywhere your existing code might already throw a <xref:System.NullReferenceException?displayProperty=nameWithType>. Add null checks, restructure flow, or apply attributes until the project is warning-clean. Each fix makes the production code more resilient even before annotations exist.
1. **Phase 2 — Add annotations.** Switch the project default to `enable`. Reference types are now non-nullable by default, and `var` locals become nullable. New warnings reflect declarations that don't match how the variables are used. Add `?` to types that should allow `null`. Tighten APIs that should require non-null inputs.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe em dash should have spaces around them.

After every file participates in the project default and the `<Nullable>enable</Nullable>` element is set:

- Remove every `#nullable` directive in your source.
- Remove `null!` and `default!` initializers that you added only to silence warnings during migration. Replace them with proper initialization, or change the member type to nullable.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what this is???

Comment on lines +55 to +63
## Design the survey types

Three classes model the survey:

- `SurveyQuestion` — one question. The text and question type are required.
- `SurveyRun` — the collection of questions plus the list of respondents.
- `SurveyResponse` — one respondent's answers, which might be missing.

Each type uses non-nullable reference types for required values and nullable reference types for missing values.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this section. It's more of an overview of the following 3 sections. Unless there's a lot more information to add here to inform the reader why they're reading this section, it should be removed. Better yet, it should be merged (simplified) into the introduction.

Overall I feel like it's out of place because the previous section is actionable, this section is conceptual, and the next 3 sections are actionable.


Each type uses non-nullable reference types for required values and nullable reference types for missing values.

## Build the survey questions
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section has 3 major steps: create SurveyQuestion.cs, create SurveyRun.cs, modify Program.cs. This should probably be converted to a procedural section, otherwise it's hard to follow.

}
```

The `surveyQuestions` field is a non-nullable `List<SurveyQuestion>`. It uses [target-typed `new`](../../language-reference/operators/new-operator.md#target-typed-new) (the `new()` syntax that lets the compiler infer the type from the field's declaration) to initialize the list at the declaration, which satisfies the non-nullable contract. Both `AddQuestion` overloads accept non-nullable parameters, so the compiler enforces that callers don't pass `null`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reader is going to get an analyzer warning here that they should use a collection initializer. I think it's better to show that:

private List<SurveyQuestion> surveyQuestions = [];

If you make that change, you'll have to change the description here, replacing the new() description with what the collection initializer is doing.


The compiler issues warning *CS8625* because `default` evaluates to `null` for a reference type, and `AddQuestion` expects a non-nullable `string`. Remove the line before continuing.

## Create respondents and capture answers
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section is also doing a lot of different steps. A procedure makes it clear to the reader when one thing ends and another begins.


The output is different on each run because respondents are generated randomly, but every line either reports a participant's answers or notes that they declined.

The finished sample is in the [csharp/NullableIntroduction](https://github.com/dotnet/samples/tree/main/csharp/NullableIntroduction) folder of the [dotnet/samples](https://github.com/dotnet/samples) repository. Experiment by changing types between nullable and non-nullable. Removing a `?` where the design allows missing values produces compiler warnings that point to every place the missing value matters.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps a conclusion section here so this text is separated from the tutorial step.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Everyday C#] Phase C, PR 9: Null safety: NRT, warnings, migration, tutorial

3 participants