What’s new in C# 9.0
Microsoft presented the C# version 9.0 at MS Build 2020 and is steadily progressing forward in developing this language. The previous versions of C# sharp were so popular that they rivaled other high-level languages like Java and Python. C# 9.0 will be a part of the .NET 5 development platform and is scheduled to arrive in November, which is appropriately one year after the release of C# 8.0. The development phases of C# 9.0 emphasized mainly on the following factors:
- Simplicity to improvise syntaxes for cleaner codes
- Terse and immutable representation of data shapes
C# lead designer Mads Torgersen shed some light on the added capabilities of the language. If you missed out on something, today we explain some newly added features and aspects of C# 9.0 below:
Simplified Null Validation Code
Let's kick off with the simplest ones that reduce the need to write unnecessary long codes. The first one our list is the null validation code that uses small parameterized annotation to reduce the boilerplate validation.
For example:
//Before
void Insert(string a)
{
if (a is null)
{
throw new ArgumentNullException(nameof(a));
}
}
//This code has been shortened to:
void Insert(string a!)
{
//body
}
Init-only properties
A necessity for successful object initialization is mutable properties that work by calling the constructor and then assign to the property setters. The newly introduced Init-only properties use init, which is a variant of the set accessor and can be only called during initialization.
For example:
//Instead of the following
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
//Use this
public class Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
}
However, with init-only, you can only assign properties once, and no subsequent assignments are allowed.
Primary Constructors
Primary constructors are an old concept in object-oriented programming that allowed developers to skip the explicit declaration of constructor code. However, constructors have had their fair share of farewells and welcome in C#. Version 9.0 lets you use primary constructors to escape the trouble of writing and re-writing boilerplate codes. With the modified parameter null validation code, you can even write cleaner code.
For example:
public class Rectangle
{
private int _area;
public Rectangle(int area)
{
_area = area;
}
public int area
{
get => _area;
set
{
if (value == null)
{
throw new NullArgumentException(nameof(area));
}
_area = value;
}
}
}
//After
public class Rectangle(int area)
{
public int area
{
get => _area;
set {
if (value == null)
{
throw new NullArgumentException(nameof(area));
}
_area = value;
}
}
}
Record Classes
Record classes are similar to primary constructors but are useful to declare objects that store valuable information and aren't used inside any method. You can put those objects in the parameters of record classes and end them with a semicolon. There is no need to type repeated code and explicitly create objects via the old method.
For example:
//To create such objects that you do not use in any method, you were required to write the complete code like below:
public class Rectangle
{
public int length { get; }
public int width { get; }
public Rectangle(int length, int width)
{
this.length = length;
this.width = width;
}
}
//Instead you can use the following in C# 9.0
public class Rectangle(int length, int width);
With-Expressions
With-expressions are newly launched expressions in C# that help you create new values from already existing ones. They reduce the length of the code by comparing the changes in both old and new values. Mads Torgersen of Microsoft has given a perfect scenario to explain the with-expression. Suppose, if you need to change the last name of a person, you will create a copy of the old instance with a different last name. It is an example of a non-destructive mutation. Instead of representing the person's name over time, it represents the person's name at a given time.
Instead of using the old method for non-destructive mutation, you can resort to the with-expression that does not create a copy but compares the changes to create a new instance from the already existing ones.
For example:
public class Person
{
public readonly string FirstName;
public readonly string LastName;
// Defining With expression
public Person With(string firstName = this.FirstName, string lastName = this.LastName) => new Person(firstName, lastName);
}
var existingPerson = new Person("Peter", "Parker");
var clonedPerson = existingPerson.With(lastName: "Spidey");
// clonedPerson: { FirstName = "Peter", LastName = "Spidey"}
Logical patterns
You can now use the operators and
, or
and not
in expressions. Very useful in if conditions and all those parentheses
//Below is the concept of overloading:
if (!(me is Person)) {
// ...
}
//Becomes
if (me is not Person) {
// ...
}
These were some of the newly added functionalities of C# in version 9.0. Stay hooked to get more information on other future features and development.