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 nameofparamè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' nameofopé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' ldstropé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' nameofopérateur génère le même code dans MSIL, ce qui signifie qu'il nameofest aussi efficace que de déclarer une variable de chaîne.
nameofopérateur et non d'une chaîne codée en dur?