Skip to main content

Newsletter Archive

Browse through our collection of past newsletters. Each edition is packed with C# and .NET insights.

Page 2 of 10 (28 editions)

March 8, 2026

Freeze Your Lookups: FrozenDictionary & FrozenSet for Hot-Path Reads

If you’ve ever built a Dictionary or HashSet at startup, say for config values, feature flags, or permission sets, and then hammered it with reads for the lifetime of your app, .NET has a gift for you: System.Collections.Frozen.

FrozenDictionary<TKey, TValue> and FrozenSet<T> are immutable, read-optimized collections. You build them once from an existing collection, and in return the runtime produces an internal layout that’s specifically tuned for the keys you gave it. The trade-off is simple: construction is slower than a normal dictionary (the runtime analyzes your keys to pick an optimal strategy), but every subsequent lookup is faster, often dramatically on hot paths.

The API couldn’t be easier. You already have the extension methods you need:

using System.Collections.Frozen;
// Built once at startup from config, a database, etc.
var configMap = new Dictionary<string, string>
{
["FeatureX:Enabled"] = "true",
["FeatureX:MaxRetries"] = "3",
["Cache:SlidingExpiration"] = "00:05:00",
["Logging:MinLevel"] = "Warning"
};
var enabledFeatures = new HashSet<string>
{
"dark-mode", "beta-search", "new-checkout-flow"
};
// One call. Every read after this is faster
FrozenDictionary<string, string> frozenConfig = configMap.ToFrozenDictionary();
FrozenSet<string> frozenFeatures = enabledFeatures.ToFrozenSet();

Once frozen, the read API is exactly what you’re used to with ContainsKey, TryGetValue, indexer access, and Contains. So, it’s a drop-in replacement anywhere you have a build-once, read-many collection:

string retries = frozenConfig["FeatureX:MaxRetries"];
if (frozenConfig.TryGetValue("Cache:SlidingExpiration", out var expiration))
Console.WriteLine($"Sliding expiration: {expiration}");
bool betaSearchOn = frozenFeatures.Contains("beta-search");

How much faster? In a quick micro-benchmark doing 10 million lookups against a small collection, the frozen variants were roughly 2× faster than their mutable counterparts:

Collection10M Lookups
Dictionary<string, string>~90 ms
FrozenDictionary<string, string>~41 ms
HashSet<string>~72 ms
FrozenSet<string>~30 ms

The key thing to remember: these collections are immutable after creation. There’s no Add, Remove, or Clear. If you need to mutate, you’re back to a regular Dictionary or HashSet. But for the very common pattern of “load once, read forever”, FrozenDictionary and FrozenSet are a one-line upgrade that turns a hot path cold.

Read the full tip + 12 curated links

Don't miss the next tip 💧

Get a .NET tip and curated links delivered to your inbox every week.

March 6, 2026

How to Implement Type Safe Unions in C# With OneOf

Grant Riordan shows how OneOf brings F# like discriminated unions to C#, so your methods can return precise outcomes with compile-time checks instead of sprawling hierarchies or surprise exceptions. In this post you get practical patterns for explicit success or failure, polymorphic return types, and stateful workflows using .Match for exhaustive handling that keeps APIs honest and maintainable.

Implementing Distributed Caching in Web API with Azure Managed Redis

Sai Nitesh Palamakula walks through adding distributed caching to an ASP.NET Core Web API using Azure Managed Redis and the IDistributedCache abstraction to speed up read-heavy endpoints across instances. This post focuses on when Redis is the right tool, how to implement the cache-aside pattern with absolute and sliding expiration, and the practical knobs like LRU eviction and AddStackExchangeRedisCache that move the performance needle.

Should my Services be Transient, Scoped, or Singleton?

The basics of Transient, Scoped, and Singleton .NET dependency injection lifetime scopes. This video covers the basics of each scope, including when it's best to use each, when not to use each, and an important reminder of something you should never do when registering your services.

Blazor Without the Bloat: Building “Power Inputs” with Plain HTML

