Roslyn Analyzers in C#
Yesterday we looked at Source Generators — code that runs at compile time to produce new C# files. Roslyn Analyzers are the other half of that story. Where generators create code, analyzers inspect it...
Source Generators in C#
Source generators are one of those features that feel like magic once you start using them. Introduced in C# 9, they let the compiler generate code at build time — no reflection, no runtime overhead, ...
Producer-Consumer with Channels in C#
If you've ever needed to pass data between tasks running at different speeds, you've probably reached for a ConcurrentQueue\<T\> and a bunch of manual signalling code. There's a cleaner way: Sys...
IAsyncEnumerable in C#
If you've used async/await in C#, you know how to await a single value. But what about a stream of values that arrive asynchronously over time? That's where IAsyncEnumerable\<T\> comes in, and o...
Span and Memory in C#
If you've ever wondered how .NET achieves near-zero-allocation performance for string parsing or buffer operations, the answer usually involves Span\<T\> and Memory\<T\>. These types let y...
Nullable Reference Types in C#
I have a complicated relationship with null.
We've been together since my early C# days. It's been mostly one-sided — null has crashed my apps, embarrassed me in production, and woken me up at 2am via...
C# Records and Immutability
If you've written DTOs, value objects, or event payloads in C#, you know the boilerplate drill: define a class, add properties, override Equals, override GetHashCode, maybe implement IEquatable\<T\...
Pattern Matching in C#
If you've ever written a long chain of if/else if blocks just to check what type something is or inspect a few properties, pattern matching is for you. C# has been adding pattern matching features sin...
Building Console Apps in C#
Console apps get underestimated. They're not glamorous, but they're often the fastest way to ship a useful tool — a migration script, a data importer, a dev utility that you'll run a hundred times. C#...
LINQ Best Practices in C#
LINQ is one of C#'s most expressive features — you can filter, transform, and aggregate collections with code that reads almost like English. But it's also one of the easiest places to write code that...
Async/Await Pitfalls in C#
Async/await is one of the best things that happened to C#. It turned callback spaghetti into readable, linear code. But it comes with a set of traps that are easy to fall into and sometimes hard to di...
What's New in .NET 10 and C# 14
.NET 10 shipped in November 2025, and it's a Long-Term Support release — the kind of milestone that signals "yes, it's time to migrate." If you're still on .NET 6 or .NET 8, this is your gre...
Characterisation Tests in C#
We've covered a lot of ground in this testing series. Unit tests, TDD, mocking, integration testing, property-based testing — all of those assume you're working with code you understand, or code you'r...
Property-Based Testing with FsCheck
We've been building up a serious testing toolkit this week. We covered unit testing with xUnit, TDD, mocking with Moq, and integration testing in ASP.NET Core. All of those rely on example-based testi...
Integration Testing in ASP.NET Core
We've been building up a solid testing toolkit this week. We covered unit testing with xUnit, TDD, and mocking with Moq. Unit tests are great, but they only tell you that your individual pieces work i...