What’s New in C# 13 for Developers?
Tags: web, blazor, csharp, development
Published: 2024-06-19 13:08:08

---
title: What’s New in C# 13 for Developers?
published: true
date: 2024-06-13 14:05:05 UTC
tags: web, blazor, csharp, development
canonical_url: https://www.syncfusion.com/blogs/post/whats-new-csharp-13-for-developers
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l1z4yyuc3upx2fqb03if.jpeg
---

**TL;DR:** Explore the latest features in C# 13! From enhanced params collections to modernized thread synchronization, discover how these updates can boost your coding efficiency and productivity. Dive in and revolutionize your development experience!

Welcome to our blog about the exciting new features introduced in [C# 13](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13 "Article: What's new in C# 13")! This latest version of C# brings a host of enhancements and innovations designed to empower developers to write cleaner, more efficient, and expressive code.

We’ll delve into the key features and updates that C# 13 offers. From enhanced params collections to the convenience of new escape sequences, C# 13 is packed with tools that make coding more intuitive and productive.

Let’s see them in detail!

## Key highlights of C# 13

Following are some of the key highlights of C# 13 **:**

- [Enhanced params collections](#Enhanced)
- [Modernized thread synchronization with lock](#Modernized)
- [Auto properties with custom logic](#Auto)
- [New escape sequence for **ESCAPE** character](#New)
- [Implicit index access in object initializers](#Implicit)
- [Extension for everything: Methods, properties, indexers, and static members](#Extension)
- [Optimized method group natural type](#Optimized)

## Prerequisites

To experiment with these features firsthand, you’ll need the latest version of [Visual Studio 2022](https://visualstudio.microsoft.com/vs/ "Visual Studio 2022") or the [.NET 9 Preview SDK](https://dotnet.microsoft.com/en-us/download/dotnet/9.0 "Download .NET 9.0"). Both options provide access to C# 13’s cutting-edge functionalities.

## <a name="Enhanced">Enhanced params collections</a>

The **params** keyword was previously restricted to arrays; now, it embraces a wider range of collection types. You can use it with **System.Span\<T\>,**  **System.ReadOnlySpan\<T\>,** and collections implementing **System.Collections.Generic.IEnumerable\<T\>** and possessing an **Add** method. Additionally, interfaces like **System.Collections.Generic.IEnumerable\<T\>,**  **System.Collections.Generic.IReadOnlyCollection\<T\>,** and more can be utilized with **params**. This flexibility streamlines parameter passing for various collection scenarios.

### Support for ReadOnlySpan\<T\>

In C# 13, the support for **ReadOnlySpan\<T\>** has been enhanced to allow collection expressions to work directly with this high-performance struct. **ReadOnlySpan\<T\>** is a type-safe and memory-safe read-only representation of a contiguous region of arbitrary memory. It is allocated on the stack and can never escape to the managed heap, which helps avoid allocations and improves performance. Collection expressions can now work directly with **ReadOnlySpan\<T\>,** a high-performance struct that avoids allocations. This enhancement is particularly beneficial for applications that require optimal performance.

#### Benefits of ReadOnlySpan\<T\>

- **Avoids allocations:** Since **ReadOnlySpan\<T\>** is a stack-allocated struct, it avoids heap allocations, which can benefit performance-critical applications.
- **Memory safety:** It provides a type-safe way to handle memory, ensuring you do not accidentally modify the underlying data.
- **Versatility:** **ReadOnlySpan\<T\>** can point to managed memory, native memory, or memory managed on the stack, making it versatile for various scenarios.

Consider a scenario where you need to initialize a collection efficiently.  
**C#**

```csharp
public void AddScores(params int[] scores)
{
    var scoresCollection = new int[] { 75, 88, 92 };
    AddScores(scoresCollection);
}
```

In C# 13, you can achieve this with better performance using **ReadOnlySpan\<T\>**.

```csharp
public void AddScores(ReadOnlySpan<int> scores)
{
    foreach (var score in scores)
    {
        // Process scores without allocations
    }
}
```

This is useful for apps that need optimal performance, such as real-time systems, game development, and high-frequency trading applications.

### Support for IEnumerable\<T\>

The **params** keyword has been enhanced to work with **IEnumerable\<T\>**, allowing you to pass collections directly to methods that accept a variable number of arguments. This enhancement improves the flexibility and usability of the **params** keyword.

Refer to the following code example.

```csharp
using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        // Using params with IEnumerable<T>.
        AddItems(new List<int> { 1, 2, 3, 4, 5 });
    }

    // Method accepting params with IEnumerable<T>.
    public static void AddItems(params IEnumerable<int>[] collections)
    {
        foreach (var collection in collections)
        {
            foreach (var item in collection)
            {
                Console.WriteLine(item);
            }
        }
    }
}
```

## <a name="Modernized">Modernized thread synchronization with lock</a>

C# 13 introduces the **System.Threading.Lock** type, designed to improve thread synchronization practices. It boasts a superior API compared to the traditional **System.Threading.Monitor** approach.

### Key features

- **Exclusive execution scope:** The **Lock.EnterScope()** method establishes an exclusive execution scope. This ensures that only one thread executes the code within the scope at a time.
- **Dispose of pattern:** The returned **ref**  **struct** from **Lock.EnterScope()** supports the **Dispose()** pattern, allowing a graceful exit from the scope. This ensures that the lock is released even if an exception occurs.
- **Integration with lock statement:** The C# lock statement now recognizes when the target is a lock object and uses the updated API. This integration simplifies the code and improves thread safety.

### Benefits

- **Improved thread safety:** By using the Lock type, developers can achieve better synchronization and avoid common pitfalls associated with thread contention.
- **Code maintainability:** The new API makes the code more readable and maintainable, reducing the complexity of thread synchronization.

## <a name="Auto">Auto properties with custom logic</a>

Auto properties have been a convenient feature since C# 3, but they have limitations. Specifically, adding custom logic to the getters or setters required reverting to full property syntax, which meant more boilerplate code. C# 13 introduces a significant enhancement to auto-properties, which can now include custom logic directly within their getters and setters.  
Let’s explain this with the following code example. Consider a scenario where you want to ensure that a date property is always set to the current date if the provided value is in the past.

```csharp
using System;

public class Event
{
    private DateTime eventDate;

    public DateTime EventDate
    {
        get => eventDate;
        set => eventDate = value < DateTime.Now ? DateTime.Now : value;
    }
}

public class Program
{
    public static void Main()
    {
        Event myEvent = new Event();
        
        // Setting a past date.
        myEvent.EventDate = new DateTime(2020, 1, 1);
        Console.WriteLine(myEvent.EventDate); // Outputs current date

        // Setting a future date.
        myEvent.EventDate = new DateTime(2025, 1, 1);
        Console.WriteLine(myEvent.EventDate); // Outputs 2025-01-01
    }
}
```

With the auto property, you can implement custom logic directly within the property definition, reducing the need for backing fields and keeping your code concise and readable.

## <a name="New">New escape sequence for ESCAPE character</a>

C# 13 introduces a more convenient way to represent the **ESCAPE** character ( **Unicode U+001B** ) within character literals. This new feature allows developers to use the **\e** escape sequence instead of the older methods, **\u001B** or **\x1B**. This enhancement simplifies code readability and reduces potential errors associated with hexadecimal interpretations.

Before C# 13, representing the **ESCAPE** character required using either the Unicode escape sequence **\u001B** or the hexadecimal escape sequence **\x1B**. These methods could be less readable and more prone to errors, especially if the following characters were valid hexadecimal digits.

**C#**

```csharp
char escapeChar1 = '\u001B'; // Using Unicode escape sequence.
char escapeChar2 = '\x1B'; // Using hexadecimal escape sequence.
```

With C# 13, you can now use the **\e** escape sequence to represent the **ESCAPE** character. This new method is more intuitive and reduces the likelihood of errors.

**C# 13**

```csharp
char escapeChar = '\e'; // Using the new escape sequence.
```

### Benefits

- **Improved readability:** The **\e** escape sequence is more concise and easier to read compared to **\u001B** or **\x1B**.
- **Reduced errors:** Using **\e** minimizes the risk of errors that can occur with hexadecimal interpretations, where subsequent characters might be misinterpreted as part of the escape sequence.
- **Consistency:** The new escape sequence aligns with other common escape sequences, making the code more consistent and easier to understand.

## <a name="Implicit">Implicit index operator in object initializers</a>

C# 13 permits using the implicit **“from the end” index operator (****^****)** within object initializer expressions. This lets you initialize arrays directly from the end, as showcased in the following example.

```csharp
var countdown = new TimerRemaining()
{
    buffer =
    {
         = 0,
         = 1,
         = 2,
        // ... (continues to 9)
    }
};
```

This code snippet initializes an array containing values from 9 down to 0, achieving a countdown effect. Before C# 13, initializing arrays from the end within object initializers wasn’t possible.

## <a name="Extension">Extension for everything: Methods, properties, indexers, and static members</a>

C# 13 expands the concept of extension methods to a new level by including properties, indexers, and static methods. This comprehensive extension mechanism enhances code discoverability and usability, making it easier for developers to extend existing types with additional functionality without modifying the source code.

### Extension methods

Extension methods have existed since C# 3. They allow us to add new methods to existing types without altering their definitions. These methods are defined as static methods in static classes, and the **“this”** keyword specifies the type they extend.

```csharp
public static class StringExtensions
{
    public static bool IsNullOrEmpty(this string str)
    {
        return string.IsNullOrEmpty(str);
    }
}
```

### Extension properties

C# 13 introduces extension properties, enabling developers to add new properties to existing types. This allows for more intuitive and readable code.

In the following code example, the **Age** property is defined as an extension property for the **DateTime** type. It calculates the age based on the birth date and the current date. The extension property is defined within a static class **DateTimeExtensions**. This is a requirement for extension methods and properties.

```csharp
public static class DateTimeExtensions
{
    public static int Age(this DateTime birthDate)
    {
        var today = DateTime.Today;
        int age = today.Year - birthDate.Year;
        if (birthDate.Date > today.AddYears(-age)) age--;
        return age;
    }
}
```

The **“this”**  keyword before the **birthDate** parameter indicates that the **Age** property is an extension property for the **DateTime** type. This property calculates the age by subtracting the birth year from the current year. It also adjusts the age if the birth date is not yet in the current year.

### Extension indexers

With C# 13, you can now define extension indexers, allowing you to add custom indexing behavior to existing types.

In the following code example, we’ve shown how to create an extension indexer for the **List\<T\>** type that retrieves elements from the end of the list.

```csharp
public static class ListExtensions
{
    public static T GetFromEnd<T>(this List<T> list, int indexFromEnd)
    {
        return list[list.Count - indexFromEnd - 1];
    }
}
```

This extension indexer allows you to access elements from the end of the list using a zero-based index, making it easier to work with lists in reverse order. For example, **list.GetFromEnd(0)** will return the last element, the **list.GetFromEnd(1)** will return the second-to-last element, and so on.

### Extension static members

C# 13 also supports extension static members, enabling the addition of static methods to existing types.

In the following code example, we’ve shown how to create an extension static method for the double type that calculates the square of a given value.

```csharp
public static class MathExtensions
{
    public static double Square(this double value)
    {
        return value * value;
    }
}
```

This extension static method allows you to call the **Square** method directly on a double value, making the code more intuitive and readable.

### Benefits

- **Enhanced code discoverability:** By extending existing types with additional functionality, developers can make their code more discoverable and easier to understand.
- **Improved usability:** Extension properties, indexers, and static members provide a more intuitive way to interact with types, making the code readable and maintainable.
- **Separation of concerns:** Extension members allow developers to add functionality without modifying the source code, promoting a cleaner separation of concerns.

## <a name="Optimized">Optimized method group natural type</a>

C# 13 introduces an optimized approach for method group natural type resolution, refining the overload resolution process involving method groups. This feature enhances performance and aligns more closely with the overall overload resolution algorithm.

In earlier versions of C#, when the compiler encountered a method group, it would generate a complete list of candidate methods for that group. If a “natural type” was required, it was determined based on the entire set of candidate methods. This approach could be inefficient, especially when dealing with large sets of methods or complex generic constraints.

C# 13 streamlines this process by progressively eliminating inapplicable methods at each scope. This includes:

- **Scope-by-scope evaluation:** The compiler now considers candidate methods scope-by-scope, starting with instance methods and moving to each subsequent scope of extension methods.
- **Pruning inapplicable methods:** The compiler prunes methods with no chance of succeeding early in the process. This includes:
  - **Generic methods with incorrect arity:** The methods will be eliminated, if they contain a different number of type arguments than the required.
  - **Unsatisfied constraints:** Generic methods that do not satisfy their constraints are also pruned.

By eliminating inapplicable methods earlier, the compiler reduces the number of candidate methods that need to be considered, improving the efficiency of the overload resolution process.

## Conclusion

Thanks for reading! C# 13 delivers compelling enhancements that empower developers to write more streamlined, robust, and expressive code. These features offer significant advantages for various development scenarios, from the versatility of params collections to the improved lock object and the convenience of the new escape sequence.

It continues to evolve by refining existing features and introducing new capabilities that enhance productivity and performance. We encourage you to explore and incorporate these new features into your C# projects to elevate your coding experience. Let’s embrace these exciting changes and continue to build amazing software together. Happy coding!

The latest version of [Essential Studio](https://www.syncfusion.com/forums/188642/essential-studio-2024-volume-2-main-release-v26-1-35-is-available-for-download "Essential Studio 2024 Volume 2")—Syncfusion’s collection of eighteen-hundred-plus UI components and frameworks for mobile, web, and desktop development—is available for current customers from the [License and Downloads](https://www.syncfusion.com/account "Essential Studio License and Downloads page") page. If you are not a Syncfusion customer, you can start a 30-day [free trial](https://www.syncfusion.com/downloads "Free evaluation of the Essential Studio products") to try all the components at Syncfusion dot com slash downloads.

If you have questions, contact us through our [support forums](https://www.syncfusion.com/forums "Syncfusion Support Forums"), [support portal](https://support.syncfusion.com/ "Syncfusion Support Portal"), or [feedback portal](https://www.syncfusion.com/feedback/ "Syncfusion Feedback Portal") at [Syncfusion](https://www.syncfusion.com/ "Syncfusion Offical site"). We are always happy to assist you!

## Related blogs

- [Syncfusion HelpBot: Simplified Assistance for Syncfusion Components](https://www.syncfusion.com/blogs/post/syncfusion-helpbot-assistance "Blog: Syncfusion HelpBot: Simplified Assistance for Syncfusion Components")
- [Syncfusion Essential Studio 2024 Volume 2 Is Here!](https://www.syncfusion.com/blogs/post/syncfusion-essential-studio-2024-vol2 "Blog: Syncfusion Essential Studio 2024 Volume 2 Is Here!")
- [Introducing the 12th Set of New .NET MAUI Controls and Features](https://www.syncfusion.com/blogs/post/syncfusion-dotnet-maui-2024-volume-2 "Blog: Introducing the 12th Set of New .NET MAUI Controls and Features")
- [What’s New in .NET MAUI Charts: 2024 Volume 2](https://www.syncfusion.com/blogs/post/dotnet-maui-charts-2024-volume-2 "Blog: What’s New in .NET MAUI Charts: 2024 Volume 2")