Daily DevOps & .NET - Where Code Meets Culture

Opinionated .NET, Azure and DevOps engineering. Hard-won lessons from production, no tutorials.

Closed Hierarchies in C# 15: Exhaustive Switches and Versioning

Closed Hierarchies in C# 15: Exhaustive Switches and Versioning

Closed hierarchies let the compiler prove a switch over a class tree is exhaustive, no discard arm required. Genuinely useful for internal domain models, and something to think through carefully before using it in a public library API, where adding a subtype breaks every consumer’s build.
C# 15 Union Types and Closed Hierarchies in Preview

C# 15 Union Types and Closed Hierarchies in Preview

C# 15 preview ships union types with real compiler-checked exhaustiveness, no more hand-rolled sealed hierarchies for a Result type. The catch: it is a union of pre-existing types, not F#-style discriminated cases, and value-type cases box unless you write non-boxing boilerplate yourself. The quieter sibling feature, closed hierarchies, may be the safer bet for enterprise teams right now.
My Analyzer Shipped Without Checking Its Own Source

My Analyzer Shipped Without Checking Its Own Source

NetEvolve.Analyzer enforces null-check idioms and file organization on other people’s code, but had never run against its own. Fixing that surfaced 39 warnings, a silent Visual Studio MEF failure, and a follow-up NE0008 bug where DateOnly and TimeOnly got flagged blind to which target framework actually has them, the same multi-targeting blindness in a different corner of the codebase.
Cyber Resilience Act for .NET Library Authors: Read the Fine Print

Cyber Resilience Act for .NET Library Authors: Read the Fine Print

The EU Cyber Resilience Act’s headline deadline is December 2027, but the reporting clock starts more than a year earlier. Article 14 vulnerability reporting applies from September 2026. Here is the engineering map I built for my own NuGet release pipeline: what the CRA regulates, the 24/72-hour cadence, SBOM tooling for .NET, and where the open-source carve-out holds.
Incremental Source Generators Done Right: Ship It Without Breaking Consumers

Incremental Source Generators Done Right: Ship It Without Breaking Consumers

Parts 1 through 3 of this series made the generator correct, incremental, and proven by tests. None of it reaches a single consumer if the NuGet package is laid out wrong — and the failure modes are silent: a DLL in lib/ instead of analyzers/dotnet/cs simply never loads, a missing dependency throws only inside the compiler, and a marker attribute delivered carelessly breaks InternalsVisibleTo in ways users cannot diagnose. This final part covers the packaging contract: the netstandard2.0 rule, the package layout, dependency bundling, attribute delivery, debugging the shipped bits, and the analyzer hygiene rules that keep you honest.