Here’s the List of All C# 11 Features.
Required MembersC# 11 introduces a new
required
modifier to fields & properties to impose constructors & callers to initialize those values.
A new SetsRequiredMembers
attribute on the constructor tells the compiler that it initializes all required members.
// Initializations with required properties var p1 = new Person { Name = "Shehryar", Surname = "Khan" }; Person p2 = new("Shehryar", "Khan"); // Initializations with missing required properties var p3 = new Person { Name = "Shehryar" }; Person p4 = new(); public class Person { public Person() {} [SetsRequiredMembers] public Person(string name, string surname) { Name = name; Surname = surname; } public Guid Id { get; set; } = Guid. NewGuid(); public required string Name { get; set; } public required string Surname { get; set; } }
C# 11 preview introduces raw string literals.
It allows containing of arbitrary text without escaping.
The format is minimum 3 double quotes """.."""
Combining with string interpolation, the count of $ denotes how many braces in a row start & end the interpolation.
C# 10 |
---|
string name = "Shehryar"; string surname = "Khan"; string jsonString = [email protected]" {{ 'Name': {name}, 'Surname': {surname} }} "; |
C# 11 |
---|
string name = "Shehryar"; string surname = "Khan"; string jsonString = $$""" { "Name": {{name}}, "Surname": {{surname}} } """; |
C# 11 preview introduces UTF-8 string literals.
It allows converting only UTF-8 characters to their byte representation at compile time.
C# 10 |
---|
byte[] array = Encoding.UTF8.GetBytes("Hello World"); |
C# 11 |
---|
byte[] array = "Hello World"; |
C# 11 preview introduces list patterns.
It expand pattern matching to match sequences of elements in a list or an array.
You can use list patterns with any pattern, including property, type, constant, & relational patterns.
var numbers = new [] { 1, 2, 3, 4 }; // List and constant patterns Console.WriteLine(numbers is [1, 2, 3, 4]); // True Console.WriteLine(numbers is [1, 2, 4]); // False // List and discard patterns Console.WriteLine(numbers is [_, 2, _, 4]); // True Console.WriteLine(numbers is [.., 3, _]); // True // List and logical patterns Console.WriteLine(numbers is [_, >=2, _, _]); // True
C# 11 preview introduces newlines in string interpolation.
It allows any valid C# code between { }, including newlines, to improve code readability.
It also helpfuls when you want to use longer C# expressions in interpolation, e.g. LINQ queries, pattern matching or switch expressions.
// switch expression in string interpolation int month = 5; string season = $"The season is { month switch { 1 or 2 or 12 => "winter", > 2 and < 6 => "spring", > 5 and < 9 => "summer", > 8 and < 12 => "autumn", - => "Unknown. Wrong month number", } }."; Console.WriteLine(season); // The season is spring. // LINQ query in string interpolation int[] numbers = new int[] { 1, 2, 3, 4, 5, 6 }; string message = $"The reversed even values of {nameof(numbers)} are { string.Join(", ", numbers.Where(n => n % 2 == 0) .Reverse()) }."; Console.WriteLine(message); // The reversed even values of numbers are 6, 4, 2.
The C# 11 compiler itself initializes any property or field not initialized by a constructor in the structs.
Such code doesn’t compile in the previous C# versions.
The compiler sets the default values.
C# 10 |
---|
struct Person { // Auto-implemented property 'Person.Age // must be fully assigned before control // is returned to the caller. public Person(string name) { Name = name; } public string Name { get; set; } public int Age { get; set; } } |
C# 11 |
---|
struct Person { public Person(string name) { Name = name; } public string Name { get; set; } public int Age { get; set; } } |
Span<char>
on a constant stringUsing pattern matching, we can test if the string has a certain constant value in C#.
C# 11 allows pattern matching a Span<char>
& ReadOnlySpan<char>
on a constant string.
C# 10 |
---|
ReadOnlySpan<char> strSpan = "SK".AsSpan(); if (strSpan == "SK") { Console.WriteLine("Hey, SK"); } |
C# 11 |
---|
ReadOnlySpan<char> strSpan = "SK".AsSpan(); if (strSpan is "SK") { Console.WriteLine("Hey, SK"); } |
C# 11 introduces the generic attributes.
C# 10 |
---|
class MyType { } class MyAttribute : Attribute { private Type type; public MyAttribute(Type type) { _type = type; } } [MyAttribute(typeof(MyType))] class Myclass {} |
C# 11 |
---|
class MyType { } class GenericAttribute<T> : Attribute where T : MyType { private T _type; } [GenericAttribute<MyType>] class MyClass { } |
C# 11 expand scope of nameof
expressions.
We can specify the name of a method parameter in an attribute on the parameter declaration or method.
This can be used in adding attributes for code analysis.
public class MyAttr : Attribute { private readonly string _paramName; public MyAttr(string paramName) { _paramName = paramName; } } public class MyClass { [MyAttr(nameof(param))] public void Method(int param, [MyAttr(nameof(param))] int anotherParam) { } }
C# 11 introduces an unsigned right-shift operator >>>.
It shifts bits right without replicating the high order bit on each shift.
int n = -32; Console.WriteLine($"Before shift: bin = {Convert.ToString(n, 2), 32}, dec = {n}"); int a = n >> 2; Console.WriteLine($"After >>: bin = {Convert.ToString(a, 2),32}, dec = {a}"); int b = n >>> 2; Console.WriteLine($"After >>>: bin = {Convert.ToString(b, 2),32}, dec = {b}"); // Output: // Before shift: bin = 11111111111111111111111111100000, dec = -32 // After >>: bin = 11111111111111111111111111111000, dec = -8 // After >>>: bin = 111111111111111111111111111000, dec = 1073741816
C# 11 introduces static abstract members in interfaces.
We can add static abstract members in interfaces to define interfaces that include other static members, overloadable operators, and static properties.
public interface IAdditionOperators<TSelf, TOther, TResult> where TSelf : IAdditionOperators<TSelf, TOther, TResult> { static abstract TResult operator +(TSelf left, TOther right); }
A little improvement in C# 11.
The nint
and nuint
types now alias System.IntPtr
and System.UIntPtr
respectively.
string str = "Hello!"; IntPtr intPtr = Marshal.StringToHGlobalAnsi(str); nint nInt = Marshal.StringToHGlobalAnsi(str); unsafe { byte* src = (byte*)intPtr.ToPointer(); byte* dst = (byte*)nInt.ToPointer(); }
That’s all for now. Thank you for reading. I have also list all .NET 7 Features. You must have a Look.
–
What’s coming with .NET 7?Quick Links
Legal Stuff
Social Media