nameof (Referencia de C#)nameof (C# Reference)

Se utiliza para obtener el nombre de cadena (incompleto) simple de una variable, tipo o miembro.Used to obtain the simple (unqualified) string name of a variable, type, or member.

Al informar de errores en el código, enlazar vínculos de controlador de vistas de modelo (MVC), desencadenar eventos de propiedad cambiada, etc., a menudo le interesa capturar el nombre de cadena de un método.When reporting errors in code, hooking up model-view-controller (MVC) links, firing property changed events, etc., you often want to capture the string name of a method. Usar nameof ayuda a lograr que su código siga siendo válido al cambiar el nombre de definiciones.Using nameof helps keep your code valid when renaming definitions. Antes había que usar literales de cadena para hacer referencia a definiciones, lo que resulta precario al cambiar el nombre de elementos de código, ya que las herramientas no saben comprobar estos literales de cadena.Before, you had to use string literals to refer to definitions, which is brittle when renaming code elements because tools do not know to check these string literals.

Una expresión nameof tiene este formato:A nameof expression has this form:

if (x == null) throw new ArgumentNullException(nameof(x));
WriteLine(nameof(person.Address.ZipCode)); // prints "ZipCode"

Casos de uso claveKey Use Cases

Estos ejemplos muestran los casos de uso clave para nameof.These examples show the key use cases for nameof.

Validar parámetros:Validate parameters:

void f(string s) {
   if (s == null) throw new ArgumentNullException(nameof(s));
}

Vínculos de acción de MVC:MVC Action links:

<%= Html.ActionLink("Sign up",
             @typeof(UserController),
             @nameof(UserController.SignUp))
%>

INotifyPropertyChanged:INotifyPropertyChanged:

int p {
    get { return this.p; }
    set { this.p = value; PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.p)); } // nameof(p) works too
}

Propiedad de dependencia de XAML:XAML dependency property:

public static DependencyProperty AgeProperty = DependencyProperty.Register(nameof(Age), typeof(int), typeof(C));

Registro:Logging:

void f(int i) {
    Log(nameof(f), "method entry");
}

Atributos:Attributes:

[DebuggerDisplay("={" + nameof(GetString) + "()}")]
class C {
    string GetString() { }
}

EjemplosExamples

Algunos ejemplos de C#:Some C# examples:

using Stuff = Some.Cool.Functionality
class C {
    static int Method1 (string x, int y) {}
    static int Method1 (string x, string y) {}
    int Method2 (int z) {}
    string f<T>() => nameof(T);
}

var c = new C()

class Test {
    static void Main (string[] args) {
        Console.WriteLine(nameof(C)); // -> "C"
        Console.WriteLine(nameof(C.Method1)); // -> "Method1"
        Console.WriteLine(nameof(C.Method2)); // -> "Method2"
        Console.WriteLine(nameof(c.Method1)); // -> "Method1"
        Console.WriteLine(nameof(c.Method2)); // -> "Method2"
        // Console.WriteLine(nameof(z)); -> "z" [inside of Method2 ok, inside Method1 is a compiler error]
        Console.WriteLine(nameof(Stuff)); // -> "Stuff"
        // Console.WriteLine(nameof(T)); -> "T" [works inside of method but not in attributes on the method]
        Console.WriteLine(nameof(f)); // -> "f"
        // Console.WriteLine(nameof(f<T>)); -> [syntax error]
        // Console.WriteLine(nameof(f<>)); -> [syntax error]
        // Console.WriteLine(nameof(Method2())); -> [error "This expression does not have a name"]
    }
}

ComentariosRemarks

El argumento nameof debe ser un nombre sencillo, nombre completo, acceso a miembros, acceso base a un miembro especificado o este acceso a un miembro especificado.The argument to nameof must be a simple name, qualified name, member access, base access with a specified member, or this access with a specified member. La expresión de argumento identifica una definición de código, pero nunca se evalúa.The argument expression identifies a code definition, but it is never evaluated.

Dado que el argumento debe ser sintácticamente una expresión, hay muchas cosas no permitidas que no sería útil mostrar.Because the argument needs to be an expression syntactically, there are many things disallowed that are not useful to list. Sí vale la pena mencionar los siguientes elementos que producen errores: tipos predefinidos (por ejemplo, int o void), tipos que aceptan valores null (Point?), tipos de matriz (Customer[,]), tipos de puntero (Buffer*), alias completo (A::B), tipos genéricos sin enlazar (Dictionary<,>), símbolos de preprocesamiento (DEBUG) y etiquetas (loop:).The following are worth mentioning that produce errors: predefined types (for example, int or void), nullable types (Point?), array types (Customer[,]), pointer types (Buffer*), qualified alias (A::B), and unbound generic types (Dictionary<,>), preprocessing symbols (DEBUG), and labels (loop:).

Si necesita obtener el nombre completo, puede utilizar la expresión typeof junto con nameof.If you need to get the fully-qualified name, you can use the typeof expression along with nameof. Por ejemplo:For example:

class C {
    void f(int i) {
        Log($"{typeof(C)}.{nameof(f)}", "method entry");
    }
}

typeof no es una expresión constante como nameof, por lo que typeof no puede usarse junto con nameof en los mismos lugares que nameof.Unfortunately typeof is not a constant expression like nameof, so typeof cannot be used in conjunction with nameof in all the same places as nameof. Por ejemplo, el siguiente ejemplo provocaría un error de compilación CS0182:For example, the following would cause a CS0182 compile error:

[DebuggerDisplay("={" + typeof(C) + nameof(GetString) + "()}")]
class C {
    string GetString() { }
}

En los ejemplos verá que puede utilizar un nombre de tipo y acceder a un nombre de método de instancia.In the examples you see that you can use a type name and access an instance method name. No es necesario tener una instancia del tipo, tal como se requiere en las expresiones evaluadas.You do not need to have an instance of the type, as required in evaluated expressions. Usar el nombre de tipo puede ser muy práctico en algunas situaciones, y puesto que solo hace referencia al nombre y no utiliza datos de instancia, no necesita idear una expresión o una variable de instancia.Using the type name can be very convenient in some situations, and since you are just referring to the name and not using instance data, you do not need to contrive an instance variable or expression.

Puede hacer referencia a los miembros de una clase en expresiones de atributos en la clase.You can reference the members of a class in attribute expressions on the class.

No hay ninguna manera de obtener información de firma, como "Method1 (str, str)".There is no way to get a signatures information such as "Method1 (str, str)". Una manera de hacerlo es usar una expresión, Expression e = () => A.B.Method1("s1", "s2"), y extraer el MemberInfo del árbol de expresión resultante.One way to do that is to use an Expression, Expression e = () => A.B.Method1("s1", "s2"), and pull the MemberInfo from the resulting expression tree.

Especificaciones del lenguajeLanguage Specifications

Para obtener más información, vea la sección Expresiones nameof de la Especificación del lenguaje C#.For more information, see Nameof expressions in the C# Language Specification. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.The language specification is the definitive source for C# syntax and usage.

Vea tambiénSee also