C# 1.0 (Visual Studio.NET)
- Classes
- Structs
- Interfaces
- Events
- Properties
- Delegates
- Expressions
- Statements
- Attributes
- Literals
- Dispose in foreach
- foreach over string specialization
C# 2 (VS 2005)
- Generics
- Partial types
- Anonymous methods
- Iterators
- Nullable types
- Getter/setter separate accessibility
- Method group conversions (delegates)
- Static classes
- Delegate inference
C# 3 (VS 2008)
- Implicitly typed local variables
- Object and collection initializers
- Auto-Implemented properties
- Anonymous types
- Extension methods
- Query expressions
- Lambda expression
- Expression trees
- Partial methods
C# 4 (VS 2010)
- Dynamic binding
- Named and optional arguments
- Co- and Contra-variance for generic delegates and interfaces
- Embedded interop types ("NoPIA")
C# 5 (VS 2012)
- Asynchronous methods
- Caller info attributes
C# 6 (VS 2015)
- Draft Specification online
- Compiler-as-a-service (Roslyn)
- Import of static type members into namespace
- Exception filters
- Await in catch/finally blocks
- Auto property initializers
- Default values for getter-only properties
- Expression-bodied members
- Null propagator (null-conditional operator, succinct null checking)
- String interpolation
- nameof operator
- Dictionary initializer
C# 7.0 (Visual Studio 2017)
- Out variables
- Pattern matching
- Tuples
- Deconstruction
- Discards
- Local Functions
- Binary Literals
- Digit Separators
- Ref returns and locals
- Generalized async return types
- More expression-bodied members
- Throw expressions
C# 7.1 (Visual Studio 2017 version 15.3)
- Async main
- Default expressions
- Reference assemblies
- Inferred tuple element names
- Pattern-matching with generics
C# 7.2 (Visual Studio 2017 version 15.5)
- Span and ref-like types
- In parameters and readonly references
- Ref conditional
- Non-trailing named arguments
- Private protected accessibility
- Digit separator after base specifier
System.Enum,System.Delegateandunmanagedconstraints.- Ref local re-assignment: Ref locals and ref parameters can now be reassigned with the ref assignment operator (
= ref). - Stackalloc initializers: Stack-allocated arrays can now be initialized, e.g.
Span<int> x = stackalloc[] { 1, 2, 3 };. - Indexing movable fixed buffers: Fixed buffers can be indexed into without first being pinned.
- Custom
fixedstatement: Types that implement a suitableGetPinnableReferencecan be used in afixedstatement. - Improved overload candidates: Some overload resolution candidates can be ruled out early, thus reducing ambiguities.
- Expression variables in initializers and queries: Expression variables like
out varand pattern variables are allowed in field initializers, constructor initializers and LINQ queries. - Tuple comparison: Tuples can now be compared with
==and!=. - Attributes on backing fields: Allows
[field: …]attributes on an auto-implemented property to target its backing field.
- Nullable reference types: express nullability intent on reference types with
?,notnullconstraint and annotations attributes in APIs, the compiler will use those to try and detect possiblenullvalues being dereferenced or passed to unsuitable APIs. - Default interface members: interfaces can now have members with default implementations, as well as static/private/protected/internal members except for state (ie. no fields).
- Recursive patterns: positional and property patterns allow testing deeper into an object, and switch expressions allow for testing multiple patterns and producing corresponding results in a compact fashion.
- Async streams:
await foreachandawait usingallow for asynchronous enumeration and disposal ofIAsyncEnumerable<T>collections andIAsyncDisposableresources, and async-iterator methods allow convenient implementation of such asynchronous streams. - Enhanced using: a
usingdeclaration is added with an implicit scope andusingstatements and declarations allow disposal ofrefstructs using a pattern. - Ranges and indexes: the
i..jsyntax allows constructingSystem.Rangeinstances, the^ksyntax allows constructingSystem.Indexinstances, and those can be used to index/slice collections. - Null-coalescing assignment:
??=allows conditionally assigning when the value is null. - Static local functions: local functions modified with
staticcannot capturethisor local variables, and local function parameters now shadow locals in parent scopes. - Unmanaged generic structs: generic struct types that only have unmanaged fields are now considered unmanaged (ie. they satisfy the
unmanagedconstraint). - Readonly members: individual members can now be marked as
readonlyto indicate and enforce that they do not modify instance state. - Stackalloc in nested contexts:
stackallocexpressions are now allowed in more expression contexts. - Alternative interpolated verbatim strings:
@$"..."strings are recognized as interpolated verbatim strings just like$@"...". - Obsolete on property accessors: property accessors can now be individually marked as obsolete.
- Permit
t is nullon unconstrained type parameter