Roslyn é a nova plataforma de compilador. Só é usado em tempo de compilação.
Paulo Morgado
2
@PauloMorgado isso não é verdade, você pode usar Rosyln em tempo de execução para fazer as coisas. Como construir um editor de código ativo ou usar a análise de Rosyln para fazer coisas com árvores ou expressões ou algo assim
Chris Marisic,
@ChrisMarisic essa é a minha impressão, mas não respondi pois meu conhecimento sobre o assunto é limitado (daí minha pergunta). Eu me deparei com isso: scriptcs.net que é um bom exemplo do poder de Roslyn, e que acredito que faça coisas de tempo de execução, mas posso estar errado, pois não estou muito bem informado sobre isso.
Gigi
@ChrisMarisic, então, o que você está dizendo é que você pode usar o Roslyn para construir código ativo a partir do código-fonte, não a partir de um binário em execução. E você ainda está usando o Roslyn para transformar a origem em binários que não usará o Roslyn para alterar esses binários. Se você não pudesse usar o Roslyn de forma absoluta em tempo de execução, nunca poderia compilar nenhum código.
Paulo Morgado
Respostas:
119
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").
Como foi mencionado nos comentários, isso significa que quando você usa nameofem 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:
Vamos supor que eu queira imprimir o nome de uma variável no console usando o nameofoperador:
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 ldstroperador:
Você notará que declarar a string de nome e usar o nameofoperador gera o mesmo código em MSIL, o que significa que nameofé tão eficiente quanto declarar uma variável de string.
Se o MSIL for descompilado para o código-fonte, quão fácil será para o descompilador reconhecer que era um nameofoperador, não uma string codificada permanentemente?
ADTC
11
Esta é uma boa pergunta! você pode postá-lo como uma nova pergunta no SO se quiser obter uma explicação detalhada :) .. no entanto, a resposta curta é que o descompilador não será capaz de descobrir que era um operador nameof, mas usará um literal de string em vez . Verifiquei que é o caso com ILSpy e Reflector.
Faris Zacina
2
@ADTC: Como o nameof foi totalmente substituído por load-a-string-on-the-stack, como o descompilador poderia tentar adivinhar que era um nameof e não um parâmetro constante simples?
quetzalcoatl
2
Isso é interessante. Talvez o descompilador possa verificar a string em relação ao contexto atual (nome do método / propriedade / etc em que você está). Ainda assim, não há como ser 100% confiável - você pode ter usado uma string codificada no final das contas.
Gigi
2
Embora eu concorde que você não pode saber se é um nameof após a compilação, não vejo qualquer indicação de que ILSpy ou Reflector suportam C # 6 ainda. Se for esse o caso, você não pode testá-lo @TheMinister
Respostas:
Sim.
nameof()
é avaliado em tempo de compilação. Olhando para a versão mais recente das especificações:De nameof operator - v5
Você pode ver isso com este exemplo TryRoslyn onde isto:
É compilado e descompilado em:
Seu equivalente em tempo de execução é:
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:Vai se tornar isso:
fonte
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: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:Você notará que declarar a string de nome e usar o
nameof
operador gera o mesmo código em MSIL, o que significa quenameof
é tão eficiente quanto declarar uma variável de string.fonte
nameof
operador, não uma string codificada permanentemente?