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
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
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
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
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.