Though C# 8 is supposed to be released this year and the roadmap for C# 8.x and 9 are beginning to be formed, Microsoft is continuing to approve features for the next release.

Target Typed Expressions

Say you have types A, B, and C, where B and C are subtypes of A. If you use the following statements the compiler cannot determine which type to return from the right-hand side.

A a1 = b ?? c; A a2 = x>0 ? b : c; A a3 = a switch { B b => b, C c => c, _ => throw new System.Exception() };

Normally fixing this requires adding casts such as:

A a1 = (A)b ?? (A)c; A a2 = x>0 ? (A)b : (A)c;

With the Target-typed switch expression proposal, in each case the compiler is allowed to use the left-hand side of the statement ( A a1 ) to determine which type the right-hand side ( b ?? c ) should return. This feature would also work with return statements ( return b ?? c ) but not var ( var a1 = b ?? c ).

Currently the pattern matching version of this (example 3) is planned for C# 8.0, with the other two slated for 8.x.

Allow 'default' in Deconstruction

This small feature will allow the default keyword to be used when initializing tuples. From the proposal,

(int i, string s) = default; (i, s) = default;

Obsolete Properties

Unlike Visual Basic, C# cannot mark individual getters and setters as obsolete. Instead, only the property as a whole can be so marked. This proposal rectifies the situation. To understand why this is important, consider Cory Nelson’s comment:

I found myself wishing for this just a few weeks ago, when trying to clean up some code that used a bunch of get/set properties to one that was a more read-only ctor-initialized record.

In April this feature was moved from C# 9 to C# 8.

Readonly Members on Structs

When assigned to a readonly field or used as an in parameter, methods on structs have a minor performance problem. If you call a method on the struct, the compiler makes a defensive copy first. While this is usually not expensive enough to cause a problem, when used in a tight loop, small inefficiencies do add up.

For fully immutable structs, this can be avoided by marking the entire struct as readonly. However, many structs are mutable for performance reasons.

With the Readonly Instance Methods proposal, developers will be able to mark individual methods as readonly. This indicates to the compiler that a defensive copy is not necessary and no values will be altered.

This is different from the Pure attribute in that a readonly method can have visible side-effects so long as they don’t alter the value of the struct itself.

The getters for auto-implemented properties will be considered readonly automatically. In some cases, the setter can also be marked as readonly, for example, when the property values are stored in a dictionary rather than directly in the struct itself.

Under the current proposal, reference types (classes and interfaces) will not be supported by this feature. The reason is three-fold: