C# has added many new keywords, syntax elements, and features since its introduction.

Feature Keyword/Syntax Version

Anonymous methods

⌨️ delegate

2.0

Asynchronous members

⌨️ async ⌨️ await

5.0

Asynchronous streams

async IAsyncEnumerable<T> Method( … )

8.0

Discards

_

7.0

Dynamic binding

⌨️ dynamic

4.0

Exceptions: Exception filters

catch (ExceptionType e) when expression

6.0

Exceptions: Throw expressions

expr ? expr : throw exception 🔹 x ?? throw exception 🔹 Member ⇒ throw exception

7.0

Expression bodied members

Member expression; // method, operator, or read-only property

6.0

Expression bodied members: Expanded

// constructors, finalizers, indexers, and all properties now supported

7.0

Extension: Blocks

⌨️ extension(TypeName) { }

14.0

Extension: Methods

Method(this Type param)

3.0

Function pointers

⌨️ delegate

9.0

Generics

Type<T> and 🏷️ System.Collections.Generic

2.0

Generics: INumber

🏷️ INumber<T>

11.0

Global usings

global using Namespace ;

10.0

Indices and ranges

^.. 🏷️ System.Index 🏷️ System.Range

8.0

Initialization: Anonymous types

new { }

3.0

Initialization: Implicitly typed local variables

⌨️ var

3.0

Initialization: Index initializers

✨ new Dictionary< type , type > { [value] = value, }

6.0

Initialization: Index reverse

var a = new int[] { [^3] = 0, [^2] = 1, [^1] = 2, }; // [0, 1, 2]

13.0

Initialization: Initializers

new Type { … } 🔹 new CollectionType { item, item, item, … }

3.0

Initialization: Required

required fieldOrProperty

11.0

Initialization: Target typed new

// new() doesn’t require a type name when inferrable

9.0

Interfaces: Default methods

// provide interface method implementations to inherit

8.0

Interfaces: Static virtual

static virtual or abstract virtual

11.0

Iterators

⌨️ yield return

2.0

Lambda expressions

params expression

3.0

Lambda expressions: Attributes

var name = [Attribute] paramsexpression ;

10.0

Lambda expressions: Discard params

(_) ⇒ expression

9.0

Lambda expressions: Natural type

var name = paramsexpression ; // or name as object, Delegate, &c

10.0

Lambda expressions: Param defaults

(int index = 1) ⇒ arrayValues[index]

12.0

Lambda expressions: Param modifiers

// Untyped params can be scoped, ref, in, out, or ref readonly

14.0

Lambda expressions: Return type

var name = returntype paramsexpression ;

10.0

Literals: Binary literals

0b10011

7.0

Literals: Collection expressions

[1, 2, 3, 4, ..arrayValues]

12.0

Literals: Default literals

⌨️ default

7.1

Literals: Digit separators

7_000_000

7.0

Literals: Escape escape

"\e" // U+001B Escape control character

13.0

Literals: Raw strings

// multiline, multiquoted, indented string literals

11.0

Literals: UTF-8 strings

"string literal"u8

11.0

Local functions

type Name() { type OtherName() { … } … OtherName(); }

7.0

Local functions: Attributes

// attributes are allowed before local functions

9.0

Local functions: Extern

// local functions may be marked as extern

9.0

Local functions: Static

// local functions can now be static

8.0

Module initializers

[ModuleInitializer] Method() { … }

9.0

Multithreading: New lock object

🏷️ System.Threading.Lock

13.0

Nameof operator

⌨️ nameof()

6.0

Nameof operator: Generics

nameof(GenericType<T>)

14.0

Native sized integers

⌨️ nint // System.IntPtr ⌨️ nuint // System.UIntPtr

9.0

Nesting: File scoped namespaces

namespace Name ;

10.0

Nesting: Top level statements

// statements in one source file outside any containing method imply program entry point

9.0

Nesting: Using declarations

using var x = disposble; // applies to end of scope

8.0

Nulls: Null forgiving operator

!

8.0

Nulls: Null propagator

✨ x?.member ✨ x?[expression]

6.0

Nulls: Null-coalescing assignment

??=

8.0

Nulls: Null-conditional assignment

object.?property = _value 🔹 object?[index] = value

14.0

Nulls: Nullable types

🏷️ Nullable<T>Type?

2.0

