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

Exploring C# 13

Nov 23 2024

Sponsored

• Boost your .NET development with dotConnect — ADO.NET data providers for the major databases and popular cloud services. It offers reliable updates, expert developer support, and full compatibility with ORMs like EF Core, Dapper, NHibernate, LinqConnect, etc.

Join Devart’s Black Friday sale to get 30% OFF. Join Devart’s Black Friday sale to get 30% OFF.

• Tired of outdated API documentation holding your team back? Postman simplifies your life by automatically syncing documentation with your API updates - no more static docs, no more guesswork! Read more.

Many thanks to the sponsors who make it possible for this newsletter to be free for readers. Become a sponsor.

The Background

C# 13 continues the evolution of Microsoft’s flagship programming language, introducing a range of features aimed at improving code expressiveness, developer productivity, and overall performance. This text explores five impactful features of C# 13, compares them with prior versions (C# 12), and explains why these additions are game-changers for developers.

1. Enhanced params Collections

What’s New in C# 13?

Traditionally, the params keyword allowed methods to accept a variable number of arguments, but it was limited to arrays. With C# 13, params can now be applied to any collection type, such as List, Span, or IEnumerable.

Example in C# 13:

C#
public void PrintNumbers(params List<int> numbers){ foreach (var number in numbers) { Console.WriteLine(number); }} // UsagePrintNumbers(new List<int> { 1, 2, 3 });

How It Was Done in C# 12:

C#
public void PrintNumbers(params int[] numbers){ foreach (var number in numbers) { Console.WriteLine(number); }} // UsagePrintNumbers(1, 2, 3); // Could only use arrays directly.

Why It’s Useful: The flexibility of params collections allows developers to use more versatile and modern collection types, avoiding unnecessary array conversions and simplifying APIs.

2. The New System.Threading.Lock

What’s New in C# 13?

C# 13 introduces the System.Threading.Lock type, a streamlined way to synchronize access to shared resources. The new Lock.EnterScope() method makes the critical section easier to manage, leveraging the Dispose pattern to automatically release the lock.

Example in C# 13:

C#
Lock myLock = new Lock();using (myLock.EnterScope()){ // Critical section Console.WriteLine("Thread-safe code here.");}

How It Was Done in C# 12:

C#
private static readonly object _lock = new object(); void ThreadSafeMethod(){ lock (_lock) { // Critical section Console.WriteLine("Thread-safe code here."); }}

Why It’s Useful: The new Lock type reduces boilerplate code and minimizes the risk of forgetting to release the lock, preventing deadlocks and improving code clarity.

3. The New Escape Sequence \e

What’s New in C# 13?

C# 13 introduces the escape sequence \e to represent the ESCAPE character. This addition is particularly beneficial for terminal-based applications that rely on ANSI escape codes for formatting.

Example in C# 13:

C#
Console.WriteLine("\e[1mThis is bold text\e[0m");

How It Was Done in C# 12: In previous versions, developers had to use hardcoded values or char codes:

C#
Console.WriteLine("\x1b[1mThis is bold text\x1b[0m");

Why It’s Useful: The \e escape sequence improves readability and reduces errors when working with ANSI codes, making terminal-based development more accessible.

4. Implicit Index Access in Object Initializers

What’s New in C# 13?

C# 13 enhances object initializers by allowing implicit "from the end" index operators (^). This feature simplifies operations on collections by enabling intuitive access to the last elements.

Example in C# 13:

C#
var numbers = new int[5] { 1, 2, 3, 4, 5 };var initializer = new List<int> { [^1] = 10 }; // Sets the last element to 10

How It Was Done in C# 12:

C#
var numbers = new int[5] { 1, 2, 3, 4, 5 };var initializer = new List<int> { 1, 2, 3, 4, 5 };initializer[initializer.Count - 1] = 10; // Manually set the last element.

Why It’s Useful: Implicit indexing makes code cleaner and less error-prone, reducing the likelihood of off-by-one mistakes in array and list manipulation.

5. Support for ref and unsafe in Async Methods and Iterators

What’s New in C# 13?

C# 13 allows ref locals and unsafe code in async methods and iterators. Previously, these features were restricted in asynchronous contexts.

Example in C# 13:

C#
public async Task ProcessDataAsync(){ Span<byte> buffer = stackalloc byte[1024]; // Unsafe context await Task.Delay(1000);}

How It Was Done in C# 12: This was not supported directly. Developers had to split logic into separate synchronous methods:

C#
void ProcessData(){ Span<byte> buffer = stackalloc byte[1024]; // Unsafe context} // Asynchronous wrapperpublic async Task ProcessDataAsync(){ await Task.Run(() => ProcessData());}

Why It’s Useful: This feature streamlines asynchronous programming by allowing low-level memory manipulation and unsafe code directly in async methods, improving performance and reducing code fragmentation.

For earlier features, see 5 Features in C# 12 and Source Generators Deep Dive.

Wrapping Up

C# 13 introduces a powerful set of features that simplify code, enhance expressiveness, and improve performance.

Whether you're working with advanced threading, terminal applications, or asynchronous methods, these enhancements make C# 13 a significant step forward.

By comparing these new features with their counterparts in C# 12, it's clear that C# 13 reduces boilerplate code, minimizes errors, and empowers developers to write cleaner, more efficient applications.

If you haven’t started exploring C# 13 yet, now is the perfect time to dive in!

That's all from me today. 

See ya on the next Monday coffee. 


Want to enforce clean code automatically? My Pragmatic .NET Code Rules course shows you how to set up analyzers, CI quality gates, and architecture tests - a production-ready system that keeps your codebase clean without manual reviews. Or grab the free Starter Kit to try it out.

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:

1. Pragmatic .NET Code Rules Course

Stop arguing about code style. In this course you get a production-proven setup with analyzers, CI quality gates, and architecture tests — the exact system I use in real projects. Join here.

Not sure yet? Grab the free Starter Kit — a drop-in setup with the essentials from Module 01.

2. Design Patterns Ebooks

Design Patterns that Deliver — Solve real problems with 5 battle-tested patterns (Builder, Decorator, Strategy, Adapter, Mediator) using practical, real-world examples. Trusted by 650+ developers.

Just getting started? Design Patterns Simplified covers 10 essential patterns in a beginner-friendly, 30-page guide for just $9.95.

3. Join 20,000+ subscribers

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

Join 20,000+ subscribers who mass-improve their .NET skills with actionable tips on C#, Architecture & Best Practices.

Subscribe to
TheCodeMan.net

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