C#idiomatic C#
nameofcsharp/language-reference/operators

Language

nameof expression (C# reference)

The C# `nameof` expression produces the name of its operand. You use it whenever you need to use the name of a symbol as text

  • page csharp/language-reference/operators/nameof
  • updated 01/20/2026

A nameof expression produces the name of a variable, type, or member as the string constant. A nameof expression is evaluated at compile time and has no effect at run time. When the operand is a type or a namespace, the produced name isn't fully qualified.


ms.custom: "updateeachrelease"

The C# language reference documents the most recently released version of the C# language. It also contains initial documentation for features in public previews for the upcoming language release.

The documentation identifies any feature first introduced in the last three versions of the language or in current public previews.

The following example shows how to use a nameof expression:

sample · csharpdocs/csharp/language-reference/operators/snippets/shared/NameOfOperator.csExamples

csharp
namespace operators;

public static class NameOfOperator
{
    public static void Examples()
    {
        // <SnippetExamples>
        Console.WriteLine(nameof(System.Collections.Generic));  // output: Generic
        Console.WriteLine(nameof(List<int>));  // output: List
        Console.WriteLine(nameof(List<>)); // output: List
        Console.WriteLine(nameof(List<int>.Count));  // output: Count
        Console.WriteLine(nameof(List<int>.Add));  // output: Add

        List<int> numbers = new List<int>() { 1, 2, 3 };
        Console.WriteLine(nameof(numbers));  // output: numbers
        Console.WriteLine(nameof(numbers.Count));  // output: Count
        Console.WriteLine(nameof(numbers.Add));  // output: Add
        // </SnippetExamples>

        // <SnippetVerbatim>
        var @new = 5;
        Console.WriteLine(nameof(@new));  // output: new
        // </SnippetVerbatim>
    }

    // <SnippetNameOfParameter>
    [ParameterString(nameof(msg))]
    public static void Method(string msg)
    {
        [ParameterString(nameof(T))]
        void LocalFunction<T>(T param) { }

        var lambdaExpression = ([ParameterString(nameof(aNumber))] int aNumber) => aNumber.ToString();
    }
    // </SnippetNameOfParameter>

    public class ParameterStringAttribute : Attribute
    {
        public ParameterStringAttribute(string parameterName) { }
    }

    private class Person
    {
        string name = string.Empty;

        // <SnippetExceptionMessage>
        public string Name
        {
            get => name;
            set => name = value ?? throw new ArgumentNullException(nameof(value), $"{nameof(Name)} cannot be null");
        }
        // </SnippetExceptionMessage>
    }
}

The preceding example that uses List<> is supported in C# 14 and later. The operand of nameof can be an unbound generic type, such as List<> or Dictionary<,>. The result is the simple type name without arity or any type-argument list — nameof(List<>) returns "List". Unbound generic operands are useful in logging, diagnostic messages, and attribute arguments where the generic type name matters but the type arguments don't.

You can use a nameof expression to make the argument-checking code more maintainable:

sample · csharpdocs/csharp/language-reference/operators/snippets/shared/NameOfOperator.csExceptionMessage

csharp
namespace operators;

public static class NameOfOperator
{
    public static void Examples()
    {
        // <SnippetExamples>
        Console.WriteLine(nameof(System.Collections.Generic));  // output: Generic
        Console.WriteLine(nameof(List<int>));  // output: List
        Console.WriteLine(nameof(List<>)); // output: List
        Console.WriteLine(nameof(List<int>.Count));  // output: Count
        Console.WriteLine(nameof(List<int>.Add));  // output: Add

        List<int> numbers = new List<int>() { 1, 2, 3 };
        Console.WriteLine(nameof(numbers));  // output: numbers
        Console.WriteLine(nameof(numbers.Count));  // output: Count
        Console.WriteLine(nameof(numbers.Add));  // output: Add
        // </SnippetExamples>

        // <SnippetVerbatim>
        var @new = 5;
        Console.WriteLine(nameof(@new));  // output: new
        // </SnippetVerbatim>
    }

    // <SnippetNameOfParameter>
    [ParameterString(nameof(msg))]
    public static void Method(string msg)
    {
        [ParameterString(nameof(T))]
        void LocalFunction<T>(T param) { }

        var lambdaExpression = ([ParameterString(nameof(aNumber))] int aNumber) => aNumber.ToString();
    }
    // </SnippetNameOfParameter>

    public class ParameterStringAttribute : Attribute
    {
        public ParameterStringAttribute(string parameterName) { }
    }

    private class Person
    {
        string name = string.Empty;

        // <SnippetExceptionMessage>
        public string Name
        {
            get => name;
            set => name = value ?? throw new ArgumentNullException(nameof(value), $"{nameof(Name)} cannot be null");
        }
        // </SnippetExceptionMessage>
    }
}

You can use a nameof expression with a method parameter inside an attribute on a method or its parameter. The following code shows how to do that for an attribute on a method, a local function, and the parameter of a lambda expression:

sample · csharpdocs/csharp/language-reference/operators/snippets/shared/NameOfOperator.csSnippetNameOfParameter

csharp
namespace operators;

public static class NameOfOperator
{
    public static void Examples()
    {
        // <SnippetExamples>
        Console.WriteLine(nameof(System.Collections.Generic));  // output: Generic
        Console.WriteLine(nameof(List<int>));  // output: List
        Console.WriteLine(nameof(List<>)); // output: List
        Console.WriteLine(nameof(List<int>.Count));  // output: Count
        Console.WriteLine(nameof(List<int>.Add));  // output: Add

        List<int> numbers = new List<int>() { 1, 2, 3 };
        Console.WriteLine(nameof(numbers));  // output: numbers
        Console.WriteLine(nameof(numbers.Count));  // output: Count
        Console.WriteLine(nameof(numbers.Add));  // output: Add
        // </SnippetExamples>

        // <SnippetVerbatim>
        var @new = 5;
        Console.WriteLine(nameof(@new));  // output: new
        // </SnippetVerbatim>
    }

    // <SnippetNameOfParameter>
    [ParameterString(nameof(msg))]
    public static void Method(string msg)
    {
        [ParameterString(nameof(T))]
        void LocalFunction<T>(T param) { }

        var lambdaExpression = ([ParameterString(nameof(aNumber))] int aNumber) => aNumber.ToString();
    }
    // </SnippetNameOfParameter>

    public class ParameterStringAttribute : Attribute
    {
        public ParameterStringAttribute(string parameterName) { }
    }

    private class Person
    {
        string name = string.Empty;

        // <SnippetExceptionMessage>
        public string Name
        {
            get => name;
            set => name = value ?? throw new ArgumentNullException(nameof(value), $"{nameof(Name)} cannot be null");
        }
        // </SnippetExceptionMessage>
    }
}

A nameof expression with a parameter is useful when you use the nullable analysis attributes or the CallerArgumentExpression attribute.

When the operand is a verbatim identifier, the @ character isn't part of the name, as the following example shows:

sample · csharpdocs/csharp/language-reference/operators/snippets/shared/NameOfOperator.csVerbatim

csharp
namespace operators;

public static class NameOfOperator
{
    public static void Examples()
    {
        // <SnippetExamples>
        Console.WriteLine(nameof(System.Collections.Generic));  // output: Generic
        Console.WriteLine(nameof(List<int>));  // output: List
        Console.WriteLine(nameof(List<>)); // output: List
        Console.WriteLine(nameof(List<int>.Count));  // output: Count
        Console.WriteLine(nameof(List<int>.Add));  // output: Add

        List<int> numbers = new List<int>() { 1, 2, 3 };
        Console.WriteLine(nameof(numbers));  // output: numbers
        Console.WriteLine(nameof(numbers.Count));  // output: Count
        Console.WriteLine(nameof(numbers.Add));  // output: Add
        // </SnippetExamples>

        // <SnippetVerbatim>
        var @new = 5;
        Console.WriteLine(nameof(@new));  // output: new
        // </SnippetVerbatim>
    }

    // <SnippetNameOfParameter>
    [ParameterString(nameof(msg))]
    public static void Method(string msg)
    {
        [ParameterString(nameof(T))]
        void LocalFunction<T>(T param) { }

        var lambdaExpression = ([ParameterString(nameof(aNumber))] int aNumber) => aNumber.ToString();
    }
    // </SnippetNameOfParameter>

    public class ParameterStringAttribute : Attribute
    {
        public ParameterStringAttribute(string parameterName) { }
    }

    private class Person
    {
        string name = string.Empty;

        // <SnippetExceptionMessage>
        public string Name
        {
            get => name;
            set => name = value ?? throw new ArgumentNullException(nameof(value), $"{nameof(Name)} cannot be null");
        }
        // </SnippetExceptionMessage>
    }
}

C# language specification

For more information, see the Nameof expressions section of the C# language specification.

See also