.NET  

.NET 10 Breaking Changes: The New field Keyword

Every new .NET release brings performance improvements, but sometimes, it also brings breaking changes that can quietly break your code, such as the new field keyword.

It introduces a real risk of breaking changes if your codebase already uses a member named field.

What Problem Does field Solve?

Before C# 14, if you wanted to:

  • Validate the value being assigned

  • Transform the value

Then you could NOT use an auto property.

You had to explicitly declare a backing field:

private string _msg;

public string Message
{
    get => _msg;
    set => _msg = value ?? throw new ArgumentNullException(nameof(value));
}

This is fine until you have dozens of properties with validation logic.

It becomes repetitive, noisy, and harder to maintain.

C# 14 Fixes This

With C# 14, you can now write:

public string Message
{
    get;
    set => field = value ?? throw new ArgumentNullException(nameof(value));
}

The compiler automatically generates the backing field, and inside the accessor, you can reference it using the field keyword.

Examples Before & After C# 14

Before C# 14 (verbose version)

private int _age;

public int Age
{
    get => _age;
    set
    {
        if (value < 0)
            throw new ArgumentOutOfRangeException(nameof(value));
        _age = value;
    }
}

C# 14 version

public int Age
{
    get;
    set
    {
        if (value < 0)
            throw new ArgumentOutOfRangeException(nameof(value));
        field = value;
    }
}

Important: Possible Breaking Change!

Because field is now a contextual keyword, any existing type member named field can now conflict with it.

Example of a problem

public class User
{
    public string field;

    public string Name
    {
        get;
        set => field = value; // Which 'field' are we setting??
    }
}

This is ambiguous and confusing. Fix it by :

set => @field = value;

or

set => this.field = value;

or (best option) rename the old field 🤔