In C # 6 è possibile utilizzare l' nameof()
operatore per ottenere una stringa contenente il nome di una variabile o di un tipo.
Viene valutato in fase di compilazione o in fase di esecuzione tramite alcune API Roslyn?
In C # 6 è possibile utilizzare l' nameof()
operatore per ottenere una stringa contenente il nome di una variabile o di un tipo.
Viene valutato in fase di compilazione o in fase di esecuzione tramite alcune API Roslyn?
Risposte:
Sì. nameof()
viene valutato in fase di compilazione. Guardando l'ultima versione delle specifiche:
Il nome dell'espressione è una costante. In tutti i casi, nameof (...) viene valutato in fase di compilazione per produrre una stringa. Il suo argomento non viene valutato in fase di runtime ed è considerato codice non raggiungibile (tuttavia non emette un avviso di "codice non raggiungibile").
Puoi vederlo con questo esempio di TryRoslyn dove questo:
public class Foo
{
public void Bar()
{
Console.WriteLine(nameof(Foo));
}
}
Viene compilato e decompilato in questo:
public class Foo
{
public void Bar()
{
Console.WriteLine("Foo");
}
}
Il suo equivalente in fase di esecuzione è:
public class Foo
{
public void Bar()
{
Console.WriteLine(typeof(Foo).Name);
}
}
Come accennato nei commenti, ciò significa che quando si utilizzano nameof
parametri di tipo in un tipo generico, non aspettarsi di ottenere il nome del tipo dinamico effettivo utilizzato come parametro di tipo invece del solo nome del parametro di tipo. Così questo:
public class Foo
{
public void Bar<T>()
{
Console.WriteLine(nameof(T));
}
}
Diventerà questo:
public class Foo
{
public void Bar<T>()
{
Console.WriteLine("T");
}
}
Volevo arricchire la risposta fornita da @ I3arnon con una prova che viene valutata in fase di compilazione.
Supponiamo che io voglia stampare il nome di una variabile nella Console utilizzando l' nameof
operatore:
var firstname = "Gigi";
var varname = nameof(firstname);
Console.WriteLine(varname); // Prints "firstname" to the console
Quando controlli l'MSIL generato, vedrai che è equivalente a una dichiarazione di stringa perché un riferimento a un oggetto a una stringa viene inserito nello stack utilizzando l' ldstr
operatore:
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)
Noterai che la dichiarazione della stringa firstname e l'utilizzo nameof
dell'operatore genera lo stesso codice in MSIL, il che significa che nameof
è efficiente quanto la dichiarazione di una variabile stringa.
nameof
operatore, non una semplice stringa hardcoded?