En C # 6, puede usar el nameof()
operador para obtener una cadena que contenga el nombre de una variable o un tipo.
¿Esto se evalúa en tiempo de compilación o en tiempo de ejecución a través de alguna API de Roslyn?
En C # 6, puede usar el nameof()
operador para obtener una cadena que contenga el nombre de una variable o un tipo.
¿Esto se evalúa en tiempo de compilación o en tiempo de ejecución a través de alguna API de Roslyn?
Respuestas:
Si. 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 (...) se evalúa 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").
Desde el nombre del operador - v5
Puede 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
parámetros de tipo en un tipo genérico, no espere obtener el nombre del tipo dinámico real que se usa 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));
}
}
Se convertirá en esto:
public class Foo
{
public void Bar<T>()
{
Console.WriteLine("T");
}
}
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 nameof
operador:
var firstname = "Gigi";
var varname = nameof(firstname);
Console.WriteLine(varname); // Prints "firstname" to the console
Cuando revise el MSIL generado, verá 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 ldstr
operador:
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 de nombre y usar el nameof
operador genera el mismo código en MSIL, lo que significa que nameof
es tan eficiente como declarar una variable de cadena.
nameof
operador, no una cadena simple codificada?