🔥 Pragmatic .NET Code Rules Course is on Presale - 40% off!BUY NOW

.NET 10 Extension

Apr 15 2025

This issue is self-sponsored.
By supporting my work and purchasing my products, you directly help me keep this newsletter free and continue creating high-quality, practical .NET content for the community. 

 

Thank you for the support 🙌  

 

P.S. I’m currently building a new course, Pragmatic .NET Code Rules, focused on creating a predictable, consistent, and self-maintaining .NET codebase using .editorconfig, analyzers, Visual Studio code cleanup, and CI enforcement.

 

The course is available for pre-sale until the official release, with early-bird pricing for early adopters.
You can find all the details here.

 
 

New "extension" keyword in .NET 10

 
 

With .NET 10 extension feature now you can define extension blocks for any type. It is shaping up to be one of the most exciting updates in recent years - and one of the most underrated gems is the new extension keyword introduced in C# 14 (Preview 3).

 

If you thought extension methods were powerful before, this takes things to a whole new level.

 

In this article, I’ll break down:
• What the new extension feature does
• Why it matters
• Real-world use cases you couldn’t solve cleanly before
• And how it changes the way we organize logic around existing types

 
 

Wait, what’s wrong with Extension Methods?

 
 

With the new syntax, you can define extension blocks for any type.
These blocks allow:

 

• Extension properties
• Private backing fields inside the extension scope
• Grouped logic in a clean and local context

 

Syntax:
C#
public static class MyExtensions { extension(TargetType instance) { public ReturnType PropertyOrMethod => ...; } extension static { public static ReturnType StaticHelper() => ...; } }

 
 

Real-World Use Case: Multi-Tenant SaaS and HttpContext

 
 

Let’s say you’re building a multi-tenant SaaS product. You need to:

 

• Extract the TenantId from claims
• Parse and validate the UserId
• Check if the user is a tenant admin
• Read custom headers
• Expose defaults and validation logic

 

The old way? You’d create scattered static methods.
The new way? One structured block with everything grouped and cached.
C#
public static class MultiTenantHttpContextExtensions { extension(HttpContext ctx) { private string? _tenantId; private Guid? _userId; public string TenantId => _tenantId ??= ctx.User.Claims.FirstOrDefault(c => c.Type == "tenant_id")?.Value ?? throw new UnauthorizedAccessException("Tenant ID missing"); public Guid UserId => _userId ??= Guid.TryParse( ctx.User.Claims.FirstOrDefault(c => c.Type == "user_id")?.Value, out var id) ? id : throw new UnauthorizedAccessException("User ID invalid"); public bool IsTenantAdmin => ctx.User.IsInRole("Admin") || ctx.Request.Headers["X-Tenant-Admin"] == "true"; public string? GetHeader(string name) => ctx.Request.Headers.TryGetValue(name, out var value) ? value.ToString() : null; } extension static { public static string DefaultTenantId => "public"; public static bool IsValidTenantId(string? id) => !string.IsNullOrWhiteSpace(id) && id.All(char.IsLetterOrDigit); } }
This approach brings:
• Readable, organized logic
• Lazy caching via private fields (tenantId, userId)
• Cohesive domain logic scoped to the right context

 
 

Another Example: Extending External Models

 
 

Let’s say you’re working with a third-party DTO:
C#
public class OrderDto { public List<OrderItemDto> Items { get; set; } public string Status { get; set; } }

 

With new extensions, you can wrap domain logic around it without modifying the class:
C#
public static class OrderExtensions { extension(OrderDto order) { public decimal TotalAmount => order.Items.Sum(i => i.Quantity * i.PricePerUnit); public bool IsComplete => order.Status == "Completed"; public int TotalItems => order.Items.Sum(i => i.Quantity); } }
Usage becomes clean and expressive:

 

C#
if (order.TotalAmount > 1000 && order.IsComplete) { // Do something }

 
 

Why not just use methods from .NET 10?

 
 

Comparing with Extension Methods

This isn't just a cosmetic change - it's a paradigm shift in how we organize logic.

 
 

My Gotchas & Notes

 
 

• This is currently available in .NET 10 Preview 3 with C# 14
• Still being refined, so expect updates in syntax and tooling support
• All your existing extension methods continue to work - this is purely additive

 
 

My Advice

 
 

Use this when you’re extending a type with multiple behaviors that feel like they belong together:

 

• DTO transformations
• HTTP context and claims logic
• Computed values on external models
• Domain-specific enhancements (e.g., IsActive, TotalAmount, NeedsSync, etc.)

 

It keeps your logic close, clean, and cache-friendly - and once you start using it, you won’t want to go back.

 
 

Wrapping Up

 
 

The new extension keyword isn’t flashy at first glance. But it solves a real pain point for developers who care about clean architecture, rich domain modeling, and maintainable code.
It gives us the power we didn’t even know we were missing in C# - and it’s just the beginning of a new era of expressiveness.

 

Let me know if you'd like to see how I plan to use this in:

 

• CQRS helpers
• ViewModel builders
• ASP.NET Core service pipelines

 

Because I already note what I can refactor for some of my older projects.

 

That's all from me today.

 

P.S. Follow me on YouTube.

About the Author

Stefan Djokic is a Microsoft MVP and senior .NET engineer with extensive experience designing enterprise-grade systems and teaching architectural best practices.

There are 3 ways I can help you:

My Design Patterns Ebooks

1. Design Patterns that Deliver

This isn’t just another design patterns book. Dive into real-world examples and practical solutions to real problems in real applications.Check out it here.


1. Design Patterns Simplified

Go-to resource for understanding the core concepts of design patterns without the overwhelming complexity. In this concise and affordable ebook, I've distilled the essence of design patterns into an easy-to-digest format. It is a Beginner level. Check out it here.


Join TheCodeMan.net Newsletter

Every Monday morning, I share 1 actionable tip on C#, .NET & Arcitecture topic, that you can use right away.


Sponsorship

Promote yourself to 18,000+ subscribers by sponsoring this newsletter.



Join 18,000+ subscribers to improve your .NET Knowledge.

Powered by EmailOctopus

Subscribe to
TheCodeMan.net

Subscribe to the TheCodeMan.net and be among the 18,000+ subscribers gaining practical tips and resources to enhance your .NET expertise.

Powered by EmailOctopus