I tried the new C# 11 features – Here are my useful takeaways

NET category image

.NET Conf 2022 is over and Microsoft released .NET 7 together with C# 11. Here are the new features and my opinion of them.

C# 11 is finally here!

Microsoft published a blog post as well as a video of the corresponding session of .NET Conf 2022 about the release. I’ll show the new stuff and add my opinion to it.

UTF-8 string literals

C# strings are UTF-16 by default. So to get a UTF-8 string the previous way was

System.Text.Encoding.UTF8.GetBytes("I am a string!"); // returns byte[]

Now you can do the following

"I am a string!"u8; // returns ReadOnlySpan<byte>

This might become quite handy for some developers because it’s much faster and easier to write. I like it although I will rarely use it. See the documentation for all details. ?

Raw string literals

First, we had strings. Then, we got string literals. And now, we have raw string literals. The newest addition has no escape characters, so everything is printed as it is. See the following code example:

var @string = "I say \\\\\\"Hello\\\\\\"";        // prints I say \\"Hello\\"
var stringLiteral = @"I say \\""Hello\\""";       // prints I say \\"Hello\\"
var rawStringLiteral = """I say \\"Hello\\" """;  // prints I say \\"Hello\\"

Raw string literals start with 3 double quotes and end with 3 double quotes. If you want to use 3 double quotes in the string, just use 4 as a suffix and a prefix (always one more ?).

You can also use it for multiline strings and indentation. See the examples below:

Multiline raw string literals in C#11 with indentation.
Multiline raw string literals in C#11 with indentation.

This is actually quite awesome! I always struggled with escaping in JSON file strings but that’s gone now. ?

Join my free Medium Newsletter!

Get an overview of my new Medium content with my monthly newsletter. Save time and pick what you like to read!

Abstracting over static members

Interfaces can have static members denoted with the abstract keyword (documentation). This forces the implementing class to provide a static method with a matching signature. However, you can’t define a method body like it is possible for non-static abstract interface methods.

public interface IMyInterface
	  public static abstract void ImplementMe();

public class MyClass : IMyInterface
    public static void ImplementMe()

That’s also pretty cool and I’ll gladly use it to enforce a static constructor for classes to instantiate new objects. ?

List patterns

List patterns are the newest member in the pattern-matching family in C#. In combination with the slice pattern .. you can do some crazy things with it as the examples in the documentation show:

Console.WriteLine(new[] { 1, 2, 3, 4, 5 } is [> 0, > 0, ..]);   // True
Console.WriteLine(new[] { 1, 1 } is [_, _, ..]);                // True
Console.WriteLine(new[] { 0, 1, 2, 3, 4 } is [> 0, > 0, ..]);   // False
Console.WriteLine(new[] { 1 } is [1, 2, ..]);                   // False
Console.WriteLine(new[] { 1, 2, 3, 4 } is [.., > 0, > 0]);      // True
Console.WriteLine(new[] { 2, 4 } is [.., > 0, 2, 4]);           // False
Console.WriteLine(new[] { 2, 4 } is [.., 2, 4]);                // True
Console.WriteLine(new[] { 1, 2, 3, 4 } is [>= 0, .., 2 or 4]);  // True
Console.WriteLine(new[] { 1, 0, 0, 1 } is [1, 0, .., 0, 1]);    // True
Console.WriteLine(new[] { 1, 0, 1 } is [1, 0, .., 0, 1]);       // False

I am not quite sure what use cases this will have. As you can see, the code is totally unreadable and wouldn’t pass a code review. Maybe I just don’t see the benefits yet, but for now, I don’t intend to use this feature. If you know some use cases, share them! ?

Required members

As a Flutter/Dart developer, I am already familiar with the concept of a required keyword. The compiler can enforce the assignment of properties either through the constructor or an object initializer (docs).

Compiler warning when using the required keyword without proper initialization in C#11
Compiler warning when using the required keyword without proper initialization in C#11

Very useful in my opinion. It ensures that important properties always contain values. But it won’t guarantee good values also it’s also possible to use required on every property which will circumvent the point of the feature. ?


That’s my short and sweet overview of C#11. What are your takeaways?

Related articles