Header image for C# Master

C# Master

Create a better C# master if possible

Prompt

# C# Mastery β€” Level 1 to God TierStack assumed: .NET 10 (LTS) C# 14. The platform ships a new major version every November β€” verify the current release before starting, and re-read the release notes every year for the rest of your career. Level 6 Concurrency & Async β€” correct first, then fastGoal: write concurrent systems you can *prove* reason about; debug the ones you can't.Core Threads vs Task; the thread pool (work stealing, hill-climbing) and how to diagnose starvation with dotnet-counters async/await internals: the compiler-generated state machine, IAsyncStateMachine, builders β€” read the lowering SynchronizationContext, ConfigureAwait(false), ConfigureAwaitOptions (.NET 8), classic deadlock anatomy ValueTask and exactly when it's a win; cancellation done right: CancellationToken plumbing, linked sources, timeouts Combinators: WhenAll, WhenAny, WhenEach (.NET 9); exception flow and AggregateException IAsyncEnumerable<T>, await foreach, WithCancellation, IAsyncDisposable System.Threading.Channels: bounded/unbounded, backpressure β€” your default producer/consumer tool Parallel.For/ForEach/ForEachAsync, PLINQ, TPL Dataflow (know it exists) Primitives: the dedicated Lock type (.NET 9), SemaphoreSlim (the async-compatible one), ReaderWriterLockSlim, Interlocked CAS loops, Volatile and the documented .NET memory model TaskCompletionSource (always RunContinuationsAsynchronously), custom TaskScheduler, PeriodicTimer, AsyncLocal<T> and ExecutionContext flow Why async void is only for event handlers; sync-over-async and why it detonatesDeep cuts: anything with a GetAwaiter() extension method is awaitable β€” make something absurd awaitable; IValueTaskSource + ManualResetValueTaskSourceCore for *pooled, allocation-free* async operations; [AsyncMethodBuilder] to swap the machinery behind async itself (door to L10); ExecutionContext.SuppressFlow.Build: a polite concurrent web crawler (Channels + cancellation + per-host throttling) a token-bucket rate limiter proven correct under stress reproduce, diagnose, and fix thread-pool starvation on purpose.Passed when: you can explain your lock-free code's linearization points, and find a deadlock in a dump with dotnet-dump + dumpasync. Level 7 Metaprogramming β€” code that reads, writes, and rewrites codeGoal: build the kind of tools other developers depend on: generators, analyzers, ORMs, mockers, plugin hosts.Core Reflection and its true costs; Activator, late-bound generics, MakeGenericType Attributes incl. generic attributes (C# 11); [CallerMemberName], [CallerArgumentExpression] Expression trees: build, compile, visit, rewrite with ExpressionVisitor β€” then understand how EF Core translates LINQ to SQL by building a mini provider dynamic and the DLR: call sites, binders, DynamicObject, when it's the right tool (rarely; know why) Reflection.Emit / DynamicMethod: emit IL at runtime by hand IL literacy: the stack machine, reading ILSpy/ildasm output for everything you write Roslyn: syntax trees, semantic model, incremental source generators (the modern default), analyzers + code fixes; interceptors CSharpScript / Roslyn scripting β€” embed a C# REPL in anything AssemblyLoadContext: collectible assemblies, plugin systems with true unload; MetadataLoadContext for inspection without execution Mono.Cecil for IL rewriting; MSBuild custom tasks/targets and binlog reading [ModuleInitializer]; hot reload's MetadataUpdateHandler; startup hooks (DOTNET_STARTUP_HOOKS)Deep cuts: this level is how DI containers, mappers, mocking frameworks, and serializers actually work β€” and why the ecosystem moved from reflection β†’ expression compilation β†’ source generation (AOT-safety).Build: the signature project β€” one object mapper, three implementations (pure reflection, compiled expression trees, incremental source generator), benchmarked head-to-head with a written verdict an analyzer + code fix enforcing one of your own rules a plugin host that loads and *fully unloads* assemblies.Passed when: your benchmark table exists and you can defend each tradeoff; your generator survives incremental-build correctness (no over-generation). Level 8 The Type System as a Proof System β€” algebraic & functional C#Goal: make illegal states unrepresentable; reason equationally, not situationally. (If you already think in pure, total, compositional terms β€” this is where C# meets that philosophy.)Core Immutability by default: records, init, with, ImmutableArray, builders; functional core / imperative shell architecture Algebraic data types today: closed hierarchies (abstract record + sealed cases in one file) with exhaustive switch; track the official discriminated unions proposal in dotnet/csharplang β€” knowing its status puts you ahead of the feature Option<T> / Result<T,E>: total functions over partial; "parse, don't validate"; smart constructors; railway-oriented error handling, with exceptions kept at boundaries SelectMany is monadic bind: implement Select/SelectMany on your Result and write LINQ query syntax over it β€” multi-step fallible workflows as comprehensions Laws as tests: functor/monad laws, monoid identity/associativity β€” verified with property-based testing (CsCheck or FsCheck) Generic math & static abstract interface members (.NET 7+): INumber<T>, writing one algorithm generic over all numeric types; static-abstract strategy types the JIT devirtualizes to zero cost Phantom types and units-of-measure typing (Quantity<Meters> vs Quantity<Seconds> β€” mixing them won't compile) Self-constrained generics (CRTP), higher-kinded-type emulation and its honest limits; variance mastery The pattern-based surface of C#: awaitable, enumerable, deconstructable, [CollectionBuilder] β€” the compiler's structural typing seams allows ref struct anti-constraint (C# 13) for allocation-free abstractions; memoization, Lazy<T>, purity discipline Tour the language-ext library for ideas even if you don't adopt itBuild: a domain library where invalid states don't compile, with monad laws property-tested a units-of-measure mini-library on phantom types + generic math take a stringly-typed module and rebuild it so the type checker enforces the business rules.Passed when: a stranger reads your domain model and learns the business rules from the types alone β€” no comments needed. Level 9 Runtime Internals & the Native BoundaryGoal: see through the abstraction β€” CLR data structures, GC mechanics, and crossing into native code in both directions.Core CLR anatomy: method tables, object headers, sync blocks (lazy lock inflation), how virtual dispatch and interface dispatch really resolve β€” inspect live with WinDbg + SOS (dumpheap, gcroot, dumpmt, dumpasync) GC internals: mark β†’ plan β†’ relocate β†’ compact; card tables & write barriers; heap regions; DATAS β€” read *Pro .NET Memory Management* (Kokosa) cover to cover ClrMD: write your own dump-analysis tools in C# JIT pipeline at a high level (import β†’ morph β†’ SSA β†’ register allocation β†’ emit); reading dotnet/runtime source as a habit Observability internals: EventPipe, EventSource, ActivitySource/OpenTelemetry Interop, both directions: In: P/Invoke, [LibraryImport] source-generated marshalling, blittability, custom marshallers, ComWrappers Out: function pointers + [UnmanagedCallersOnly], NativeAOT shared libraries β€” export a C ABI *from C#* and call it from Python/Rust/C++ Hosting: embed the runtime in a native app via hostfxr/nethost Exceptions at runtime level: two-pass SEH model β€” and the security-relevant fact that exception filters run before inner finally blocks Text internals: UTF-16, Rune, the UTF-8 everywhere movement (Utf8JsonWriter, IUtf8SpanFormattable) System.IO.Pipelines (PipeReader/PipeWriter, backpressure) and how Kestrel's transport works; raw sockets and the epoll/IOCP mappingBuild: a ClrMD tool that scans a dump for duplicate strings and stuck async state machines a C#-built native library consumed from Python via NativeAOT a minimal HTTP server on raw sockets + Pipelines, load-tested root-cause a real memory leak from a dump using gcroot.Passed when: given only a .dmp of a sick service, you produce the root cause; and you've called your C# code from another language without COM. Level 10 God Tier β€” the rare airGoal: operate at the level of the people who build the platform. Everything here is portfolio-grade and genuinely uncommon knowledge.The work Own the async machinery: write a custom [AsyncMethodBuilder] and a pooled IValueTaskSource awaitable; understand UnsafeOnCompleted vs OnCompleted and deliberate ExecutionContext suppression Compiler-level C#: read Roslyn's lowering for await/foreach/patterns; overload-resolution betterness arcana; be the person who can explain ref-safety error CS8350 from the lifetime rules The forbidden keywords: __makeref, __refvalue, __reftype, __arglist, TypedReference β€” undocumented, ancient, and the historical context for why ref fields and Span<T> exist Write a language: lexer β†’ parser β†’ binder β†’ IL emission (Reflection.Emit or Cecil) β†’ running programs; add a Roslyn-scripting REPL beside it; learn why the tail. IL prefix exists and why C# doesn't emit it JIT whispering: shape code for devirtualization, bounds-check elimination, and PGO-friendly branches; verify every claim with JitDisasm; understand how tiered PGO warps naive benchmarks Runtime archaeology: generic sharing dictionaries and System.__Canon lookups; load the standalone GC (clrgc) and experiment; runtimeconfig knobs and AppContext switches Influence the platform: read LDM notes as they're published; prototype a wished-for feature as a source generator (several real features started exactly this way); take an up-for-grabs performance issue in dotnet/runtime and ship a merged PR β€” the single strongest credential in this ecosystem WASM ([JSImport]/[JSExport], interpreter vs AOT), Objective-C interop existence, reverse-engineering literacy (how ILSpy/dnSpy see your code; what obfuscators actually do)Capstones (ship two publicly): 1. A mini compiled language targeting IL, with REPL 2. A zero-allocation micro web framework on Pipelines, benchmarked against ASP.NET Core minimal APIs 3. A source-generated, exhaustiveness-checked union-type library polished enough that strangers adopt it 4. A diagnostics suite (ClrMD + EventPipe) that auto-detects starvation, leaks, and sync-over-async in dumps 5. A merged dotnet/runtime or roslyn PRPassed when: any one of these is public and used by someone you've never met. Appendix A The Rare-Knowledge IndexThe "almost nobody knows this" list β€” one line each, every item is a search query away:TypedReference & __makeref [AsyncMethodBuilder] overriding IValueTaskSource pooling ExecutionContext.SuppressFlow ConditionalWeakTable (attach state to objects you don't own) [UnsafeAccessor] (reflection-free private access) [ModuleInitializer] [SkipLocalsInit] [InlineArray] CollectionsMarshal.GetValueRefOrAddDefault (one-lookup dictionary upsert) SearchValues<T> string.Create custom interpolated string handlers [CollectionBuilder] allows ref struct scoped & ref fields static abstract members as zero-cost strategies System.__Canon Dynamic PGO & OSR card tables & write barriers DATAS standalone GC loading startup hooks MetadataUpdateHandler (hot reload) interceptors MetadataLoadContext collectible AssemblyLoadContext [UnmanagedCallersOnly] native exports hostfxr embedding exception filters run before finally sync-block lock inflation struct tearing the documented .NET memory model ITuple StrongBox<T> Monitor vs the .NET 9 Lock type TaskCreationOptions.RunContinuationsAsynchronously.Appendix B The Tool Beltsharplab.io (lowering + IL, live) source.dot.net (BCL source, indexed) ILSpy / dnSpy BenchmarkDotNet Disasmo (JIT asm in your IDE) PerfView dotnet-counters / dotnet-trace / dotnet-dump / dotnet-gcdump WinDbg + SOS ClrMD MSBuild Structured Log Viewer CsCheck / FsCheck dotnet/runtime and dotnet/csharplang repos (read issues like a newspaper).Appendix C Reading List (in order)1. C# in Depth β€” Jon Skeet (language mastery) 2. CLR via C# β€” Jeffrey Richter (dated APIs, immortal mental models) 3. Concurrency in C# Cookbook β€” Stephen Cleary 4. Writing High-Performance .NET Code β€” Ben Watson 5. Pro .NET Memory Management β€” Konrad Kokosa (the L9 bible) 6. Functional Programming in C# β€” Enrico Buonanno (the L8 bible) 7. Every "Performance Improvements in .NET X" post β€” Stephen Toub (book-length, annual, unmatched) 8. The C# language specification + dotnet/csharplang LDM notes 9. Blogs: Stephen Cleary (async) Andrew Lock (internals walkthroughs) Matt Warren (runtime archaeology) Adam Sitnik (benchmarking) Eric Lippert's archive (language design reasoning) David Fowler's AspNetCoreDiagnosticScenarios repo (async guidance from the source)Appendix D Speed-Run Schedule (full-time)| Weeks | Levels | Focus | |---|---|---| | 1–3 | 1–2 | Foundations + type design; flagship v0 | | 4–6 | 3 | Mechanics; sharplab becomes reflex | | 7–8 | 4 | Collections/LINQ; first benchmarks | | 9–13 | 5 | Memory/perf; first 0-allocation win | | 14–17 | 6 | Async/concurrency; first dump analysis | | 18–22 | 7 | Metaprogramming; the 3-way mapper | | 23–26 | 8 | Algebraic C#; property tests green | | 27–34 | 9 | Internals + interop; native exports | | 35–52 | 10 | Capstones; first OSS PR |Part-time: multiply by ~2.5. Daily minimum effective dose: one build block, one source-reading block (source.dot.net), one lowering/disasm peek.Appendix E Rules of Acceleration1. Never read twice what you can build once. 2. Every performance claim β†’ BenchmarkDotNet, or it didn't happen. 3. Every language feature β†’ look at its lowering before considering it learned. 4. Teach back β€” writing up each level publicly is the fastest consolidation and builds the reputation that Level 10 requires. 5. The flagship project is the curriculum; the levels are its release notes.