What to Expect in C# 10

In this article we are going to look at the newest features being added to the C# programming languages to give developers a better idea of how their software development will be affected.

New Features in C# 10

At the time of writing, the following list shows the new features developers can expect in C# 10. They are as follows: Null Parameter Checking Required Properties Field Keyword Global Usings File Namespaces

Let’s go into more details about each C# sharp feature to better understand the changes to the language.

Null Parameter Checking in C# 10

The infamous: “Object Reference Not Set to an instance of an object” error is one of those errors that can be quite difficult to anticipate and to handle. This error is a NullReferenceException, meaning that when you try to access a member, method, or property that holds a null value, the above message is thrown.

This is where the new feature Null Parameter Checking can help us by making our code more robust and more readily avoiding (and handling) such errors..

Currently, if we want to check for a Null Reference we’d need to write code similar to the following C# code block:

public FunctionName(int Age, ClassName newClassNameObject)
{
  if (newClassNameObject == null)
  {
    throw new ArgumentNullException("newClassNameObject");
  }
}

In the code above, we have a function with two parameters: an Age integer and an object (newClassNameObject) from a class called (ClassName). We start by checking to see if this class object is null in order to throw the ArgumentNullException. If we do not do a check and newClassNameObject is null a NullreferenceException would occur.

With the new features of C# 10, all you need to do to check if an object is null is to add two exclamation marks next to the object you want to test. Here is the same example, but with the newly added features of C# 10 implemented:

public FunctionName(int Age, ClassName newClassNameObject!!)
{

}

Here, the newClassnameObject automatically gets tested for null, and the AgrumentNullException will automatically be thrown if it is null.

Required Properties in C# 10

As the name implies, this new feature allows us to set required properties. This means that whenever we create an object, we can ensure that some properties should always be set. Here is an example show the old method:

var newSong = new Song
{
	Title = "Spread Your Wings",
	Artist = "Queen",
	ReleaseDate =1997
}

There is nothing wrong with the example above, but let’s take it a step further:

Let’s add the following code:

var newSong = new Song
{
	Artist = "Queen",
	ReleaseDate =1997
}

Here, we have omitted the Title, which is acceptable, but not really correct. This is where C#’s new feature Required Properties comes to the rescue. Let’s take the same example and rewrite its class definition in C# 10:

public class Song
{
  public required string Title { get; init; }
  public string Artist { get; init; }
  public DateTime ReleaseDate { get; init; }
}

By adding the required flag, we ensure that a Title always has to be entered.

Field Keyword and init Accessors in C#

C# 10 features a new keyword called field, along with another new feature called init accessors. These two additions allow immutable objects te be more flexible and allow the caller to mutate members during construction. Let’s have a look at an older C# example:

public class Song
{
  private string _title;
  public string Title
  {
    get
    {
      return _title;
    }
    set
    {
      if (value.Trim() == "")
        throw new ArgumentException("Title can't be empty");

      _title = value;
    }
  }
}

In this example we add the backing field and we are forced to write the usual methods pertaining to that addition. However, in C# 10 we can rewrite this same example in the following manner:

public class Song
{
  public string Title
  {
    get;
    set
    {
      if (value.Trim() == "")
        throw new ArgumentException("Title can't be empty");
      field = value;
    }
  }
}

In this version, there is no need to implement backing fields. Here is another C# 10 example, this time using the init accessor:

public class Song
{
  public string Title
  {
    get;
    set
    {
      if (value.Trim() == "")
        throw new ArgumentException("Title can't be empty");
      field = value;
    }
  }

  public string Category { get; init; }
  public DateTime ReleaseDate{ get; init => field = value.Date(); }
}

Global Usings in C# 10

Every C# file usually has a lot of usings associated with it. Usings are required to import the necessary capabilities to a file, but sometimes they can become redundant and add unnecessary noise to your code.

Fortunately, C# 10 introduces a new feature called Global Usings, where, with the help of the global keyword, you can define global usings for the whole project! You could simply set up a file named usings.cs, for example, and add all the usings in there. Here is an example showing this practice:

global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.EntityFrameworkCore;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Hosting;
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
These usings will be available for the entire project.

File Namespaces in C# 10

The addition of File Namespaces in C# 10 is more of a cosmetic change, added to eliminate horizontal waste. Here is the current method for defining a class in C#:

namespace Music
{
  	public class Song
  	{
	 }
}

In C# 10 you define the namespace on the file level and it would look like:

namespace Music;
public class Song
{
}

More by Author

Must Read