Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
C# 9 and .NET 5 – Modern Cross-Platform Development

You're reading from   C# 9 and .NET 5 – Modern Cross-Platform Development Build intelligent apps, websites, and services with Blazor, ASP.NET Core, and Entity Framework Core using Visual Studio Code

Arrow left icon
Product type Paperback
Published in Nov 2020
Publisher Packt
ISBN-13 9781800568105
Length 822 pages
Edition 5th Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Mark J. Price Mark J. Price
Author Profile Icon Mark J. Price
Mark J. Price
Arrow right icon
View More author details
Toc

Table of Contents (23) Chapters Close

Preface 1. Hello, C#! Welcome, .NET! 2. Speaking C# FREE CHAPTER 3. Controlling Flow and Converting Types 4. Writing, Debugging, and Testing Functions 5. Building Your Own Types with Object-Oriented Programming 6. Implementing Interfaces and Inheriting Classes 7. Understanding and Packaging .NET Types 8. Working with Common .NET Types 9. Working with Files, Streams, and Serialization 10. Protecting Your Data and Applications 11. Working with Databases Using Entity Framework Core 12. Querying and Manipulating Data Using LINQ 13. Improving Performance and Scalability Using Multitasking 14. Introducing Practical Applications of C# and .NET 15. Building Websites Using ASP.NET Core Razor Pages 16. Building Websites Using the Model-View-Controller Pattern 17. Building Websites Using a Content Management System 18. Building and Consuming Web Services 19. Building Intelligent Apps Using Machine Learning 20. Building Web User Interfaces Using Blazor 21. Building Cross-Platform Mobile Apps 22. Index

Working with null values

You have now seen how to store primitive values like numbers in variables. But what if a variable does not yet have a value? How can we indicate that? C# has the concept of a null value, which can be used to indicate that a variable has not been set.

Making a value type nullable

By default, value types like int and DateTime must always have a value, hence their name. Sometimes, for example, when reading values stored in a database that allows empty, missing, or null values, it is convenient to allow a value type to be null. We call this a nullable value type.

You can enable this by adding a question mark as a suffix to the type when declaring a variable. Let's see an example:

  1. In the Chapter02 folder, create a new folder named NullHandling.
  2. Add the NullHandling folder to the Chapter02 workspace.
  3. Create a new Terminal window for the NullHandling project.
  4. Create a new console application project in the NullHandling folder.
  5. Select NullHandling as the current project for OmniSharp.
  6. In the NullHandling project, in Program.cs, in the Main method, add statements to declare and assign values, including null, to int variables, as shown in the following code:
    int thisCannotBeNull = 4;
    thisCannotBeNull = null; // compile error!
    int? thisCouldBeNull = null;
    Console.WriteLine(thisCouldBeNull);
    Console.WriteLine(thisCouldBeNull.GetValueOrDefault());
    thisCouldBeNull = 7;
    Console.WriteLine(thisCouldBeNull);
    Console.WriteLine(thisCouldBeNull.GetValueOrDefault());
    
  7. Comment out the statement that gives a compile error.
  8. Run the application and view the result, as shown in the following output:
    0
    7
    7
    

The first line is blank because it is outputting the null value!

Understanding nullable reference types

The use of the null value is so common, in so many languages, that many experienced programmers never question the need for its existence. But there are many scenarios where we could write better, simpler code if a variable is not allowed to have a null value.

More Information: You can find out more through the following link, where the inventor of null, Sir Charles Antony Richard Hoare, admits his mistake in a recorded hour-long talk: https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare

The most significant change to the language in C# 8.0 was the introduction of nullable and non-nullable reference types. "But wait!", you are probably thinking, "Reference types are already nullable!"

And you would be right, but in C# 8.0 and later, reference types can be configured to no longer allow the null value by setting a file- or project-level option to enable this useful new feature. Since this is a big change for C#, Microsoft decided to make the feature opt-in.

It will take multiple years for this new C# language feature to make an impact since there are thousands of existing library packages and apps that will expect the old behavior. Even Microsoft has not had time to fully implement this new feature in all the main .NET 5 packages.

More Information: You can read the tweet about achieving 80% annotations in .NET 5 at the following link: https://twitter.com/terrajobst/status/1296566363880742917

