No C # 6, você pode usar o nameof()
operador para obter uma string contendo o nome de uma variável ou tipo.
Isso é avaliado em tempo de compilação ou em tempo de execução por meio de alguma API Roslyn?
No C # 6, você pode usar o nameof()
operador para obter uma string contendo o nome de uma variável ou tipo.
Isso é avaliado em tempo de compilação ou em tempo de execução por meio de alguma API Roslyn?
Respostas:
Sim. nameof()
é avaliado em tempo de compilação. Olhando para a versão mais recente das especificações:
O nome da expressão é uma constante. Em todos os casos, nameof (...) é avaliado em tempo de compilação para produzir uma string. Seu argumento não é avaliado em tempo de execução e é considerado código inacessível (entretanto, não emite um aviso de "código inacessível").
Você pode ver isso com este exemplo TryRoslyn onde isto:
public class Foo
{
public void Bar()
{
Console.WriteLine(nameof(Foo));
}
}
É compilado e descompilado em:
public class Foo
{
public void Bar()
{
Console.WriteLine("Foo");
}
}
Seu equivalente em tempo de execução é:
public class Foo
{
public void Bar()
{
Console.WriteLine(typeof(Foo).Name);
}
}
Como foi mencionado nos comentários, isso significa que quando você usa nameof
em parâmetros de tipo em um tipo genérico, não espere obter o nome do tipo dinâmico real usado como um parâmetro de tipo em vez de apenas o nome do parâmetro de tipo. Então, é isso:
public class Foo
{
public void Bar<T>()
{
Console.WriteLine(nameof(T));
}
}
Vai se tornar isso:
public class Foo
{
public void Bar<T>()
{
Console.WriteLine("T");
}
}
Eu queria enriquecer a resposta fornecida por @ I3arnon com uma prova de que ela é avaliada em tempo de compilação.
Vamos supor que eu queira imprimir o nome de uma variável no console usando o nameof
operador:
var firstname = "Gigi";
var varname = nameof(firstname);
Console.WriteLine(varname); // Prints "firstname" to the console
Ao verificar o MSIL gerado, você verá que ele é equivalente a uma declaração de string porque uma referência de objeto a uma string é enviada para a pilha usando o 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)
Você notará que declarar a string de nome e usar o nameof
operador gera o mesmo código em MSIL, o que significa que nameof
é tão eficiente quanto declarar uma variável de string.
nameof
operador, não uma string codificada permanentemente?