¿Se evalúa nameof () en tiempo de compilación?


En C # 6, puede utilizar el nameof() operador para obtener una cadena que contiene el nombre de una variable o un tipo.

¿Se evalúa esto en tiempo de compilación, o en tiempo de ejecución a través de alguna API de Roslyn?

Puedes leer sobre el operador nameof() en la discusión oficial señalada en la respuesta aceptada , o en la publicación dedicada en mi blog . El 2000things.com , puede encontrar su descripción y ejemplo de su uso.

Author: Community, 2014-10-26

2 answers

Sí. nameof() se evalúa en tiempo de compilación. Mirando la última versión de las especificaciones:

El nombre de la expresión es una constante. En todos los casos, nameof(...) es evaluado en tiempo de compilación para producir una cadena. Su argumento no se evalúa en tiempo de ejecución, y se considera código inalcanzable (sin embargo, no emite una advertencia de "código inalcanzable").

From nameof operator-v5

Puedes ver que con este ejemplo de TryRoslyn donde esto:

public class Foo
{
    public void Bar()
    {
        Console.WriteLine(nameof(Foo));
    }
}

Se compila y descompila en esto:

public class Foo
{
    public void Bar()
    {
        Console.WriteLine("Foo");
    }
}

Su equivalente en tiempo de ejecución es:

public class Foo
{
    public void Bar()
    {
        Console.WriteLine(typeof(Foo).Name);
    }
}

Como se mencionó en los comentarios, eso significa que cuando use nameof en parámetros de tipo en un tipo genérico, no espere obtener el nombre del tipo dinámico real utilizado como parámetro de tipo en lugar de solo el nombre del parámetro de tipo. Así que esto:

public class Foo
{
    public void Bar<T>()
    {
        Console.WriteLine(nameof(T));
    }
}

Será esto:

public class Foo
{
    public void Bar<T>()
    {
        Console.WriteLine("T");
    }
}
 109
Author: i3arnon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-13 23:39:57

Quería enriquecer la respuesta proporcionada por @I3arnon con una prueba de que se evalúa en tiempo de compilación.

Supongamos que quiero imprimir el nombre de una variable en la Consola usando el operador nameof:

 var firstname = "Gigi";
 var varname = nameof(firstname);
 Console.WriteLine(varname); // Prints "firstname" to the console

Cuando revisas el MSIL generado verás que es equivalente a una declaración de cadena porque una referencia de objeto a una cadena se envía a la pila usando el operador ldstr:

IL_0001: ldstr "Gigi"
IL_0006: stloc.0
IL_0007: ldstr "firstname"
IL_000c: stloc.1
IL_000d: ldloc.1
IL_000e: call void [mscorlib]System.Console::WriteLine(string)

Notará que declarar la cadena firstname y usando el operador nameof genera el mismo código en MSIL, lo que significa que nameof es tan eficiente como declarar una variable de cadena.

 57
Author: Faris Zacina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:06