DEV Community

mohamed Tayel
mohamed Tayel

Posted on

Mastering C# Fundamentals: Null Reference Types and Nullable Types

Meta Description: Learn how to effectively work with null values in C#. This guide covers handling null in reference and value types, avoiding NullReferenceException, and using nullable types, with practical assignments from easy to advanced levels

In C#, dealing with null values is a fundamental concept that you'll come across frequently. Understanding how null works can prevent common issues like NullReferenceException. In this article, we’ll break down how null relates to both reference types and value types, and explore practical examples for different levels of difficulty.

What is null?

In C#, null simply represents the absence of a value. For reference types like classes, null means that a variable does not currently point to any object in memory. Let’s explore this with our Employee class.

Reference Types and null

Consider the following declaration:

Employee employee;
Enter fullscreen mode Exit fullscreen mode

Here, employee is a variable of type Employee. Since Employee is a reference type, this variable does not point to any value in memory yet—it is null by default. It’s like having an empty box, and you haven’t put anything inside it.

If we now attempt to call a method on employee without initializing it:

employee.DisplayEmployeeDetails();
Enter fullscreen mode Exit fullscreen mode

This will result in a NullReferenceException at runtime because employee does not point to an actual Employee object. To avoid this, we need to instantiate employee first:

employee = new Employee();
Enter fullscreen mode Exit fullscreen mode

Now, employee points to an Employee object in memory, and we can safely call methods on it.

Setting an Object Back to null

If we no longer need the employee object, we can set it back to null:

employee = null;
Enter fullscreen mode Exit fullscreen mode

This effectively breaks the reference between the employee variable and the actual object in memory. The object becomes unreachable and eligible for garbage collection.

Value Types and null

Value types, such as int, double, etc., by default cannot be null because they store data directly. However, C# provides a way to make value types nullable by using the ? operator. This is especially useful when dealing with data that might not always have a value, like optional fields from a database.

For example, let’s declare an integer that can be null:

int? salary = null;
Enter fullscreen mode Exit fullscreen mode

The int? type allows the variable to hold either an integer or null. To determine if the value is set or not, you can use the .HasValue property:

if (salary.HasValue)
{
    Console.WriteLine($"Salary: {salary.Value}");
}
else
{
    Console.WriteLine("Salary is not available.");
}
Enter fullscreen mode Exit fullscreen mode

To avoid dealing with null manually, you can also provide a default value using the null-coalescing operator (??):

int finalSalary = salary ?? 30000; // Use 30000 if salary is null
Enter fullscreen mode Exit fullscreen mode

Practical Examples: Assignments by Difficulty Level

To help you solidify your understanding of null, here are exercises with increasing levels of complexity.

Level 1: Easy

  1. Nullable Integer Example

Create a variable of type int? called age, set it to null, and print a message based on whether the value is present.

   int? age = null;

   if (age.HasValue)
   {
       Console.WriteLine($"Age: {age.Value}");
   }
   else
   {
       Console.WriteLine("Age is not available.");
   }
Enter fullscreen mode Exit fullscreen mode
  1. Assign Default Value Using Null-Coalescing Operator

Assign a default value to age if it's null using ??.

   int finalAge = age ?? 25; // Assign 25 if age is null
   Console.WriteLine($"Final Age: {finalAge}");
Enter fullscreen mode Exit fullscreen mode

Level 2: Medium

  1. Instantiate an Employee Class

Declare an Employee variable and explicitly set it to null. Then try to call a method on it and catch the exception.

   Employee employee = null;

   try
   {
       employee.DisplayEmployeeDetails(); // This will throw a NullReferenceException
   }
   catch (NullReferenceException)
   {
       Console.WriteLine("Caught NullReferenceException: Cannot call a method on a null reference.");
   }

   // Now instantiate the object and call the method again
   employee = new Employee();
   employee.DisplayEmployeeDetails(); // This will work successfully
Enter fullscreen mode Exit fullscreen mode
  1. Nullable Struct Example

Create a struct called Order with a nullable Quantity property.

   public struct Order
   {
       public int? Quantity { get; set; }
   }

   Order order = new Order();
   order.Quantity = null;

   if (!order.Quantity.HasValue)
   {
       Console.WriteLine("Quantity is not assigned.");
   }
   else
   {
       Console.WriteLine($"Quantity: {order.Quantity.Value}");
   }
Enter fullscreen mode Exit fullscreen mode

Level 3: Difficult

  1. Complex Object Relationships

Create a class Department with a nullable reference to an Employee as its Manager. Write logic to assign a default manager if the Manager is null.

   public class Department
   {
       public Employee? Manager { get; set; }
   }

   Department department = new Department();

   if (department.Manager == null)
   {
       Console.WriteLine("No manager assigned, setting default manager.");
       department.Manager = new Employee { Name = "Default Manager" };
   }

   Console.WriteLine($"Manager: {department.Manager.Name}");
Enter fullscreen mode Exit fullscreen mode
  1. Null-Coalescing Assignment

Use the null-coalescing assignment operator (??=) to assign values only if they are null. Update the Employee class to have a nullable HourlyRate and set a default value if it's null.

   public class Employee
   {
       public string Name { get; set; }
       public double? HourlyRate { get; set; }
   }

   Employee mysteryEmployee = new Employee();

   mysteryEmployee.HourlyRate ??= 15.0; // Assign default hourly rate if null
   Console.WriteLine($"Hourly Rate: {mysteryEmployee.HourlyRate}");
Enter fullscreen mode Exit fullscreen mode
  1. Working with Nullable Collections

Create a list of nullable double values representing employee salaries. Iterate through the list and use the null-coalescing operator to provide a default value for any null entries.

   List<double?> salaries = new List<double?> { 50000, null, 75000, null, 60000 };

   foreach (var salary in salaries)
   {
       Console.WriteLine($"Salary: {salary ?? 30000}"); // Use 30000 if salary is null
   }
Enter fullscreen mode Exit fullscreen mode

Conclusion

Understanding null and how to handle it properly is crucial when working with reference and value types in C#. This knowledge helps you prevent runtime issues like NullReferenceException and allows for more flexible handling of data, especially in scenarios where values might be absent.

Practice these assignments to get comfortable with how null works in C# and learn how to manage nullable types effectively, ensuring your code is more reliable and easier to maintain.

Top comments (0)