My working repo for a single talk covering two .NET 11 features:
- C# 15 Union Types (discriminated unions) — see
docs/01-CSharp15-Unions.md - .NET 11 Runtime Async — see
docs/02-RuntimeAsync.md
Each doc has my notes: a feature walkthrough, a deep dive into the implementation (decompiled C#
plus IL from ilspycmd), a set of runnable samples, the gotchas I ran into, and a demo running
order.
Built and run against .NET 11 SDK
11.0.100-preview.5.26302.115,LangVersion=preview, June 2026. Every code block and IL listing in the docs was compiled and run.
CSharp15.slnx # .NET 11 XML solution
Directory.Build.props # shared: net11.0, LangVersion=preview, nullable
global.json # pins the .NET 11 preview SDK
docs/
01-CSharp15-Unions.md # concept: union types
02-RuntimeAsync.md # concept: runtime async (state machine vs runtime, pseudo-code + IL)
src/
00_Rust/ # [rust] the same demos in Rust (enum + Option/Result); not in the .slnx
01_Basics/ # [unions] console — declaration, conversion, exhaustive switch
02_ResultOption/ # [unions] classlib — Option<T> / Result<T,E> + combinators (extension blocks)
03_RecursiveExpr/ # [unions] console — recursive AST evaluator + printer
04_DomainModeling/ # [unions] console — state machine, illegal states unrepresentable
05_PatternShowcase/ # [unions] console — every pattern form through a union
06_Lowering/ # [unions] classlib — types for the IL deep dive (+ decompile.sh)
07_CollectionExprArgs/ # [bonus] console — collection expression arguments (with(...))
08_RuntimeAsync_Classic/ # [async] console — classic compiler state machine (13 frames)
09_RuntimeAsync_Enabled/ # [async] console — runtime-async=on (5 frames) + patterns demo
10_ResultOptionUsage/ # [unions] console — real-world Option/Result usage (consumes 02)
11_UnionWithMembers/ # [unions] console — union with custom ToString/methods (3 forms)
runtime-async-compare.sh # builds 08 vs 09, diffs stack traces + IL
tests/
Csharp15.Tests/ # xUnit — 10 tests over Option/Result
- .NET 11 preview SDK (
global.jsonpins the exact version I used). - For the IL deep dives:
dotnet tool install -g ilspycmd.
dotnet build CSharp15.slnx -c Release # 0 warnings, 0 errors
dotnet test tests/Csharp15.Tests # Passed! Passed: 10
# Union samples
dotnet run --project src/01_Basics
dotnet run --project src/03_RecursiveExpr
dotnet run --project src/05_PatternShowcase
dotnet run --project src/07_CollectionExprArgs
dotnet run --project src/10_ResultOptionUsage
# Deep dives
src/06_Lowering/decompile.sh # union -> struct + IUnion, switch IL
src/runtime-async-compare.sh # state machine vs runtime async
# Rust counterpart (needs a Rust toolchain, https://rustup.rs)
(cd src/00_Rust && cargo run) # enum + Option/Result, parallels 01_Basics & 02- Union types:
union Pet(Cat, Dog, Bird);lowers to astruct : IUnionholdingobject? Value; conversions are constructor calls,switchis anisinstladder with aThrowSwitchExpressionExceptionsafety net, and exhaustiveness is CS8509 (a warning). - Runtime async:
<Features>runtime-async=on</Features>makes the runtime, not the compiler, manage suspension — noIAsyncStateMachinetypes,await xbecomesAsyncHelpers.Await(x), methods are flaggedMethodImplOptions.Async, and live stack traces shrink (13 → 5 frames here).