This short course covers the latest and greatest features of C#, covering versions 7, 7.1, 7.2, 7.3, 8.0, 9.0 and 10.0 of the language that are being sim-shipped with corresponding Visual Studio updates.
Course Topics
Here's every language feature presented in this course, grouped by the version of the C# language.
C# 7:
This short course covers the latest and greatest features of C#, covering versions 7, 7.1, 7.2, 7.3, 8.0, 9.0 and 10.0 of the language that are being sim-shipped with corresponding Visual Studio updates.
Course Topics
Here's every language feature presented in this course, grouped by the version of the C# language.
C# 7:
Out Variables
Pattern Matching (is and switch expressions)
Tuples and Tuple Deconstruction
Local Functions
Ref Returns and Locals
Expression Bodied Members
Throw Expressions
Generalized Async Return Types
Literal Improvements
C# 7.1:
How to turn on C# 7.1 support
Async Main
Default Expressions
Ref Assemblies
Infer Tuple Names
Pattern-Matching with Generics
C# 7.2:
Leading Digit Separators
'Private Protected' Access Modifier
Non-Trailing Named Arguments
Reference Semantics on Value Types:
'In' Parameters
'Ref Readonly' Variables
'Ref Struct' and Span<T>
C# 7.3:
Performance improvements
Access fixed fields without pinning
Reassign ref local variables
Use initializers on stackalloc arrays
Use fixed statements on any type that supports a pattern
Enhancements to existing features
Tuple and . = support
Use expression variables in more locations
Attach attributes to backing field of auto-properties
Improved method resolution when arguments differ by 'in'
Improved overload resolution
New compiler options:
deterministic
publicsign
pathmap
C# 8:
Nullable Reference Types
Indices and Ranges
Default Interface Members
Pattern Matching
C# 9:
Record Types
Top-Level Calls
Initial Setters
Pattern Matching Improvements (type patterns, parenthesized patterns, conjunctive and, disjunctive or, negated not, relational patterns)
Performance and Interop (Native sized integers (nint/nuint), function pointers, SkipLocalsInit)
Fit and Finish (target-typed new, target type resolution of conditional expressions, static modifier for lambda expressions and anonymous methods, covariant return types, foreach GetEnumerator() use, discards as parameters to lambdas, attributes on local functions)
C# Code Generators (partial method syntax, module initializers)
C# 10:
Record Structs
Global Using Directives
File-Scoped Namespace Declarations
Extended Property Patterns
Generic Attributes
Lambda Improvements (attributes, explicit return types, natural type inference)
Enhanced #line directives
Prerequisites
Knowledge and understanding of C# 6 and earlier
General experience in .NET/C# application development
Learning Outcomes
An understanding and appreciation of latest C# 7/7.1/7.2/7.3/8/9 language features
Understanding of how to convert existing C# code to C# 7/7.1/7.2/7.3/8/9
A description of the contents of this course.
It used to be the case that, in order to use an out variable, you had to declare it first. Well, not anymore!
Not quite the F# pattern-matching on structural types, but it's a start.
Better tuples with names and deconstruction. Somewhat ruined by the requirement of an external Nuget package.
Update: System.ValueTuple is now part of .NET Framework 4.7.
What is deconstruction and why should you care?
Functions inside functions, what could be simpler?
References! Just like in C++, except not quite.
A community-proposed feature of extending expression bodies to constructors/destructors and getters/setters.
Throw from a null-coalescing expression? What madness is this?
Async method return types are no longer restricted to void/Task/Task<T>.
Underscores in decimal, hex and binary literals.
If you make a new project in Visual Studio 2017.3 and try to use a C#7.1 feature, the project won't compile. Why is that?
Oh, and what happens if your assembly has multiple Main methods, some async and some not?
The Main()
method can now be marked async
and is allowed to return a Task
or Task<int>
.
Watch the default
keyword become a literal (similar to the null
literal) and start taking on additional responsibilities.
Learn about assemblies whose method bodies are replaced with throw
.
null
Just as the name suggests, this feature allows us, in certain cases, to infer tuple names and lets us omit them.
C# 7.1 makes it easier to pattern-match against a variable of a generic type.
You can now put an underscore after a binary (0b) or hexadecimal (0x) literal prefix.
A new access modifier called 'private protected' was introduced. Learn what it's for and how it is different from 'protected internal'.
Named arguments can now appear before positional ones.
Value types can now be passed by reference. What magic is this?
Since references to value types are meant to be readonly (otherwise, just pass by value), we have a new 'ref readonly' qualifier.
The 'ref struct' feature was designed specifically for Span<T> in mind... shame that the type itself is not yet ready.
Even though Span<T> is still in prerelease form, let's take a look at it anyway! Its internal mechanics will change, but the public API probably won't.
Improvements to C#, related mainly to unsafe memory manipulations.
Some minor improvements to existing C# features.
Three new compiler flags!
OOPS: the explanation for -publicsign is incorrect and will be fixed! Sorry!
A couple of links to my other .NET/C# courses!
Probably the worst, most incorrect name given to a feature, Nullable Reference Types are a new way of generating null-related warnings.
Two new pieces of syntactic sugar and two new types, Index and Range, help you index into and take parts of collections easier.
A rather controversial feature, default interface members allow you to patch interfaces after deployment with concrete implementations. .NET Core only!
Continuing to steal features from F#, pattern matching is now augmented with many useful features.
Say hello to C#9!
Record types make it easy to create data classes where the chores of equality, hash codes and string output are taken care of for you by the compiler.
Top-level calls make it easy to create single-file C# scripts by avoiding namespace/class/Main method declarations altogether.
Fields have 'readonly', and now properties have 'init'.
It never ends, does it?
If the type can be inferred at a particular location, you don't have to type its name anymore!
Some simple code generation functionality built into the compiler.
Some tools to help support source generators.
Learn what's new in C# 10.
OpenCourser helps millions of learners each year. People visit us to learn workspace skills, ace their exams, and nurture their curiosity.
Our extensive catalog contains over 50,000 courses and twice as many books. Browse by search, by topic, or even by career interests. We'll match you to the right resources quickly.
Find this site helpful? Tell a friend about us.
We're supported by our community of learners. When you purchase or subscribe to courses and programs or purchase books, we may earn a commission from our partners.
Your purchases help us maintain our catalog and keep our servers humming without ads.
Thank you for supporting OpenCourser.