C# language support status
dgrunwald opened this issue · 3 comments
Here we list recent C# language versions (> C# 6) and their implementation status in ILSpy. Older (completed) language versions can be found in the wiki.
- Language features that are checked are implemented in the current master branch of ILSpy and have a minimal test suite at least.
- Language features that are crossed out will likely never be implemented in the decompiler, either because
- they are not reproducible from compiled binaries (e.g. constant interpolated strings, Caller info attributes),
- or they are of limited use and would require too much work to implement in the decompiler (e.g. static and global using directives, expression bodied members).
C# 12 (VS 2022 17.8)
- ref readonly parameters
- Collection Expressions
-
Interceptors (experimental feature) - Inline Arrays
-
nameof accessing instance members -
Using aliases for any type - Primary Constructors
- Lambda optional parameters
-
Experimental attribute
C# 11 (VS 2022 17.4)
- File-local types
- ref fields
- Required members
- DIM for static members
- Numeric IntPtr
- Unsigned Right Shift
- Utf8 String Literals
- Pattern matching on
ReadOnlySpan<char>
- Checked Operators
-
auto-default structs -
Newlines in interpolations - List patterns
-
Raw string literals - Cache delegates for static method group
-
nameof(parameter) - Relaxing Shift Operator
-
Relax ordering ofref
andpartial
modifiers - Generic attributes (see also dotnet/runtime#58073)
C# 10 (VS 2022 17.0)
- Record structs
-
Global Using Directive: Currently there are no plans to support this in the decompiler, as it is of limited use. - Improved Definite Assignment
-
Constant Interpolated Strings: These are irreproducible. - Extended property patterns
- Sealed record ToString
-
Source Generator V2 APIs: There is nothing we could do. - Mix declarations and variables in deconstruction
- Async method builder override
-
Enhanced: These are irreproducible.#line
directive - Lambda improvements
- Static Abstract Members In Interfaces C# 10 Preview
- Interpolated string improvements
- File-scoped namespace
- Parameterless struct constructors
-
Caller expression attribute: These are irreproducible.
C# 9 (VS 2019 16.8)
-
Target-typed new: Currently we have no plans to implement this feature, just like we (almost) never emitvar
, unless anonymous types are used - Skip locals init
- Lambda discard parameters
- Native ints
- Attributes on local functions
- Function pointers
- Pattern matching improvements
-
Static lambdas: Currently we have no plans to implement this feature. - Records -> #2217
- Target-typed conditional
- Covariant Returns --> #2470
- Extension GetEnumerator
- Module initializers
-
Extending Partial: These are irreproducible. -
Top-level statements: We have no plans to support this feature as it would add a lot of complexity to the ILSpy UI as well as the decompiler. "Top level functions/free functions" from IL are already supported: they are located in the synthesized<Module>
type, similarly C# top level statements are located in the synthesizedProgram
type.
C# 8.0 (Visual Studio 2019)
- Default Interface Methods
- Async streams
-
await foreach
- Nullable reference type
- Readonly members
- Recursive patterns
- Switch expressions
- Enhanced using (
using var ... = ...;
) -
await using
- Disposable ref struct
- Ranges
- Null-coalescing Assignment --> #2552
-
Alternative interpolated verbatim strings: There are no plans to support this feature. Note that we don't ever emit verbatim strings. - stackalloc in nested contexts
- Unmanaged generic structs
- Static local functions
C# 7.3 (Visual Studio 2017 version 15.7)
-
System.Enum
,System.Delegate
andunmanaged
constraints. - 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, for example
Span<int> x = stackalloc[] { 1, 2, 3 };
. - Indexing movable fixed buffers: Fixed buffers can be indexed into without first being pinned.
- Custom
fixed
statement: Types that implement a suitableGetPinnableReference
can be used in afixed
statement. - 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 var
and pattern variables are allowed in field initializers, constructor initializers, and LINQ queries. - Tuple comparison: Tuples can now be compared with
==
and!=
. -> #1822 - Attributes on backing fields: Allows
[field: …]
attributes on an auto-implemented property to target its backing field.
C# 7.2 (Visual Studio 2017 version 15.4)
- ref readonly
- interior pointer/Span/ref struct
- non-trailing named arguments
- private protected (see #1010)
- conditional ref operator
-
Digit separator after base specifier: Currently, we have no plans to add support for this.
C# 7.1 (Visual Studio 2017 version 15.3)
- Async main --> #1023
- Default expressions
- Reference assemblies
-
Inferred tuple element names: There is no need for the decompiler to infer tuple names, the compiler already embeds these in the assembly metadata. - Pattern-matching with generics
C# 7.0 (Visual Studio 2017)
- Out variables
- Pattern matching --> #2048
- Tuples --> #1134
- Deconstruction --> #1832
- Discards
- Local Functions
-
Binary Literals: Currently, we have no plans to add support for this. -
Digit Separators: Currently, we have no plans to add support for this. - Ref returns and locals
- Generalized async return types
-
More expression-bodied members: We have no plans to add more places, where we emit expression-bodied members. Getter-only properties are currently the only case. - Throw expressions
💡 I noticed you have nameof
operator crossed out. While this is typically not possible due to lack of information in the compiler output, it would be good to support it in limited cases, such as the paramName
argument for ArgumentException
and derived types, which is likely to align with the name of a parameter visible in the current scope.
💡 I noticed you have Caller Info attributes crossed out. While this is typically not possible, one way it could be leveraged is intentionally omitting arguments (and allowing defaults to apply) in cases where the IL passes literal arguments which are known to align with the actual values that would be inserted by these attributes. The CallerMemberNameAttribute
would work without additional considerations. If other information is desired, the #line
directive could be used to set the file name and line number for the call site.
- I assume struck-through indicates "won't implement"? Would be useful to have that info at the beginning of the issue.
- For the "won't implement" features, a one-liner description or link to relevant issue discussing why not would be appreciated for additional context.
- Consider ordering by langver descending (so C# 10 is at the start and 1 at the end) - very few people are going to be interested in the older versions.