In C # 6 können Sie den nameof()
Operator verwenden, um eine Zeichenfolge abzurufen, die den Namen einer Variablen oder eines Typs enthält.
Wird dies zur Kompilierungszeit oder zur Laufzeit über eine Roslyn-API ausgewertet?
In C # 6 können Sie den nameof()
Operator verwenden, um eine Zeichenfolge abzurufen, die den Namen einer Variablen oder eines Typs enthält.
Wird dies zur Kompilierungszeit oder zur Laufzeit über eine Roslyn-API ausgewertet?
Antworten:
Ja. nameof()
wird zur Kompilierungszeit ausgewertet. Schauen Sie sich die neueste Version der Spezifikationen an:
Der Name des Ausdrucks ist eine Konstante. In allen Fällen wird nameof (...) zur Kompilierungszeit ausgewertet , um eine Zeichenfolge zu erstellen. Das Argument wird zur Laufzeit nicht ausgewertet und gilt als nicht erreichbarer Code (es wird jedoch keine Warnung "Nicht erreichbarer Code" ausgegeben).
Sie können dies anhand dieses TryRoslyn-Beispiels sehen :
public class Foo
{
public void Bar()
{
Console.WriteLine(nameof(Foo));
}
}
Wird dazu kompiliert und dekompiliert:
public class Foo
{
public void Bar()
{
Console.WriteLine("Foo");
}
}
Das Laufzeitäquivalent lautet:
public class Foo
{
public void Bar()
{
Console.WriteLine(typeof(Foo).Name);
}
}
Wie in den Kommentaren erwähnt, bedeutet dies, dass Sie bei der Verwendung nameof
von Typparametern in einem generischen Typ nicht erwarten, den Namen des tatsächlichen dynamischen Typs zu erhalten, der als Typparameter verwendet wird, sondern nur den Namen des Typparameters. Also das:
public class Foo
{
public void Bar<T>()
{
Console.WriteLine(nameof(T));
}
}
Wird dies werden:
public class Foo
{
public void Bar<T>()
{
Console.WriteLine("T");
}
}
Ich wollte die Antwort von @ I3arnon mit einem Beweis bereichern, dass sie zur Kompilierungszeit ausgewertet wird.
Nehmen wir an, ich möchte den Namen einer Variablen in der Konsole mit dem nameof
Operator drucken :
var firstname = "Gigi";
var varname = nameof(firstname);
Console.WriteLine(varname); // Prints "firstname" to the console
Wenn Sie die generierte MSIL auschecken, werden Sie feststellen, dass sie einer Zeichenfolgendeklaration entspricht, da ein Objektverweis auf eine Zeichenfolge mit dem ldstr
Operator auf den Stapel verschoben wird:
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)
Sie werden feststellen, dass das Deklarieren der Vorname-Zeichenfolge und die Verwendung des nameof
Operators denselben Code in MSIL generiert. Dies bedeutet, dass dies nameof
genauso effizient ist wie das Deklarieren einer Zeichenfolgenvariablen.
nameof
Operator und nicht um eine einfache fest codierte Zeichenfolge handelt?