Isaac.

csharp

C# Nullable Reference Types

Eliminate null reference exceptions with nullable reference types.

By Emem IsaacMarch 3, 20223 min read
#csharp#nullable#null safety#types
Share:

A Simple Analogy

Nullable reference types are like seatbelts. They alert you when something might be null, helping you catch potential crashes before they happen.


Why Nullable Reference Types?

  • Null safety: Compiler prevents null reference exceptions
  • Documentation: Code shows intent (nullable or not)
  • Reduced bugs: Catch issues at compile-time
  • Backward compatible: Opt-in per project
  • Better design: Forces thinking about null cases

Enable Feature

// In .csproj
<PropertyGroup>
    <Nullable>enable</Nullable>  // Or "warnings", "annotations"
</PropertyGroup>

// Or in file
#nullable enable

public class Order
{
    public string Id { get; set; } = "";  // Non-nullable, must initialize
    public string? Description { get; set; }  // Nullable, can be null
}

Non-Nullable by Default

#nullable enable

public class User
{
    // Non-nullable properties
    public string Name { get; set; } = "";  // Must initialize
    public int Age { get; set; }
    public string Email { get; set; } = "";

    // Nullable properties  
    public string? Phone { get; set; }  // Can be null
    public string? Address { get; set; }
    
    // Constructor
    public User(string name, string email)
    {
        Name = name;
        Email = email;
        Age = 0;
        // Phone and Address can be null
    }
}

// Compiler prevents this
var user = new User(name: null, email: "test@example.com");  // ERROR

// And this
string notnull = user.Phone;  // ERROR: Phone can be null

// But allows this
string? nullable = user.Phone;  // OK

Null Coalescing

#nullable enable

public class OrderService
{
    public void ProcessOrder(Order? order)
    {
        // Option 1: Check for null
        if (order == null) return;
        
        var total = order.Total;  // Safe after null check
        
        // Option 2: Coalesce
        var description = order.Description ?? "No description";
        
        // Option 3: Conditional access
        var customerName = order.Customer?.Name ?? "Unknown";
        
        // Option 4: Null forgiving operator (use sparingly!)
        var id = order.Id!;  // I know it's not null
    }
}

Validation with Null Checks

public class UserValidator
{
    public bool Validate(User? user)
    {
        if (user == null)
            return false;
        
        if (string.IsNullOrEmpty(user.Name))
            return false;
        
        if (user.Age < 0 || user.Age > 150)
            return false;
        
        return true;
    }
}

// Usage
User? user = GetUserOrNull();

if (user != null && user.Name.Length > 3)
{
    // Safe: both user and Name are non-null here
    ProcessUser(user);
}

Nullable Collections

public class Order
{
    // Non-null list, non-null items
    public List<OrderItem> Items { get; set; } = new();
    
    // Nullable list (list itself can be null)
    public List<OrderItem>? OptionalItems { get; set; }
    
    // Non-null list with nullable items
    public List<string?> Tags { get; set; } = new();
}

// Usage
var order = new Order();

// Safe
order.Items.Add(new OrderItem());  // Items is never null

// Need to check
if (order.OptionalItems != null)
{
    order.OptionalItems.Add(new OrderItem());
}

// Can contain nulls
order.Tags.Add(null);  // OK
string? tag = order.Tags[0];  // Could be null

Best Practices

  1. Enable globally: Set in project file
  2. Use #nullable enable: In legacy codebases
  3. Suppress warnings: Only when justified
  4. Null forgiving sparingly: Use ! rarely
  5. Document nullable: Explain why null is possible

Related Concepts

  • Option types (functional programming)
  • Maybe monad
  • Null object pattern
  • Defensive copying

Summary

Nullable reference types bring compile-time null safety to C#. Enable them project-wide to catch null reference exceptions before runtime.

Share:

Written by Emem Isaac

Expert Software Engineer with 15+ years of experience building scalable enterprise applications. Specialized in ASP.NET Core, Azure, Docker, and modern web development. Passionate about sharing knowledge and helping developers grow.

Ready to Build Something Amazing?

Let's discuss your project and explore how my expertise can help you achieve your goals. Free consultation available.

💼 Trusted by 50+ companies worldwide | ⚡ Average response time: 24 hours