Skip to content

Available C# and .NET features

James Groom edited this page Sep 14, 2022 · 22 revisions

This document is to supplement BizHawk development, and will be deleted once the project is on .NET Core. Yoshi will maintain a copy on GitLab for the benefit of other projects.

BizHawk-specific notes:

  • All projects in the main BizHawk solution use C# 9 currently.
  • In the added "convention" column, I've used required/disallowed/encouraged/discouraged/allowed like RFC 2119's MUST / MUST NOT / SHOULD / SHOULD NOT / MAY, respectively. Unsupported is also MUST NOT (because attempting to use the feature will result in an error).
  • Each project's target (Framework vs. Standard) is at the top of its project file, or you can check the project graph.

Legend:
βœ”οΈ Available
β­• Available with polyfill
❌ Not available
? Unknown

πŸ”΅ Availablity in .NET Framework 4.8 (net48)
🟒 Availablity in .NET Standard 2.0 (netstandard2.0)
I have not considered Framework 4.7.2 and below as there is little reason not to upgrade to Framework 4.8. I have not considered Framework 4.8.1 because it matches Framework 4.8 in terms of language features and is generally not useful. I use Standard 2.0 and not Standard 2.1 as the latter is not subsumed by Framework 4.8, rendering it useless.

Note: .NET calls destructuring "deconstructing", not to be confused with destructing which .NET calls "finalising".

