C# 11 is on the way! What's new C# 11 | C# 11 new Features

C# 11 is on the way!  What's new C# 11 | C# 11 new Features

 Microsoft recently released C# 10 and .NET in 2021, and now they already started working on C# 11 and .NET 7 with new features.

 So in this article we'll take a look at some of the upcoming C# 11 features .

.Net 7 Preview 1 was released on February 17, and along with it,  previewed some of the new features in C# 11. 



These are currently preview features. You must set <LangVersion> to preview to enable these features. Any feature may change before its final release. These features may not all be released in C# 11. Some may remain in a preview phase for longer based on feedback on the feature.


C#11 Allow newlines in the “holes” of interpolated strings

To introduce this new feature that C# 11 will bring, we have to keep in mind that C# currently supports two types of intepolated strings:


  • Verbatim interpolated: $@""
  • Non-verbatim interpolated: $""

What is a verbatim character?

A verbatim string literal consists of an @ character followed by a double-quote character, zero or more characters, and a closing double-quote character. A simple example is @"hello".

This does not happen in non-verbatim interpolated strings; in these cases escape characters (such as /r/n) are used.

But now inNon-verbatim Interpolation new line allowed

NewLine in Non-verbatim Interpolation

Consider the following code.

var CompanyInfo= new
    Name = "DotnetOffice",
    city = "Bangalore"
var _ = $"Company info : {CompanyInfo.Name}";

Previously, in C# 10, the code would not compile. You were not allowed to use newline in non-verbatim ($"")string interpolations. This restriction has been removed now allowing you to define newline in non-verbatim string interpolation.


Generic Attribute

With C# 11, the .Net framework has provided a way for developers to write their own custom generic attribute.

For example,

public class CustomeAttribute<T>:Attribute
    public T CoustomeProperty {get;set;}
    public CoustomeAttribute<T>(T CoustomeValue) => CoustomeProperty = CoustomeValue;
As per Microsoft Article Generic attribute is
 You can declare a generic class whose base class is System.Attribute. This provides a more convenient syntax for attributes that require a System.Type parameter. Previously, you'd need to create an attribute that takes a Type as its constructor parameter:

// Before C# 11:
public class TypeAttribute : Attribute
   public TypeAttribute(Type t) => ParamType = t;

   public Type ParamType { get; }

And to apply the attribute, you use the typeof operator:

public string Method() => default;

Using this new feature, you can create a generic attribute instead:

C#11 feature:
public class GenericAttribute<T> : Attribute { }

Then, specify the type parameter to use the attribute:

[GenericAttribute<string>()] public string Method() => default;

You must supply all type parameters when you apply the attribute. In other words, the generic type must be fully constructed.

public class GenericType<T>
   [GenericAttribute<T>()] // Not allowed! generic attributes must be fully constructed types.
   public string Method() => default;

The type arguments must satisfy the same restrictions as the typeof operator. Types that require metadata annotations aren't allowed. For example, the following types aren't allowed as the type parameter:

  • dynamic
  • nintnuint
  • string? (or any nullable reference type)
  • (int X, int Y) (or any other tuple types using C# tuple syntax).

These types aren't directly represented in metadata. They include annotations that describe the type. In all cases, you can use the underlying type instead:

  • object for dynamic.
  • IntPtr instead of nint or unint.
  • string instead of string?.
  • ValueTuple<int, int> instead of (int X, int Y).

NotNull checks

Previously in .Net 10, the .Net framework introduced a new and cleaner way of handling nulls checks in preconditions.

public void Company(string name)


    if (name is null)

{ throw new ArgumentNullException(nameof(name)); }


In C# 11, Microsoft introducing the "!!" operator. The above code could now be rewritten as

public void Company(string name!!)


    // Logic


List patterns

Here is another new feature which is introduce by Microsoft team the new list pattern. What it allows us to do in C#11 is to compare with arrays and lists.

the slice pattern can be written like, for example, another list pattern, such as the var pattern, in order to capture the contents of the slice.

Let's look at Microsoft's example:

The pattern [1, 2, .., 10] matches all of the following:

int[] arr1 = { 1, 2, 10 };
int[] arr1 = { 1, 2, 5, 10 };
int[] arr1 = { 1, 2, 5, 6, 7, 8, 9, 10 };


Now list patterns can be written like below:

public static int CheckSwitch(int[] values)
    => values switch
        [1, 2, .., 10] => 1,
        [1, 2] => 2,
        [1, _] => 3,
        [1, ..] => 4,
             [..] => 50

C# 11 conclusion

November 2021 Microsoft officially released .NET 6 and C# 10, and now microsoft is coming with C#11 with .Net 7 and there can be more changes as well.