Skip to content

Add exploration tutorial for unions and closed hierarchies#54627

Open
BillWagner wants to merge 8 commits into
dotnet:mainfrom
BillWagner:explore-unions-closed-hierarchies
Open

Add exploration tutorial for unions and closed hierarchies#54627
BillWagner wants to merge 8 commits into
dotnet:mainfrom
BillWagner:explore-unions-closed-hierarchies

Conversation

@BillWagner

@BillWagner BillWagner commented Jul 2, 2026

Copy link
Copy Markdown
Member

Copilot AI review requested due to automatic review settings July 2, 2026 18:45
@dotnetrepoman dotnetrepoman Bot added this to the July 2026 milestone Jul 2, 2026

Copilot AI left a comment

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.

Pull request overview

This PR adds two new exploratory tutorials under the C# “What’s new” section to teach upcoming preview language features: union types and closed type hierarchies. It also introduces a shared “TelemetryMonitor / SmartHome” sample used by the tutorials via snippet-backed code files.

Changes:

  • Adds new tutorials: Explore union types and Explore closed hierarchies, and links them from docs/csharp/toc.yml.
  • Adds a multi-project sample (SmartHome.Core, SmartHome.App, and SmartHome.Extensions) with snippet regions referenced by both tutorials.
  • Introduces shim support types (UnionAttribute, IUnion, and IsClosedTypeAttribute) to allow the sample to compile when the SDK doesn’t yet ship the required runtime types.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
docs/csharp/whats-new/tutorials/unions.md New unions tutorial content, including referenced snippets and expected output.
docs/csharp/whats-new/tutorials/closed-hierarchies.md New closed-hierarchies tutorial content, including referenced snippets and expected output.
docs/csharp/toc.yml Adds both new tutorials to the “What’s new → Tutorials” section.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.Core/SmartHome.Core.csproj Adds Core sample project for snippets.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.Core/Readings.cs Adds Reading union sample and consumption switch.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.Core/Result.cs Adds “before” result type and Result<T> union sample + consumption.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.Core/Sample.cs Adds generic union (Sample<T>) and numeric normalization example.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.Core/Quantity.cs Adds custom union-like type example for non-boxing cases.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.Core/Sensors.cs Adds closed hierarchy sample and exhaustive switch.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.Core/Report.cs Adds generic closed hierarchy sample + fold/count example.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.Core/UnionSupport.cs Adds temporary shim types required for preview language features.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.App/SmartHome.App.csproj Adds console app that exercises the sample scenarios.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.App/Program.cs Demo program used by both tutorials via snippet regions.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.Extensions/SmartHome.Extensions.csproj Adds extensions project used to demonstrate the “escape hatch” case.
docs/csharp/whats-new/tutorials/snippets/telemetry-monitor/SmartHome.Extensions/DoorContact.cs Adds cross-assembly subtype for the open Contact leaf case.

