Index types, nullable reference types, default interfaces, and async streams should improve code quality and make software more flexible over the long term
Microsoft has fleshed out more details about C# Version 8.0, the next planned major release of the language. C# 8.0 is expected to arrive in 2019, concurrent with the arrival of .Net Core 3.0. Developers can try out language features in betas of the Visual Studio 2019 IDE.
Microsoft said that while most language features in C# 8.0 will run on any version
Type-related additions to C# 8.0 include:
- The new
Index
type, for indexing. An index can be created from anint
that counts from the beginning or with a prefix^
operator that counts from the end. - The
Range
type, which consists of twoIndex
es, one for the start and one for the end. It can be written with anx..y
range expression; developers then can index with aRange
to produce a slice. - Nullable reference types, to improve code quality, according to the .Net Foundation, which oversees the open source .Net that C# is part of. The feature will add safe reference types in addition to the existing ones that will be called non-nullable. Compilers will warn you when nullable types are dereferenced or when null is values are assigned to non-nullable variable types. The nullable reference type is intended to help developers prevent null reference exceptions. A core of the capability is expressing an intent to be null. The compiler will recognize when something is not null and warn you when you’ve assigned null to a reference that was not declared as null. With the capability, developers get an assist in finding bugs and making them go away.
Other new features planned for C# 8 are:
- Switch expressions, which present a lightweight version of switch statements, in which all cases are expressions.
- Target-typed new expressions, in which the type can be omitted when developers are creating a new object and the type is already given from context.
- Recursive patterns, in which patterns can contain other patterns.
- An opt-in method to deal with code-breaking behavior.
- A default interfaces programming capability, so interfaces can be evolve via virtual extension methods. An API author could add methods to an interface in future versions without breaking source or binary compatibility. The feature already is available in languages such as Java.
- An async streams feature to provide an abstraction that is the asynchronous version of IEnumerable, which is the base interface for nongeneric collections that can be enumerated.
- Extension everything, to provide a way to define new kinds of extension members. Although it is already possible in C# to define methods that act as instance methods of the extended type, the C# 8 proposal expands this capability by supporting static and instance members.
C# 8 New Planned Features
Nullable Reference Types
This feature was already considered in the early stages of C# 7.0 development but was postponed until the next major version. Its goal is to help developers avoid unhandled NullReferenceException exceptions.
Records
Currently, a significant amount of boilerplate C# code has to be written while creating a simple class which acts as a value container only and does not include any methods or business logic.
Recursive Patterns
Some pattern matching features have already been added to C# in version 7.0. There are plans to further extend the support in C# 8.0.
Default Interface Methods
Interfaces in C# are currently not allowed to contain method implementations.
In spite of this, there are plans to add support for default interface methods to C# 8.0, i.e. method implementations using the syntax suggested in the first example above. This would allow scenarios not supported by abstract classes.
A library author could extend an existing interface with a default interface method implementation, instead of a method declaration.
Asynchronous Streams
C# already has support for iterators and asynchronous methods. In C# 8.0, it’s planned to combine the two in asynchronous iterators.
It’s very similar to the code we’re currently using for consuming regular synchronous iterators. However, it does not look familiar because we typically just use the foreach statement instead.
Ranges
There are plans to add new syntax for expressing. It’s still undecided whether the range operator would be inclusive or exclusive, i.e. whether the resulting range would include the End value or not. It’s even possible that both an inclusive and an exclusive syntax will be available.
Generic Attributes
Support for generic attributes would allow nicer syntax for attributes which require a type as their argument.
Default Literal in Deconstruction
To assign default values to all members of a tuple in C# 7, the tuple assignment syntax must be used:
( int x, int y) = ( default , default ); |
With support for default literal in deconstruction syntax, the same could be achieved with the following syntax:
( int x, int y) = default ; |
Caller Argument Expression
In C# 5, caller information attributes (CallerMemberName, CallerFilePath and CallerLineNumber) were introduced into the language, so that the called method could receive more information about the caller for diagnostic purposes.
Target-typed new Expression
When declaring local variables, the var keyword can already be used to avoid repeating (potentially long) type names in code
Ordering of ref and partial Modifiers on Type Declarations
C# currently requires the partial keyword to be placed directly before the struct or class keyword.
Even with the introduction of the ref keyword for stack-allocated structs in C# 7.2, the restriction for the partialkeyword remained in place, therefore the ref keyword must be placed directly before the struct keyword if there is no partial keyword; and directly before the partial keyword, if the latter is present.
Conclusion
There are many new features already in the works for C# 8. This tutorial does not list all of them.
However, they’re probably still quite far away from the final release of C# 8.0, as the release date has not been announced yet. Until then, they can expect the plans to change: not all features might make it into the release. And even those that will make it to the final release, might still change syntactically or even semantically.
Of course, other new features not mentioned in the article might be added to the language as well. With all that in mind, you should regard the information in this article only as an interesting glimpse into the potential future of the language.