David Gallivan makes the case for building Blazor forms without third-party component bloat by leaning on the power already built into plain HTML inputs. This post shows how to bind native inputs and constraints to Blazor with a little C#, delivering smaller bundles, built-in validation, and a modern UX without extra dependencies.

Create and Run Durable AI Agents in .NET with Microsoft Agent Framework

Kavathiyakhushali shows how to build durable AI agents in .NET with the Microsoft Agent Framework on Azure Durable Functions so your C# workflows can pause, persist state, and resume. This post highlights the orchestration pattern and minimal setup, and why this approach fits real world automation and multi step processes.

Building a Gated Multi-Step Wizard in .NET MAUI with Tab View

Sneha Kumar shows how to build a gated multi-step registration wizard in .NET MAUI with Syncfusion Tab View, turning tabs into a state-driven workflow that only unlocks after validation. In this post you will pick up patterns that reduce form fatigue like state-controlled tab visibility, real-time validation, and modular views for each step, plus a GitHub sample.

Don't miss the next tip 💧

Get a .NET tip and curated links delivered to your inbox every week.

How to Improve Performance with Threading in .NET

Saurav Kumar explains how threading and parallel programming in .NET can boost responsiveness and throughput, and why modern apps lean on Tasks, the thread pool, and Parallel APIs. This post focuses on choosing the right tool for I/O vs CPU workloads and avoiding gotchas like oversubscription, blocking, and unsafe shared state, so your code stays fast and sane.

New in .NET 10 and C# 14: Multi-Tenant Rate Limiting

Ali Hamza Ansari walks through building a multi-tenant rate limiter in ASP.NET Core 10 using the native throttling middleware in .NET 10 and C# 14, with a tenant resolver and token bucket partitions keyed by X-Tenant-ID. This post shows how the updated AddRateLimiter and UseRateLimiter simplify fair-use controls, reduce third-party dependencies, and keep noisy neighbor problems in check for real-world SaaS APIs.

How to Classify Documents using AI in C#/.NET

Cloudmersive shows how to plug AI driven document classification into C# and .NET, turning single type upload portals into smart intakes that handle resumes, cover letters, and more. In this post you install the Cloudmersive Document AI SDK, send an InputFile with category definitions, and read back a classification plus confidence to drive routing in your workflows.

Builder Design Pattern in C#: Complete Guide with Examples

Nick Cosentino walks through the Builder pattern in C#, showing how step by step construction tames telescoping constructors, complex initialization, and immutable models while keeping APIs fluent and readable. This post uses relatable examples from custom pizzas to query builders, calls out pitfalls and best practices, and maps the pattern to real .NET tooling like StringBuilder, EF Core, and configuration so you know when to reach for it and when to keep things simple.

Make Unity Feel Instant: Background Jobs With Thread Manager

WitShells shows how to keep Unity scenes smooth by offloading heavy work to background threads with ThreadManager, a lightweight C# package for jobs and progress reporting. This post focuses on a reusable pattern using a small worker pool, typed ThreadJob, QuickThreadJobs one-liners, and safe main-thread callbacks to keep gameplay and UI responsive.

Scalable .NET MAUI: Implementing Clean Architecture for Enterprise-Grade Apps

The C# Alchemist walks through applying Clean Architecture to .NET MAUI so you can dodge the Massive ViewModel trap and keep business rules clear of UI concerns. This post outlines the domain, application, infrastructure, and presentation layers with DI glue, highlighting how decoupling boosts testability, maintainability, and even makes platform or data store swaps far less painful.

March 4, 2026

String Performance: The Fastest Way to Get a String’s Length

Getting a string length sounds trivial, but this post digs into what the JIT actually does, benchmarking string.Length, AsSpan and other patterns alongside the guidance behind CA1820 and CA1829. Expect practical takeaways on when Span helps, which checks are fastest in hot paths, and how to silence analyzers without sacrificing readability.

Extract Pages from Word Documents Using C#

