Skip to content

Extended nameof scope C# 11.0readabilitycorrectness

Use nameof with method parameters in attributes on that method.

The nameof operator could not reference method parameters when used in attribute arguments on the method or its parameters. This forced developers to use hardcoded strings that could silently become stale when parameters were renamed.

C# 11 extends the scope of nameof so that method parameter names are accessible in attributes on the method, its parameters, and its type parameters.

The practical value is refactor safety. A hardcoded "input" still compiles and still produces the same string if the parameter is later renamed to value, silently breaking the attribute's meaning. nameof(input) is rewritten by the compiler to the literal "input" but is tracked by rename operations, so the rename updates it automatically.

Code ​

csharp
[return: NotNullIfNotNull(nameof(input))]
public string? Process(string? input)
{
    return input?.Trim();
}

public void Copy(
    [DisallowNull] string source,
    [CallerArgumentExpression(nameof(source))] string? expr = null)
{
}
csharp
[return: NotNullIfNotNull("input")]
public string? Process(string? input)
{
    return input?.Trim();
}

public void Copy(
    [DisallowNull] string source,
    [CallerArgumentExpression("source")] string? expr = null)
{
}

Notes ​

  • nameof is evaluated at compile time, so the attribute argument is still the constant string "input" in the IL - nothing runs at runtime
  • This pairs naturally with CallerArgumentExpression C# 10.0, which is the most common place to need a parameter name inside an attribute
  • Also works in attributes on the method's type parameters as well as on the method and its parameters
  • Earlier versions required the literal string, which no compiler analysis or refactoring tool could verify

More information ​

Powered by Intracia