C# 11
The biggest wins in everyday code usually come from raw string literals and required members.
Back to overview
Section titled “Back to overview”Raw string literals
Section titled “Raw string literals”Raw string literals are much easier to read when a string contains quotes, braces, JSON, SQL, or regex-like content.
var json = """{ "name": "Ada", "role": "Engineer"}""";Legacy style:
var json = "{\"name\":\"Ada\",\"role\":\"Engineer\"}";Required members
Section titled “Required members”Required members ensure important properties are supplied during initialization.
public class ConnectionSettings{ public required string ConnectionString { get; init; } public required string DatabaseName { get; init; }}Usage:
var settings = new ConnectionSettings{ ConnectionString = "...", DatabaseName = "Main"};This helps avoid partially initialized objects.
List patterns
Section titled “List patterns”List patterns make it easy to inspect array and list shapes.
if (values is [1, 2, ..]){ Console.WriteLine("Starts with 1, 2");}This is often clearer than manually checking Count and indexing into the collection.
Generic attributes
Section titled “Generic attributes”Generic attributes remove the need to pass a Type object in some attribute scenarios.
[MyValidator<Order>]public class CreateOrderCommand{}This can make attribute usage more strongly typed and easier to refactor.
UTF-8 string literals
Section titled “UTF-8 string literals”UTF-8 string literals are useful when APIs work directly with UTF-8 bytes.
ReadOnlySpan<byte> header = "Content-Type"u8;This can avoid an encoding step compared to starting from a UTF-16 string.