Feature πŸ”΅ net48 🟒 ns2.0 convention for main BizHawk solution
enhanced nameof ? ? unsupported
pattern matching for Span<char> ? ? unsupported
Kotlin-like raw string literals ? ? unsupported
list pattern matching ? ? unsupported
multi-line expressions in interpolated strings ? ? unsupported
generic maths using static abstract members ? ? unsupported
genericised attributes ? ? unsupported
^ C# 11 ^ πŸ”΅ net48 🟒 ns2.0 ---
per-method AsyncMethodBuilder ? ? unsupported
enhanced null analysis ? ? unsupported
enhanced destructuring βœ”οΈ βœ”οΈ unsupported
sealed ToString in records ? ? unsupported
limited string interpolation in consts βœ”οΈ βœ”οΈ unsupported
attributes for lambdas βœ”οΈ βœ”οΈ unsupported
type inference for lambdas βœ”οΈ βœ”οΈ unsupported
pattern matching IV βœ”οΈ βœ”οΈ unsupported
namespace A; βœ”οΈ βœ”οΈ unsupported
global using A;/<Using> βœ”οΈ βœ”οΈ unsupported
custom interpolated string handlers ? ? unsupported
with for structs βœ”οΈ βœ”οΈ unsupported
enhanced struct field init βœ”οΈ βœ”οΈ unsupported
record struct βœ”οΈ βœ”οΈ unsupported
^ C# 10 ^ πŸ”΅ net48 🟒 ns2.0 ---
enhanced partial methods ? ? unsupported
[ModuleInitializer] method β­• β­• unsupported
attributes on local methods βœ”οΈ βœ”οΈ allowed
discarding lambda parameters βœ”οΈ βœ”οΈ encouraged
foreach picks up GetEnumerator extension βœ”οΈ βœ”οΈ discouraged (surely this can only be used for stupid)
covariant return type when overriding ❌ ❌ unsupported
enhanced type inference βœ”οΈ βœ”οΈ omit explicit type cast where possible, otherwise place the cast on default branch of switch and first branch of ternary
static lambdas βœ”οΈ βœ”οΈ encouraged
target-typed new() βœ”οΈ βœ”οΈ encouraged
function pointers ? ? unsupported
nint/nuint βœ”οΈ βœ”οΈ allowed
pattern matching III βœ”οΈ βœ”οΈ encouraged
unindented Main ? ? N/A (neither executable uses it)
with for records βœ”οΈ βœ”οΈ discouraged
init βœ”οΈ βœ”οΈ discouraged
record class βœ”οΈ βœ”οΈ discouraged
^ C# 9 ^ πŸ”΅ net48 🟒 ns2.0 ---
@$"" (instead of $@"") βœ”οΈ βœ”οΈ disallowed
stackalloc as arg for Span param βœ”οΈ βœ”οΈ allowed
??= βœ”οΈ βœ”οΈ encouraged
Index and Range (^ and .. operators) β­• β­• unsupported (we have a generic Range<T> but it has some problems, like not working with ..)
async streams β­• β­• unknown
NRTs (attribute-based analysis) β­• β­• encouraged
NRTs (syntax and basic analysis) βœ”οΈ βœ”οΈ encouraged for new files, see project graph for when #nullable enable is needed
static local methods βœ”οΈ βœ”οΈ encouraged
using statement without block βœ”οΈ βœ”οΈ encouraged
pattern matching II βœ”οΈ βœ”οΈ encouraged
switch expression βœ”οΈ βœ”οΈ encouraged
default interface methods ❌ ❌ unsupported
readonly methods/getters/setters βœ”οΈ βœ”οΈ encouraged
^ C# 8 ^ πŸ”΅ net48 🟒 ns2.0 ---
field attribute target for auto-prop backing field βœ”οΈ βœ”οΈ discouraged (surely this can only be used for stupid)
stackalloc with array intialiser βœ”οΈ βœ”οΈ encouraged
^ C# 7.3 ^ πŸ”΅ net48 🟒 ns2.0 ---
Span and co. β­• β­• allowed
ref struct (stack-bound) βœ”οΈ βœ”οΈ allowed
readonly struct and in parameters βœ”οΈ βœ”οΈ encouraged
^ C# 7.2 ^ πŸ”΅ net48 🟒 ns2.0 ---
inferred tuple field names βœ”οΈ βœ”οΈ discouraged
default without type βœ”οΈ βœ”οΈ encouraged for non-nullable value types, discouraged otherwise
async Main ? ? N/A (neither executable uses it)
^ C# 7.1 ^ πŸ”΅ net48 🟒 ns2.0 ---
throw expression βœ”οΈ βœ”οΈ encouraged
enhanced int literals βœ”οΈ βœ”οΈ encouraged
discards βœ”οΈ βœ”οΈ encouraged
ref returns/locals βœ”οΈ βœ”οΈ allowed
expression-bodied ctors βœ”οΈ βœ”οΈ encouraged
local methods βœ”οΈ βœ”οΈ preferred over lambdas/delegates if used multiple times or to unsub from event
basic pattern matching βœ”οΈ βœ”οΈ encouraged
KeyValuePair<K, V>.Deconstruct β­• β­• allowed
basic tuples and destructuring βœ”οΈ βœ”οΈ encouraged
out var βœ”οΈ βœ”οΈ encouraged
^ C# 7.0 ^ πŸ”΅ net48 🟒 ns2.0 ---
nameof βœ”οΈ βœ”οΈ encouraged
interpolated string literals βœ”οΈ βœ”οΈ preferred over string.Format or concatenation
null-conditional member access βœ”οΈ βœ”οΈ required
expression-bodied methods/props βœ”οΈ βœ”οΈ encouraged
inline initialisation of auto-props βœ”οΈ βœ”οΈ encouraged
catch (Exception e) when (predicate(e)) βœ”οΈ βœ”οΈ encouraged
using static A; βœ”οΈ βœ”οΈ allowed only for the file's own namespace
^ C# 6 ^ πŸ”΅ net48 🟒 ns2.0 ---
[Caller*] βœ”οΈ βœ”οΈ allowed
async βœ”οΈ βœ”οΈ allowed
^ C# 5 ^ πŸ”΅ net48 🟒 ns2.0 ---
covariant and contravariant generics βœ”οΈ βœ”οΈ encouraged
default arguments βœ”οΈ βœ”οΈ preferred over overloads
named arguments βœ”οΈ βœ”οΈ encouraged for primitive-typed parameters
dynamic type βœ”οΈ β­• discouraged
^ C# 4 ^ πŸ”΅ net48 🟒 ns2.0 ---
object initialisation syntax βœ”οΈ βœ”οΈ encouraged
partial methods βœ”οΈ βœ”οΈ allowed
var βœ”οΈ βœ”οΈ preferred except when target-typed new() can be used
extension methods βœ”οΈ βœ”οΈ allowed
Expression trees βœ”οΈ βœ”οΈ discouraged (what are these even for)
lambdas βœ”οΈ βœ”οΈ preferred over delegates
LINQ's query expression syntax βœ”οΈ βœ”οΈ disallowed
anonymous classes βœ”οΈ βœ”οΈ disallowed (use tuples)
auto-props βœ”οΈ βœ”οΈ encouraged
^ C# 3 ^ πŸ”΅ net48 🟒 ns2.0 ---
anonymous delegates βœ”οΈ βœ”οΈ disallowed
^ C# 2 ^ πŸ”΅ net48 🟒 ns2.0 ---
using alias βœ”οΈ βœ”οΈ discouraged unless there's a conflict
delegate constructors βœ”οΈ βœ”οΈ disallowed
unsafe (pointers etc.) βœ”οΈ βœ”οΈ discouraged