C# Language Nombre del operador


Ejemplo

El operador nameof devuelve el nombre de un elemento de código como una string . Esto es útil cuando se lanzan excepciones relacionadas con los argumentos de los métodos y también cuando se implementa INotifyPropertyChanged .

public string SayHello(string greeted)
{
    if (greeted == null)
        throw new ArgumentNullException(nameof(greeted));
    
    Console.WriteLine("Hello, " + greeted);
}

El operador nameof se evalúa en el momento de la compilación y cambia la expresión a una cadena literal. Esto también es útil para las cadenas que llevan el nombre de su miembro que las expone. Considera lo siguiente:

public static class Strings
{
    public const string Foo = nameof(Foo); // Rather than Foo = "Foo"
    public const string Bar = nameof(Bar); // Rather than Bar = "Bar"
}

Dado que nameof expresiones nameof expresiones son constantes en tiempo de compilación, se pueden usar en atributos, etiquetas de case , declaraciones de switch , etc.


Es conveniente usar nameof con Enum s. En lugar de:

Console.WriteLine(Enum.One.ToString());

Es posible utilizar:

Console.WriteLine(nameof(Enum.One))

La salida será One en ambos casos.


El operador nameof puede acceder a miembros no estáticos utilizando una sintaxis similar a la estática. En lugar de hacer:

string foo = "Foo";
string lengthName = nameof(foo.Length);

Puede ser reemplazado por:

string lengthName = nameof(string.Length);

La salida será Length en ambos ejemplos. Sin embargo, este último impide la creación de instancias innecesarias.


Aunque el operador nameof funciona con la mayoría de las construcciones de lenguaje, existen algunas limitaciones. Por ejemplo, no puede usar el operador nameof en tipos genéricos abiertos o valores de retorno de método:

public static int Main()
{   
    Console.WriteLine(nameof(List<>)); // Compile-time error
    Console.WriteLine(nameof(Main())); // Compile-time error
}

Además, si lo aplica a un tipo genérico, el parámetro de tipo genérico se ignorará:

Console.WriteLine(nameof(List<int>));  // "List"
Console.WriteLine(nameof(List<bool>)); // "List"

Para más ejemplos, vea este tema dedicado a nameof .


Solución para versiones anteriores ( más detalles )

Aunque el operador nameof no existe en C # para las versiones anteriores a 6.0, se puede tener una funcionalidad similar utilizando MemberExpression como se MemberExpression a continuación:

6.0

Expresión:

public static string NameOf<T>(Expression<Func<T>> propExp)
{
    var memberExpression = propExp.Body as MemberExpression;
    return memberExpression != null ? memberExpression.Member.Name : null;
}

public static string NameOf<TObj, T>(Expression<Func<TObj, T>> propExp)
{
    var memberExpression = propExp.Body as MemberExpression;
    return memberExpression != null ? memberExpression.Member.Name : null;
}

Uso:

string variableName = NameOf(() => variable);
string propertyName = NameOf((Foo o) => o.Bar);

Tenga en cuenta que este enfoque hace que se cree un árbol de expresiones en cada llamada, por lo que el rendimiento es mucho peor en comparación con el nameof operador, que se evalúa en el momento de la compilación y no tiene sobrecarga en el tiempo de ejecución.