C# 13.0 – Important New Features
C# 13.0 was released in November 2024 alongside .NET 9. It introduced improvements in collections, thread synchronization, properties, and memory-safe programming.
1. params Collections
What is it?
Previously, params primarily supported arrays. C# 13 allows collection types such as Span<T>, ReadOnlySpan<T>, and suitable collection types.
Example:
void PrintNumbers(params IEnumerable<int> numbers)
{
foreach (int number in numbers)
{
Console.WriteLine(number);
}
}
PrintNumbers(10, 20, 30);
Explanation: We can pass multiple arguments without manually creating a collection.
Key Points:
-
Supports more collection types than earlier versions.
-
Reduces boilerplate code.
-
Useful for methods accepting variable numbers of arguments.
2. New lock Type (System.Threading.Lock)
What is it?
C# 13 introduces System.Threading.Lock, a dedicated synchronization type designed for efficient thread locking.
Example:
using System.Threading;
Lock _lock = new();
int counter = 0;
void Increment()
{
lock (_lock)
{
counter++;
}
}
Explanation: Only one thread can execute the protected code at a time using the same lock instance.
Key Points:
-
Helps prevent race conditions.
-
Designed for efficient synchronization.
-
Available in .NET 9 and later.
-
Prefer a dedicated
Lockinstance rather than locking onthisor a string.
3. Partial Properties
What is it?
C# 13 allows a property declaration and its implementation to be split across partial class definitions.
Example:
public partial class Employee
{
public partial string Name { get; set; }
}
public partial class Employee
{
private string _name = "";
public partial string Name
{
get => _name;
set => _name = value;
}
}
Explanation: The first declaration defines the property contract, while the second provides its implementation.
Key Points:
-
Useful in source generators.
-
Helps separate generated and manually written code.
-
Requires a partial type.
4. ref struct Interface Implementation
What is it?
Previously, ref struct types could not implement interfaces. C# 13 allows them to implement interfaces while preserving their stack-only restrictions.
Example:
interface IPrinter
{
void Print();
}
ref struct ReportPrinter : IPrinter
{
public void Print()
{
Console.WriteLine("Printing report");
}
}
ReportPrinter printer = new();
printer.Print();
Explanation: ReportPrinter implements IPrinter, but it cannot be boxed into an interface variable.
Key Points:
-
Enables interface-based contracts for
ref struct. -
Does not permit boxing.
-
Useful for high-performance, memory-sensitive code.
-
Generic code can use
allows ref structwhere appropriate.
5. ref and unsafe in Iterators and Async Methods
What is it?
C# 13 relaxes restrictions on using ref local variables and unsafe code inside iterator and async methods.
Example:
async Task PrintValueAsync()
{
int number = 100;
{
ref int value = ref number;
value = 200;
}
await Task.Delay(100);
Console.WriteLine(number);
}
Explanation: The ref local is used before await and does not cross the suspension point.
Key Points:
-
reflocals can be used in async and iterator methods under restrictions. -
They cannot remain in use across
awaitoryield returnboundaries. -
unsafecode is allowed in regions that do not contain suspension points. -
Useful for performance-oriented programming.
Quick Interview Revision
|
Feature |
Main Purpose |
|---|---|
|
|
Accept variable arguments using more collection types |
|
|
Efficient thread synchronization |
|
Partial Properties |
Separate property declaration and implementation |
|
|
Support interfaces without boxing |
|
|
Relax restrictions in async and iterator methods |
Interview priority: Focus first on System.Threading.Lock and params Collections. Partial properties and ref struct improvements are more relevant to advanced C# and performance-oriented development.