Comment thread docs/csharp/whats-new/tutorials/unions.md Outdated
Comment thread docs/csharp/whats-new/tutorials/unions.md
Comment thread docs/csharp/whats-new/tutorials/unions.md
Comment thread docs/csharp/whats-new/tutorials/closed-hierarchies.md
BillWagner and others added 4 commits July 2, 2026 15:42
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
You might need to add a polyfill
@BillWagner BillWagner marked this pull request as ready for review July 2, 2026 20:16
@BillWagner BillWagner requested a review from a team as a code owner July 2, 2026 20:16
Comment thread docs/csharp/whats-new/tutorials/closed-hierarchies.md Outdated
Comment on lines +31 to +32
- The .NET SDK that includes the closed hierarchies preview feature. Download it from the [.NET download site](https://dotnet.microsoft.com/download/dotnet).
- An editor such as Visual Studio or Visual Studio Code with the C# Dev Kit.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These bullets seem to be lacking an intro statement.


:::code language="csharp" source="snippets/telemetry-monitor/SmartHome.Core/Sensors.cs" id="SensorExhaustive":::

1. Build the project. In earlier previews, you need to add a polyfill for the `Closed` attribute:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is "earlier previews" clear to readers?

Comment thread docs/csharp/whats-new/tutorials/unions.md Outdated
Comment thread docs/csharp/whats-new/tutorials/unions.md Outdated

This tutorial uses preview language features. You need an SDK that supports union types and a language version set to `preview`.

- The .NET 11 SDK that includes the union types preview feature. Download it from the [.NET download site](https://dotnet.microsoft.com/download/dotnet).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Needs intro?

Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com>

@adegeo adegeo left a comment

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.

Here's feedback on closed. I'll follow up with union soon.

@@ -0,0 +1,63 @@
using SmartHome.Core;

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 folder structure is violating the snippet design we have. If it's shared by multiple articles, it should be in a shared folder. For example, move the entire telementry-monitor folder:

‎docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/


This tutorial uses preview language features. You need an SDK that supports closed hierarchies and a language version set to `preview`.

- The .NET SDK that includes the closed hierarchies preview feature. Download it from the [.NET download site](https://dotnet.microsoft.com/download/dotnet).

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.

Should this be .NET 11 Preview X? The user doesn't really know what to download from this statement.


You build a class library, `SmartHome.Core`, that holds the closed hierarchy, a second library, `SmartHome.Extensions`, that extends an open case, and a console app, `SmartHome.App`, that drives them.

1. Create the solution and projects:

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.

Tutorials should be explicit in steps. Here the first step should be to open a terminal and run the following dotnet commands from a folder previously created to store the code of the tutorial.

Comment on lines +53 to +59
1. In each project file, set the language version to `preview`:

```xml
<PropertyGroup>
<LangVersion>preview</LangVersion>
</PropertyGroup>
```

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.

They could probably use --langVersion preview on all of the dotnet new commands in the previous step. If so, I would keep this here for reference, as an optional step. Someone may follow the tutorial but hate creating the new projects via terminal and prefer to use an IDE. If so, they'll need to know how to set the preview version.

---
# Tutorial: Explore C# closed hierarchies

A *closed hierarchy* restricts the direct subtypes of a base type to the assembly that declares it. Because the compiler knows the full set of subtypes, it can verify that a switch handles every one without a default arm. Closed hierarchies suit domains where the set of cases is stable and you want the compiler to flag every place that needs to change when you add a case.

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.

...it can verify that a switch handles every one without a default arm...

Should it be explicit with switch expression or switch expression pattern?


:::code language="csharp" source="snippets/telemetry-monitor/SmartHome.Core/Sensors.cs" id="ClosedSensor":::

1. In the same file, add a method that matches every sensor with a switch:

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.

Suggested change
1. In the same file, add a method that matches every sensor with a switch:
1. In the same file, add a method that matches every sensor with a switch expression:


:::code language="csharp" source="snippets/telemetry-monitor/SmartHome.Core/Sensors.cs" id="SensorExhaustive":::

1. Build the project. In earlier previews, you need to add a polyfill for the `Closed` attribute:

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 what the reader is supposed to do. Are they supposed to add this? Only the latest preview is supported, so we should code directly for that and not include information that can confuse the reader.


## Run the sample

The console app builds each sensor and report, then prints them through the exhaustive switches:

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 think this can be more expressive. It should tell the reader what file to open, to paste in the code, then to run it.


You built the sensor model of a smart-home telemetry monitor and, in the process, worked through closed-hierarchy scenarios. You:

- Declared a `closed` `Sensor` base type and matched its subtypes with an exhaustive switch that needs no default arm.

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.

nit: is this better?

Suggested change
- Declared a `closed` `Sensor` base type and matched its subtypes with an exhaustive switch that needs no default arm.
- Declared a `closed Sensor` base type and matched its subtypes with an exhaustive switch that needs no default arm.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[C# 15-Tutorials]: New Feature - closed type hierarchies [C# 15-Tutorials]: New Feature - unions

4 participants