New Features And Improvements In C# 11

Introduction

C# 11 was released as part of .NET 6 in November 2022. .NET 6 is a major release of the .NET platform that includes a variety of new features and improvements, including enhancements to performance, security, and developer productivity. C# 11 was developed by Microsoft and its community contributors, introducing several new features and enhancements that make writing code in C# easier and more efficiently. These include file-scoped namespaces, global using directives, improved pattern matching, and extended support for top-level programs.

How to use C#11

To use C# 11, you need to install .NET 6 SDK or later on your development machine. Once you have the latest version of .NET installed, you can create new C# projects in Visual Studio or other supported IDEs and start using the new language features.

C# 11 is a significant release that brings many new features and improvements to the language. Developers can use these new features to write more efficient and maintainable code and take advantage of the latest capabilities of the .NET platform. Existing C# projects can also be updated to target C# 11 by changing the language version in the project properties to "C# latest minor version" or by explicitly setting the language version to "preview" and specifying the version number.

What's New in C# 11

C# 11 is the latest C# programming language version, released in November 2021. Here are some of the new features and improvements in C# 11:

1. File-scoped namespaces

Before C# 11, namespaces had to be defined in a namespace block at the beginning of every file in which they were used. This could lead to a lot of repetitive code, especially in larger projects.

With file-scoped namespaces, you can now define a namespace at the top of a file without needing to wrap your entire code file in a namespace block. The namespace is then automatically applied to all the code in that file, making it easier to organize and structure your code.

Here is an example of how you can define a file-scoped namespace in C# 11:

// File: Example.cs
namespace MyNamespace;

class MyClass
{
    // class implementation
}

In the above example, the MyNamespace namespace is defined at the top of the file, and the MyClass class is defined within that namespace. All the code in the file is automatically included in the MyNamespace namespace. File-scoped namespaces make writing and organizing your code easier, especially in larger projects, by reducing the amount of repetitive code you need to write.

2. Global using directives

Before C# 11, if you wanted to use a namespace in multiple files within a project, you had to add a using directive to each file individually. This could become cumbersome and repetitive, especially in large projects.

With global using directives, you can now specify using directives that are automatically included in all files in a project without needing to add them to each file individually. This can help reduce boilerplate code and make your code more concise and easier to read.

Here is an example of how you can define a global using directive in C# 11:

// File: GlobalUsings.cs
global using System;

// File: Example.cs
class MyClass
{
    // use System.Console.WriteLine without needing a using directive
    static void Main() => Console.WriteLine("Hello, world!");
}

In the above example, the System namespace is included as a global using directive in the GlobalUsings.cs file. This means that any file in the project can use the System namespace without needing to add a using directive. Global using directives can help make your code more concise and easier to read by reducing the boilerplate code you need to write.

3. Interpolated string improvements

C# 11 supports interpolated string handlers, allowing you to customize how interpolated strings are formatted. It also introduces support for interpolated string constants, allowing you to declare them as constants.

Interpolated strings allow you to embed expressions within string literals, making it easy to create strings that include dynamic values. Here are some of the improvements to interpolated strings in C# 11:

Interpolated string handlers

C# 11 allows you to define custom handlers that can be used to format interpolated strings. This allows you to customize how strings are interpolated, making it possible to do things like custom number formatting, localization, or custom escaping.

Interpolated string constants

C# 11 introduces support for interpolated string constants, which allow you to declare interpolated strings as constants. This makes it easier to reuse interpolated strings throughout your code without recreating them each time.

Verbatim interpolated strings

C# 11 allows you to create interpolated strings using verbatim string syntax (using the @$"..." syntax). This makes it easier to create strings that contain backslashes or other escape characters.

Here is an example of how you can use interpolated string handlers in C# 11:

// Define a custom handler for formatting numbers with a currency symbol
using System.Globalization;

namespace MyNamespace;

static class InterpolatedStringHandlers
{
    public static string Currency(this FormattableString formattable)
    {
        var culture = CultureInfo.CurrentCulture;
        var value = formattable.GetArgument(0);
        return value.ToString("C", culture);
    }
}

// Use the custom handler to format a currency value in an interpolated string
var value = 42.00m;
var formatted = $"{value:Currency()}";

The above example defines a custom handler that formats a number as a currency value. We use it in an interpolated string to format a decimal value as a currency value. Overall, the improvements to interpolated strings in C# 11 make them more flexible and powerful and allow you to customize how strings are interpolated to better fit your needs.

4. Improved pattern matching

C# 11 improves pattern matching with a new "or" operator that allows you to combine patterns and a new "not" operator to negate patterns. Pattern matching allows you to test whether an expression matches a specific pattern and to extract information from the expression if it does. Here are some of the improvements to pattern matching in C# 11:

Logical patterns

C# 11 introduces support for logical patterns, which allow you to combine multiple patterns using logical operators. This makes it easier to test for complex patterns that involve multiple conditions.

Relational patterns

C# 11 introduces support for relational patterns, which allow you to test whether an expression is greater than, less than, or equal to a specific value. This makes it easier to test for numeric or ordinal values.

Parenthesized patterns

C# 11 allows you to use parentheses to group patterns and control the order of evaluation. This makes writing complex patterns easier and avoids errors due to operator precedence.

Here is an example of how you can use logical patterns in C# 11:

// Test whether a value is between 10 and 20, inclusive
if (value is >= 10 and <= 20)
{
    Console.WriteLine("Value is between 10 and 20");
}

The above example uses a logical pattern to test whether a value is between 10 and 20 inclusive. The is keyword is used to test the pattern and the and operator is used to combine the range patterns. Overall, the improvements to pattern matching in C# 11 make it easier to work with complex data structures and patterns, and allow you to write more concise and readable code.

5. Enhanced lambda expressions

C# 11 supports target-typed new expressions in lambda expressions, which allows you to omit the type of object being created in the expression body. C# 11 does not introduce any significant changes to lambda expressions compared to C# 10. However, there are a few minor improvements related to lambda expressions that were introduced in C# 10 and are still available in C# 11:

  1. Lambda expressions can now be used in more contexts, such as in using statements, lock statements, and fixed statements.

  2. You can now use the |> operator (the "pipe operator") to chain multiple lambda expressions together. This makes it easier to write code that performs a sequence of operations on a value, such as filtering, mapping, and aggregating.

Here is an example of how you can use the pipe operator in C# 11,

var numbers = Enumerable.Range(1, 10);

var result = numbers
    .Where(x => x % 2 == 0)
    .Select(x => x * x)
    .Aggregate(0, (acc, x) => acc + x);

Console.WriteLine(result); // Output: 220

In the above example, we use a lambda expression to filter even numbers, another lambda expression to square each number, and a third lambda expression to aggregate the squared values into a single result. The pipe operator (|>) is used to chain the operations together in a readable and concise way. While these improvements are relatively minor, they can help make your code more concise and expressive and allow you to write more functional-style code with less ceremony.

6. Extended support for top-level programs

C# 9 introduced top-level programs, allowing you to write C# code without defining a class or a main method. C# 11 extends this support by allowing you to define additional members in a top-level program.

7. Performance improvements

C# 11 includes various performance improvements, such as reduced memory usage and faster code execution.

Summary

These are just some of the new features and improvements in C# 11. Overall, C# 11 introduces several enhancements that make writing code in C# easier and more efficiently.


Similar Articles