Nulls: Nullable types: Reference types

// reference types may not be null without ?, and require null-checking with it

8.0

Operators: Checked/unchecked

checked or unchecked

11.0

Operators: Compound assignment

void operator+() { } 🔹 void operator=(type other) { } 🔹 …

14.0

Parameters: Caller info attributes

🏷️ CallerFilePathAttribute 🏷️ CallerLineNumberAttribute 🏷️ CallerMemberNameAttribute

5.0

Parameters: Caller info attributes: Expression

🏷️ CallerArgumentExpressionAttribute

10.0

Parameters: In parameters

⌨️ in

7.2

Parameters: Named arguments

Method( paramName: value)

4.0

Parameters: Non-trailing named arguments

// named params can precede unnamed ones that are in the right position

7.2

Parameters: Params collections

Method(params IEnumerable<string> strings)

13.0

Parameters: Out variables

Method(out var param)

7.0

Parameters: Ref readonly parameters

⌨️ ref readonly

12.0

Partial classes

⌨️ partial class ⌨️ partial interface ⌨️ partial struct

2.0

Partial constructors

public partial TypeName();

14.0

Partial events

public partial event EventHandler? OnEvent;

14.0

Partial methods

⌨️ partial TypeName Method( … );

3.0

Pattern matching

expression is pattern // or is not 🔹 switch(expression) { case pattern: … }

7.0

Pattern matching: Character spans

charSpan is "string literal"

11.0

Pattern matching: Conjunction

x is pattern and pattern

9.0

Pattern matching: Disjunction

x is pattern or pattern

9.0

Pattern matching: Lists

value is [1, 2, 3, _, 5, ..]

11.0

Pattern matching: Negation

x is not pattern // not just types

9.0

Pattern matching: Parentheses

x is ( patterns ) and ( patterns )

9.0

Pattern matching: Properties

expression is { Property: value }

8.0

Pattern matching: Properties: Extended

expression is { Property.Subproperty: value }

10.0

Pattern matching: Relational

x is > value // or >= < ⇐

9.0

Pattern matching: Switch expressions

expression switch { patternvalue, … }

8.0

Pattern matching: Tuples

expression is ( value/identifier , …)

8.0

Pattern matching: Type variables

x is type

9.0

Properties: Auto properties

Property { get; set; }

3.0

Properties: Auto properties: Initializers

Property { get; set; } = value;

6.0

Properties: Field

⌨️ public type PropertyName { get; set ⇒ field = value; }

14.0

Properties: Init only setters

Property { get; init; }

9.0

Query expressions

⌨️ from item in Items where item != null orderby item select item

3.0

Readonly members

⌨️ readonly Method

8.0

Records

⌨️ record

9.0

Records: Record structs

record struct

10.0

Static imports

using static Namespace.StaticClassName ;

6.0

Static lambdas and anonymous funcions

// lambdas and anonymous functions may be static

9.0

String interpolation

✨ $"…{expression}…"

6.0

String interpolation: Braces

$$""{"value": "{{value}}"}"" // multiple $ add extra { } for interpolation

11.0

String interpolation: Const

const string name = $"…{constantexpr}…";

10.0

String interpolation: Custom handler

🏷️ InterpolatedStringHandlerAttribute

10.0

String interpolation: Newlines

// newlines allowed within interpolation expressions

11.0

String interpolation: Verbatim enhancement

✨ @$"…" (previously only $@"…" worked)

8.0

Struct initializers

Property { get; init; } = value ;

10.0

Suppress emitting localsinit

🏷️ SkipLocalsInitAttribute

9.0

Tuples: Deconstruction

(type, …) x = (value, …); // or with (_type PropertyName, …)

7.0

Tuples: Inferred element names

list.Select(x ⇒ (x.Id, x.Name)).Where(y ⇒ y.Id == 1)

7.1

Types: Alias any type

using stringset = System.Collections.Generic.HashSet<string>;

12.0

Types: Experimental attribute

[Experimental] class MyClass { [Experimental] void Method() { … } }

12.0

Types: Pointer aliases

nint or nuint

11.0

Types: Primary constructors

class MyClass(int id, string name) { … }

12.0

Visibility: File scope

file class MyClass

11.0

Legend

  • ⌨️ new keyword

  • ✨ new syntax

  • 🏷️ new type

Sources