Every feature is tagged with what it is for rather than which version it arrived in. Use this when you know the kind of problem you have - "this allocation is in a hot loop" - rather than the release you need to target.
All 158 feature pages are tagged, and most carry more than one tag, so a feature can appear under several headings.
Jump to a tag
- Code reduction (66)
- Readability (43)
- Correctness (35)
- Performance (30)
- New scenarios (17)
- Type safety (15)
- Code generation (7)
- Interop (6)
- Discovery (4)
- Extensibility (3)
- Concurrency (1)
Code reduction
Features that remove boilerplate you had to write before.
- Anonymous methods C# 2.0 - Create a delegate using an inline function body.
- Delegate covariance and contravariance C# 2.0 - Allow a delegate to point at a method whose parameters or return type are less or more derived than the delegate's signature.
- Null-coalescing operator C# 2.0 - Provide a default value when an expression is null.
- Anonymous types C# 3.0 - Create objects without explicitly defining a type.
- Auto implemented properties C# 3.0 - Declare properties without explicit backing fields.
- Collection initializers C# 3.0 - Populate collections inline during construction.
- Implicitly typed local variables C# 3.0 - Declare variables with
varso the compiler infers the type. - Object initializers C# 3.0 - Set property values when creating an object.
- Optional arguments C# 4.0 - Define default values for method parameters to make them optional.
- Caller info attributes C# 5.0 - Provide parameter attributes to capture information about the caller of a method.
- Auto property initializer C# 6.0 - Allow auto-implemented properties to have an initial value.
- Expression bodied members C# 6.0 - Declare members using
=>arrow functions. - Index initializers C# 6.0 - Allow indexers to be set from object or collection initializers.
- Null-conditional operators C# 6.0 - Safely access members on potentially null objects.
- String interpolation C# 6.0 - Build formatted strings with in-place evaluation.
- using static C# 6.0 - Import static members as top-level functions.
- Deconstruction C# 7.0 - Extract tuple and property values from objects.
- Expanded expression bodied members C# 7.0 - Allow the
=>syntax for constructors, finalizers, and get/set accessors. - Out variables C# 7.0 - Declare out parameters inline.
- Pattern matching C# 7.0 - Pattern match expressions for type and value checking.
- Throw expressions C# 7.0 - Throw exceptions in more convenient ways.
- Tuples C# 7.0 - Group multiple values without creating a dedicated type.
- Async main C# 7.1 - Use
asyncandawaitdirectly inProgram.Main. - Default literals C# 7.1 - Use
defaultwithout specifying the type explicitly. - Generic type pattern matching C# 7.1 - Use pattern matching with generic type constraints.
- Inferred tuple element names C# 7.1 - Infer tuple element names from variable names.
- Conditional ref expressions C# 7.2 - Use the conditional operator with ref returns and ref locals.
- Non-trailing named arguments C# 7.2 - Use named arguments in any position when positional arguments follow.
- Expression variables in initializers C# 7.3 - Use
out varand pattern variables in field initializers, constructor initializers, and LINQ queries. - Ref reassignment C# 7.3 - Point an existing ref local or ref parameter at a different variable.
- Stackalloc array initializers C# 7.3 - Initialize stackalloc arrays with inline values.
- Tuple equality operators C# 7.3 - Compare tuples directly using
==and!=operators. - Null coalescing assignment C# 8.0 - A short syntax for assigning a value to an object if it is null.
- Property pattern C# 8.0 - Match against object properties within pattern matching expressions.
- Ranges and indices C# 8.0 - Use
..and^operators to slice collections and access elements from the end. - Recursive pattern matching C# 8.0 - Match against properties and nested object structures in patterns.
- stackalloc in nested expressions C# 8.0 - Allow a stackalloc expression anywhere an expression is permitted, not just as a direct initializer.
- Switch expressions C# 8.0 - A switch designed to return values directly within a method.
- Switch tuple pattern C# 8.0 - Match against multiple values simultaneously using tuple patterns.
- Using declarations C# 8.0 - Simplify disposable resource management without nesting.
- Pattern matching improvements C# 9.0 - Enhanced pattern matching with relational, logical, and simplified type patterns.
- Records C# 9.0 - Declare immutable types and eliminate boilerplate code.
- Target-typed conditional expression C# 9.0 - Eliminate casts in conditional operations by considering the result type.
- Target-typed new C# 9.0 - Use new without a type if the compiler can infer it.
- Top-level statements C# 9.0 - Skip Program.Main() for a script-like experience.
- Caller argument expressions C# 10.0 - Allow methods to capture the code passed in an argument at compile time.
- Constant interpolated strings C# 10.0 - Allow constant strings to use string interpolation.
- Extended property patterns C# 10.0 - Allow property sub-patterns to reference nested members.
- Lambda improvements C# 10.0 - Add attributes, explicit return types, and natural type inference to lambdas.
- Parameterless struct constructors C# 10.0 - Allow structs to have parameterless constructors.
- Record structs C# 10.0 - Allow records to be value type structs.
- with expressions for structs C# 10.0 - Create modified copies of structs and anonymous types using with expressions.
- Auto-default structs C# 11.0 - The compiler auto-initializes unassigned struct fields in constructors.
- List patterns C# 11.0 - Match arrays and lists against sequences of patterns.
- Raw string literals C# 11.0 - Allow strings containing newlines and quotes without escaping.
- Unsigned right shift operator C# 11.0 - Shift the bits of an integer to the right ignoring the sign.
- Alias any type C# 12.0 - Use the alias directive to give names to types like tuples.
- Collection expressions C# 12.0 - A short syntax for initializing collections.
- Default lambda parameters C# 12.0 - Allow a lambda's parameters to specify default values.
- Primary constructors C# 12.0 - Define a constructor and backing fields with a short syntax.
- Allow params to use collections C# 13.0 - The params keyword no longer has to use an array but can use other collection types.
- Field keyword C# 14.0 - Reference the synthesized backing field of an auto property using the field keyword.
- Implicit span conversions C# 14.0 - Implicitly convert arrays and strings to spans without explicit casting.
- Simple lambda parameters with modifiers C# 14.0 - Use parameter modifiers without specifying types in simple lambda syntax.
- Collection expression arguments C# 15.0 - Pass capacity, comparers and other constructor arguments from inside a collection expression.
- Labeled break and continue C# 15.0 - Break out of or continue an outer loop directly from inside nested loops.
Readability
Features that make the intent of existing code clearer.
- Delegate covariance and contravariance C# 2.0 - Allow a delegate to point at a method whose parameters or return type are less or more derived than the delegate's signature.
- Null-coalescing operator C# 2.0 - Provide a default value when an expression is null.
- Implicitly typed local variables C# 3.0 - Declare variables with
varso the compiler infers the type. - Lambda expressions C# 3.0 - Create inline functions using concise
=>arrow syntax. - Object initializers C# 3.0 - Set property values when creating an object.
- Query expressions C# 3.0 - Provide a native query syntax reminiscent of SQL.
- Named arguments C# 4.0 - Specify method parameters by name instead of position.
- Asynchronous members C# 5.0 - Provide
asyncandawaitoperations to simplify Task-based operations. - Exception filters C# 6.0 - Conditionally catch exceptions based on a boolean expression.
- String interpolation C# 6.0 - Build formatted strings with in-place evaluation.
- Binary literals C# 7.0 - Allow numeric literals to be written in binary.
- Digit separators C# 7.0 - Allow numeric literals to contain the
_character as a visual aid. - Discards C# 7.0 - Signal that values are intentionally being ignored.
- Pattern matching C# 7.0 - Pattern match expressions for type and value checking.
- Throw expressions C# 7.0 - Throw exceptions in more convenient ways.
- Numeric literal leading underscores C# 7.2 - Allow underscores to be used before the first digit in a numeric literal.
- Tuple equality operators C# 7.3 - Compare tuples directly using
==and!=operators. - Property pattern C# 8.0 - Match against object properties within pattern matching expressions.
- Ranges and indices C# 8.0 - Use
..and^operators to slice collections and access elements from the end. - Switch expressions C# 8.0 - A switch designed to return values directly within a method.
- Switch tuple pattern C# 8.0 - Match against multiple values simultaneously using tuple patterns.
- Using declarations C# 8.0 - Simplify disposable resource management without nesting.
- Init-only setters C# 9.0 - Specify properties that can only be set during construction.
- Lambda discard parameters C# 9.0 - Signify no interest in a parameter to a lambda.
- Pattern matching improvements C# 9.0 - Enhanced pattern matching with relational, logical, and simplified type patterns.
- Target-typed new C# 9.0 - Use new without a type if the compiler can infer it.
- Constant interpolated strings C# 10.0 - Allow constant strings to use string interpolation.
- Extended property patterns C# 10.0 - Allow property sub-patterns to reference nested members.
- File-scoped namespaces C# 10.0 - Allow a namespace to be specified for an entire file to reduce indentation.
- global using directives C# 10.0 - Specify common using directives to be used across all source files.
- with expressions for structs C# 10.0 - Create modified copies of structs and anonymous types using with expressions.
- Extended nameof scope C# 11.0 - Use nameof with method parameters in attributes on that method.
- List patterns C# 11.0 - Match arrays and lists against sequences of patterns.
- Newlines in string interpolations C# 11.0 - Allow newlines inside interpolated string expression holes.
- Pattern match Span on string constants C# 11.0 - Use pattern matching to compare a Span of characters against a string literal.
- Raw string literals C# 11.0 - Allow strings containing newlines and quotes without escaping.
- Collection expressions C# 12.0 - A short syntax for initializing collections.
- Character literal escape sequence C# 13.0 - A new
\eescape sequence for character literals. - Implicit index access C# 13.0 - Allow the
^from-end operator to be used in object initializers. - Method group natural type improvements C# 13.0 - Method groups are now more likely to identify the correct method.
- Null-conditional assignment C# 14.0 - Conditionally assign values with
?.just like reading values. - Extension indexers C# 15.0 - Add indexers to existing types from an extension block.
- Labeled break and continue C# 15.0 - Break out of or continue an outer loop directly from inside nested loops.
Correctness
Features that let the compiler catch a mistake you could previously make.
- Iterators C# 2.0 - Produce and consume sequences.
- Nullable value types C# 2.0 - Give value-types "null" semantics to indicate missing values.
- Pragma directives C# 2.0 - Use
#pragma warningto selectively suppress or restore compiler warnings. - Foreach variable capture fix C# 5.0 - Each iteration of
foreachnow captures its own copy of the loop variable. - Exception filters C# 6.0 - Conditionally catch exceptions based on a boolean expression.
- nameof operator C# 6.0 - Capture the name of a variable, type or member at compile time.
- Discards C# 7.0 - Signal that values are intentionally being ignored.
- Local function statements C# 7.0 - Allow functions to be declared inside other functions.
- Out variables C# 7.0 - Declare out parameters inline.
- Pattern matching C# 7.0 - Pattern match expressions for type and value checking.
- In parameter modifiers C# 7.2 - Pass parameters by reference without allowing modifications.
- Private protected access modifier C# 7.2 - Restrict access to derived types within the same assembly.
- readonly struct C# 7.2 - Declare immutable value types that cannot be modified after creation.
- ref readonly method returns C# 7.2 - Return references that cannot be modified by the caller.
- Null-forgiving operator C# 8.0 - Suppress nullable reference type warnings when you know a value isn't null.
- Nullable reference types C# 8.0 - Allow use of reference types to be declared nullable or non-nullable.
- readonly instance members C# 8.0 - Allow struct members that do not modify state to be annotated as such.
- Static local functions C# 8.0 - Allow local functions to be declared static so they do not capture the class.
- Init-only setters C# 9.0 - Specify properties that can only be set during construction.
- Lambda discard parameters C# 9.0 - Signify no interest in a parameter to a lambda.
- Records C# 9.0 - Declare immutable types and eliminate boilerplate code.
- Checked user-defined operators C# 11.0 - Define checked versions of user-defined operators for overflow-aware arithmetic.
- Extended nameof scope C# 11.0 - Use nameof with method parameters in attributes on that method.
- Required members C# 11.0 - Require members to be set by initializers.
- Static interface members C# 11.0 - Allow members of an interface to be static abstract or virtual.
- Experimental attribute C# 12.0 - An annotation attribute to signal areas that are experimental.
- ref readonly parameters C# 12.0 - Allow parameters to be passed by reference without being modified.
- Character literal escape sequence C# 13.0 - A new
\eescape sequence for character literals. - Implicit index access C# 13.0 - Allow the
^from-end operator to be used in object initializers. - Method group natural type improvements C# 13.0 - Method groups are now more likely to identify the correct method.
- Field keyword C# 14.0 - Reference the synthesized backing field of an auto property using the field keyword.
- Unbound generic types and nameof C# 14.0 - Use the
nameofkeyword with generic definitions. - Closed hierarchies C# 15.0 - Mark a class as closed so only types in its own assembly can derive from it, enabling exhaustive switches.
- Memory safety C# 15.0 - Pointer relaxations, requires-unsafe members and unsafe expressions tie unsafe to the operations that access memory.
- Union types C# 15.0 - Declare a type that holds exactly one of several case types, with exhaustive switch checking.
Performance
Features that avoid an allocation, a copy or a virtual call.
- Ref local variable C# 7.0 - Create a reference to the original value.
- Ref return C# 7.0 - Return references to variables instead of copies of values.
- In parameter modifiers C# 7.2 - Pass parameters by reference without allowing modifications.
- ref readonly method returns C# 7.2 - Return references that cannot be modified by the caller.
- ref struct C# 7.2 - Declare stack-only value types that cannot be allocated on the heap.
- Ref reassignment C# 7.3 - Point an existing ref local or ref parameter at a different variable.
- Stackalloc array initializers C# 7.3 - Initialize stackalloc arrays with inline values.
- Unmanaged generic type constraints C# 7.3 - Constrain generic types to unmanaged types only.
- Pattern-based using and disposable ref structs C# 8.0 - Support using statements for types that offer a Dispose method without implementing IDisposable.
- readonly instance members C# 8.0 - Allow struct members that do not modify state to be annotated as such.
- stackalloc in nested expressions C# 8.0 - Allow a stackalloc expression anywhere an expression is permitted, not just as a direct initializer.
- Static local functions C# 8.0 - Allow local functions to be declared static so they do not capture the class.
- Unmanaged constructed types C# 8.0 - Allow a generic type built from unmanaged type arguments to satisfy the unmanaged constraint.
- Function pointers C# 9.0 - Call methods through pointers without delegate allocations in performance-critical code.
- Skip locals init C# 9.0 - Prevent the CLR from zeroing local variables for performance.
- Static anonymous functions C# 9.0 - Prevent an anonymous function from capturing state.
- Interpolated string handlers C# 10.0 - Replace interpolated string expressions with handlers to optimize performance.
- Pattern match Span on string constants C# 11.0 - Use pattern matching to compare a Span of characters against a string literal.
- ref fields and scoped ref C# 11.0 - Allow ref fields inside ref struct types and control ref lifetime with scoped.
- Unsigned right shift operator C# 11.0 - Shift the bits of an integer to the right ignoring the sign.
- UTF-8 string literals C# 11.0 - Allow literal strings to be stored as UTF-8 instead of UTF-16.
- Inline arrays C# 12.0 - Annotate a struct with InlineArray for optimized performance.
- ref readonly parameters C# 12.0 - Allow parameters to be passed by reference without being modified.
- Allow params to use collections C# 13.0 - The params keyword no longer has to use an array but can use other collection types.
- allows ref struct C# 13.0 - Allow ref struct types to be used as generic type arguments.
- New lock object C# 13.0 - A new disposable System.Threading.Lock type optimized for modern lock statements.
- ref and unsafe in iterators and async C# 13.0 - Allow ref locals and unsafe blocks in iterator and async methods.
- Implicit span conversions C# 14.0 - Implicitly convert arrays and strings to spans without explicit casting.
- User-defined compound assignment C# 14.0 - Define custom behavior for compound assignment operators like += and -=.
- Collection expression arguments C# 15.0 - Pass capacity, comparers and other constructor arguments from inside a collection expression.
New scenarios
Features that make something possible that was not possible before.
- Expression trees C# 3.0 - Represent code as data structures for analysis or transformation.
- Lambda expressions C# 3.0 - Create inline functions using concise
=>arrow syntax. - Dynamic binding C# 4.0 - Defer type checking until runtime using the dynamic keyword.
- Asynchronous members C# 5.0 - Provide
asyncandawaitoperations to simplify Task-based operations. - Auto-implemented property field attributes C# 7.3 - Allow attributes to be applied to the hidden backing field of auto-implemented properties.
- Async streams C# 8.0 - Create and consume streams asynchronously.
- Pattern-based using and disposable ref structs C# 8.0 - Support using statements for types that offer a Dispose method without implementing IDisposable.
- Attributes on local functions C# 9.0 - Apply attributes to local functions and their parameters.
- Module initializers C# 9.0 - Run code in an assembly when it is first loaded.
- Native integers C# 9.0 - Provide architecture-specific integer types.
- ref fields and scoped ref C# 11.0 - Allow ref fields inside ref struct types and control ref lifetime with scoped.
- allows ref struct C# 13.0 - Allow ref struct types to be used as generic type arguments.
- ref and unsafe in iterators and async C# 13.0 - Allow ref locals and unsafe blocks in iterator and async methods.
- File-based app directives C# 14.0 - New preprocessor directives for configuring file-based apps.
- User-defined compound assignment C# 14.0 - Define custom behavior for compound assignment operators like += and -=.
- Closed hierarchies C# 15.0 - Mark a class as closed so only types in its own assembly can derive from it, enabling exhaustive switches.
- Union types C# 15.0 - Declare a type that holds exactly one of several case types, with exhaustive switch checking.
Type safety
Features that narrow what a type is allowed to hold.
- Friend assemblies C# 2.0 - Use
InternalsVisibleToto exposeinternalmembers to specific assemblies. - Generics C# 2.0 - Write type-safe code that works with multiple data types.
- Nullable value types C# 2.0 - Give value-types "null" semantics to indicate missing values.
- Property accessor accessibility C# 2.0 - Specify different access modifiers on a property's
getandsetaccessors. - Static classes C# 2.0 - Declare a class as
staticto prevent instantiation and ensure only static members. - Embedded interop types C# 4.0 - Embed COM interop type information directly into assemblies.
- Generic contravariant C# 4.0 - Mark a generic type parameter with
inso a less derived type argument can be used. - Generic covariant C# 4.0 - Mark a generic type parameter with
outso a more derived type argument can be used. - Enum and Delegate generic constraints C# 7.3 - Constrain generic type parameters to
System.EnumorSystem.Delegate. - Covariant returns C# 9.0 - Allow a method to return a more specific type than the method it overrides.
- Native integers C# 9.0 - Provide architecture-specific integer types.
- Checked user-defined operators C# 11.0 - Define checked versions of user-defined operators for overflow-aware arithmetic.
- Generic attributes C# 11.0 - Allow attributes to take generic type arguments for strong typing.
- Static interface members C# 11.0 - Allow members of an interface to be static abstract or virtual.
- Alias any type C# 12.0 - Use the alias directive to give names to types like tuples.
Code generation
Features aimed at generators and tooling rather than hand-written code.
- Partial types C# 2.0 - Split type definitions between files to separate generated and human-written code.
- Partial methods C# 3.0 - Define a method signature in a partial class for implementation elsewhere.
- Extending partial methods C# 9.0 - Partial methods can have return values and out parameters.
- File local types C# 11.0 - Restrict a type so it can only be referenced from the file it is declared in.
- Interceptors C# 12.0 - Allow a method to declare it replaces another method.
- Partial properties & indexers C# 13.0 - Allow properties and indexers to be partially defined like partial methods.
- Partial events and constructors C# 14.0 - Allow constructors and events to be partially defined like partial methods and properties.
Interop
Features for working with other languages, runtimes and platforms.
- Extern alias C# 2.0 - Disambiguate types with the same fully-qualified name from different assemblies.
- Dynamic binding C# 4.0 - Defer type checking until runtime using the dynamic keyword.
- Embedded interop types C# 4.0 - Embed COM interop type information directly into assemblies.
- Unmanaged constructed types C# 8.0 - Allow a generic type built from unmanaged type arguments to satisfy the unmanaged constraint.
- Function pointers C# 9.0 - Call methods through pointers without delegate allocations in performance-critical code.
- Memory safety C# 15.0 - Pointer relaxations, requires-unsafe members and unsafe expressions tie unsafe to the operations that access memory.
Discovery
Features that surface information from the compiler.
- Extension methods C# 3.0 - Add methods to existing types without modifying them.
- global using directives C# 10.0 - Specify common using directives to be used across all source files.
- Extension members C# 14.0 - Add properties to existing classes just like extension methods.
- Extension indexers C# 15.0 - Add indexers to existing types from an extension block.
Extensibility
Features for adding behaviour to types you do not own.
- Default interface methods C# 8.0 - Allow interfaces to evolve by providing default implementations of methods.
- Extension GetEnumerator C# 9.0 - Extension methods allow foreach to enumerate over new types.
- Overload resolution priority C# 13.0 - Allow library authors to guide which overload is preferred using an attribute.
Concurrency
Features that change how code runs in parallel.
- New lock object C# 13.0 - A new disposable System.Threading.Lock type optimized for modern lock statements.