Alice Yang walks through practical patterns for extracting pages from Word documents in C# using Spire.Doc, from grabbing a single page or range to splitting a file into one document per page. The examples and gotchas around zero-based indexing, page vs section, and safe cloning help you automate approvals and conversions without layout surprises.

Generating SBOM for NuGet packages

Gérald Barré shows how to have your NuGet packages include a Software Bill of Materials by wiring up Microsoft.Sbom.Targets and letting dotnet pack embed an SPDX manifest for you. This post frames SBOMs as practical supply chain hygiene that helps with license visibility and audits while keeping your release flow simple.

Deep C# - Multicast Delegates and Events

Mike James digs into multicast delegates and how they power C# events, untangling Delegate vs MulticastDelegate and showing how invocation lists actually behave in real code. Expect practical takeaways like why the last handler returns the value, how += and -= build or trim pipelines, and the gotcha that an exception stops the chain, all backed by clear examples and lambdas.

Building an authenticated MCP server with Microsoft Entra and .NET

Matteo Pagani shows how to build a secure MCP server in ASP.NET Core that uses Microsoft Entra for identity, fronted by Azure API Management so agents like GitHub Copilot can call your tools safely over Streamable HTTP. In this post, you wire up C# tools with the MCP .NET SDK, generate OpenAPI, publish to App Service, add OAuth code flow metadata in APIM, and lock down the backend, a practical pattern you can reuse for production agent integrations.

Using ClientConnectionId to Correlate .NET Connection Attempts in Azure SQL

Kalyan Singh Bondili shows a pragmatic way to capture and log ClientConnectionId from SqlConnection in .NET to correlate client connection attempts with Azure SQL diagnostics. This post includes a small console app that emits tidy JDBC-style lines with timestamps and IDs so you can pinpoint intermittent connectivity issues faster.

Don't miss the next tip 💧

Get a .NET tip and curated links delivered to your inbox every week.

Set the AMR Claim When Using Passkeys Authentication in ASP.NET Core

Damien Bowden shows how to set the amr claim correctly for passkeys with ASP.NET Core Identity in .NET 10 using the OpenID Connect EAP ACR Values so passkey sign ins return pop as expected. This post shares a clean workaround for the current framework behavior and demonstrates requesting phishing resistant authentication with acr_values so LoA and downstream authorization stay accurate.

Visual Studio February Update

Mark Downie walks through the Visual Studio 2026 February update that leans into practical AI and diagnostics to keep .NET devs in the flow. This post highlights Copilot powered unit test generation, call stack explanations, and a profiler that runs with your tests, plus a WinForms expert agent, richer IEnumerable DataTips, and faster Razor hot reload that smooths out day to day work.

Generic Math in .NET: Design, Constraints, and Practical Use

Viktor Ponamarev walks through how .NET generic math and the INumber interfaces reshape numeric code design, moving from type-switch gymnastics and dynamic to clear constraints and compile time safety. This post highlights when and how to use numeric interfaces to build reusable, fast algorithms across many numeric types, with practical patterns you can apply to sums and other operations without sacrificing correctness.

Stop Using ToLower() for Comparisons! The Fast, Correct Way in C#

Lowercasing strings to compare them costs allocations and can break under different cultures (hello, Turkish I). In this video, Michael shows why .ToLower()/.ToUpper() are the wrong tools for comparisons and how StringComparison and StringComparer give you fast, correct behavior. We’ll cover Contains/StartsWith/EndsWith overloads, collection comparers, EF Core caveats, and SQL Server collations. Plus, a tiny benchmark to visualize the allocation difference.

Async Await Just Got A Massive Improvement in .NET

.NET 11 releases big updates to async/await and Nick covers it all in this YouTube video, including performance boosts.

.NET MAUI: C# Expressions in XAML: throw out your converters

Steven Thewissen shows how upcoming C# expressions in .NET MAUI XAML let you bind with {Name}, use real string interpolation, do inline math, and flip booleans without the usual converter circus, trimming boilerplate and multi-bindings. In this post he notes the feature rides on XAML source generation, is available today behind EnablePreviewFeatures in .NET 10, and even supports inline lambda handlers for quick interactions.