En C # 6, vous pouvez utiliser l' nameof()
opérateur pour obtenir une chaîne contenant le nom d'une variable ou d'un type.
Est-ce évalué au moment de la compilation ou à l'exécution via une API Roslyn?
En C # 6, vous pouvez utiliser l' nameof()
opérateur pour obtenir une chaîne contenant le nom d'une variable ou d'un type.
Est-ce évalué au moment de la compilation ou à l'exécution via une API Roslyn?
Réponses:
Oui. nameof()
est évalué au moment de la compilation. En regardant la dernière version des spécifications:
Le nom de l'expression est une constante. Dans tous les cas, nameof (...) est évalué au moment de la compilation pour produire une chaîne. Son argument n'est pas évalué à l'exécution, et est considéré comme du code inaccessible (cependant il n'émet pas d'avertissement "code inaccessible").
Depuis le nom de l'opérateur - v5
Vous pouvez le voir avec cet exemple TryRoslyn où ceci:
public class Foo
{
public void Bar()
{
Console.WriteLine(nameof(Foo));
}
}
Est compilé et décompilé en ceci:
public class Foo
{
public void Bar()
{
Console.WriteLine("Foo");
}
}
Son équivalent d'exécution est:
public class Foo
{
public void Bar()
{
Console.WriteLine(typeof(Foo).Name);
}
}
Comme mentionné dans les commentaires, cela signifie que lorsque vous utilisez des nameof
paramètres de type dans un type générique, ne vous attendez pas à obtenir le nom du type dynamique réel utilisé comme paramètre de type au lieu du nom du paramètre de type uniquement. Donc ça:
public class Foo
{
public void Bar<T>()
{
Console.WriteLine(nameof(T));
}
}
Deviendra ceci:
public class Foo
{
public void Bar<T>()
{
Console.WriteLine("T");
}
}
Je voulais enrichir la réponse fournie par @ I3arnon avec une preuve qu'elle est évaluée à la compilation.
Supposons que je souhaite imprimer le nom d'une variable dans la console à l'aide de l' nameof
opérateur:
var firstname = "Gigi";
var varname = nameof(firstname);
Console.WriteLine(varname); // Prints "firstname" to the console
Lorsque vous extrayez le MSIL généré, vous verrez qu'il est équivalent à une déclaration de chaîne car une référence d'objet à une chaîne est poussée vers la pile à l'aide de l' ldstr
opérateur:
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)
Vous remarquerez que déclarer la chaîne de prénom et utiliser l' nameof
opérateur génère le même code dans MSIL, ce qui signifie qu'il nameof
est aussi efficace que de déclarer une variable de chaîne.
nameof
opérateur et non d'une chaîne codée en dur?