During the transition, you can choose between several approaches for your own projects:

  • Default: No changes are needed. Non-nullable reference types are not supported.
  • Opt-in project, opt-out files: Enable the feature at the project level and, for any files that need to remain compatible with old behavior, opt out. This is the approach Microsoft is using internally while it updates its own packages to use this new feature.
  • Opt-in files: Only enable the feature for individual files.

Enabling nullable and non-nullable reference types

To enable the feature at the project level, add the following to your project file:

<PropertyGroup>
  <Nullable>enable</Nullable>
</PropertyGroup>

To disable the feature at the file level, add the following to the top of a code file:

#nullable disable

To enable the feature at the file level, add the following to the top of a code file:

#nullable enable

Declaring non-nullable variables and parameters

If you enable nullable reference types and you want a reference type to be assigned the null value, then you will have to use the same syntax as making a value type nullable, that is, adding a ? symbol after the type declaration.

So, how do nullable reference types work? Let's look at an example. When storing information about an address, you might want to force a value for the street, city, and region, but the building can be left blank, that is, null:

  1. In NullHandling.csproj, add an element to enable nullable reference types, as shown highlighted in the following markup:
    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net5.0</TargetFramework>
        <Nullable>enable</Nullable>
      </PropertyGroup>
    </Project>
    
  2. In Program.cs, at the top of the file add a statement to enable nullable reference types, as shown in the following code:
    #nullable enable
    
  3. In Program.cs, in the NullHandling namespace, above the Program class, add statements to declare an Address class with four fields, as shown in the following code:
    class Address
    {
      public string? Building;
      public string Street;
      public string City; 
      public string Region;
    }
    
  4. After a few seconds, note that the C# extension warns of problems with non-nullable fields like Street, as shown in the following screenshot:
    A screenshot of a cell phone  Description automatically generated

    Figure 2.6: Warning messages about non-nullable fields in the PROBLEMS window

  5. Assign the empty string value to each of the three fields that are non-nullable, as shown in the following code:
    public string Street = string.Empty;
    public string City = string.Empty;
    public string Region = string.Empty;
    
  6. In Main, add statements to instantiate an Address and set its properties, as shown in the following code:
    var address = new Address();
    address.Building = null;
    address.Street = null;
    address.City = "London";
    address.Region = null;
    
  7. Note the warnings, as shown in the following screenshot:
    A screenshot of a cell phone  Description automatically generated

    Figure 2.7: Warning message about assigning null to a non-nullable field

So, this is why the new language feature is named nullable reference types. Starting with C# 8.0, unadorned reference types can become non-nullable, and the same syntax is used to make a reference type nullable as is used for value types.

More Information: You can watch a video to learn how to get rid of null reference exceptions forever at the following link: https://channel9.msdn.com/Shows/On-NET/This-is-how-you-get-rid-of-null-reference-exceptions-forever

Checking for null

Checking whether a nullable reference type or nullable value type variable currently contains null is important because if you do not, a NullReferenceException can be thrown, which results in an error. You should check for a null value before using a nullable variable, as shown in the following code:

// check that the variable is not null before using it
if (thisCouldBeNull != null)
{
  // access a member of thisCouldBeNull
  int length = thisCouldBeNull.Length; // could throw exception
  ...
}

If you are trying to use a member of a variable that might be null, use the null-conditional operator ?., as shown in the following code:

string authorName = null;
// the following throws a NullReferenceException
int x = authorName.Length;
// instead of throwing an exception, null is assigned to y
int? y = authorName?.Length;

More Information: You can read more about the null-conditional operator at the following link: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

Sometimes you want to either assign a variable to a result or use an alternative value, such as 3, if the variable is null. You do this using the null-coalescing operator, ??, as shown in the following code:

// result will be 3 if authorName?.Length is null
var result = authorName?.Length ?? 3; 
Console.WriteLine(result);

More Information: You can read about the null-coalescing operator at the following link: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator

You have been reading a chapter from
C# 9 and .NET 5 – Modern Cross-Platform Development - Fifth Edition
Published in: Nov 2020
Publisher: Packt
ISBN-13: 9781800568105
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime