← back to index

S8367 — Identifiers should not conflict with the C# 14 "field" contextual keyword

Language: C#  |  Type: CODE_SMELL  |  Severity: Critical

Tags: csharp-14, compatibility, upgrade

This rule raises an issue when code uses 'field' as an identifier in contexts where it conflicts with the new field contextual keyword introduced in C# 14.

Why is this an issue?

C# 14 introduces the field contextual keyword for field-backed properties. This keyword allows access to the synthesized backing fields directly within property accessors, simplifying property implementations that need custom logic.

By using 'field' as an identifier, several problems can occur:

What is the potential impact?

Using 'field' as an identifier can prevent successful compilation when upgrading to C# 14. In property accessors, local variables or parameters named 'field' will cause compilation errors, while class members named 'field' may be unexpectedly overshadowed by synthesized backing fields, leading to logic errors and unexpected runtime behavior.

How to fix it

Rename the identifier, escape it by prefixing with @, or qualify member access with this. or base. to avoid conflicts with the contextual keyword. This rule applies only inside property get, set, and init accessors; indexer and event accessors are not affected.

Code examples

Noncompliant code example

public class ClassFieldExample
{
    private string field;

    public string Message
    {
        get => field; // Noncompliant
        set => field = value; // Noncompliant
    }
}
public class LocalFunctionExample
{
    public int Value
    {
        get
        {
            return LocalFunction(42);

            int LocalFunction(int field) // Noncompliant
                => field;
        }
    }
}

Compliant solution

public class ClassFieldExample
{
    private string field;

    public string Message
    {
        get => this.field;          // or @field
        set => this.field = value;  // or @field = value;
    }
}
public class LocalFunctionExample
{
    public int Value
    {
        get
        {
            return LocalFunction(42);

            int LocalFunction(int value) // Compliant - renamed
                => value;
        }
    }
}

Resources

Documentation