nameof() 到底是编译时还是运行时行为?
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nameof() 到底是编译时还是运行时行为?相关的知识,希望对你有一定的参考价值。
咨询区
Gigi:
在 C#6.0
中,可以用 nameof()
直接获取变量或者类型的名字,请问这是一个 编译时
还是 运行时
行为?
回答区
Faris Zacina:
可以肯定的说,它是一种 编译时
行为,我举一个例子,参考如下代码:
static void Main(string[] args)
{
var firstname = "Gigi";
var varname = nameof(firstname);
Console.WriteLine(varname);
Console.ReadLine();
}
程序跑起来后,我们观察一下它的 MSIL 代码。
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 27 (0x1b)
.maxstack 1
.entrypoint
.locals init (
[0] string firstname,
[1] string varname
)
IL_0000: nop
IL_0001: ldstr "Gigi"
IL_0006: stloc.0
IL_0007: ldstr "firstname"
IL_000c: stloc.1
IL_000d: ldloc.1
IL_000e: call void [System.Console]System.Console::WriteLine(string)
IL_0013: nop
IL_0014: call string [System.Console]System.Console::ReadLine()
IL_0019: pop
IL_001a: ret
} // end of method Program::Main
从上面的 MSIL 代码中,可以清晰的看到, nameof(firstname)
变成了 ldstr "firstname"
, 也就是说是将字符串 firstname 推送到计算堆栈上。
i3arnon:
是的, nameof()
它是一种编译器行为,其实 C# spec
规格说明上也明确提到了,同时 TryRoslyn 也给了相应的例子。
public class Foo
{
public void Bar()
{
Console.WriteLine(nameof(Foo));
}
}
编译之后会变成这样。
public class Foo
{
public void Bar()
{
Console.WriteLine("Foo");
}
}
这里简单提一下,如果想要在运行时获取类似的行为怎么处理呢?可以用反射哈。
public class Foo
{
public void Bar()
{
Console.WriteLine(typeof(Foo).Name);
}
}
点评区
在 nameof 出现之前,要实现该功能只能用反射了,太难了,现在又多了一个选择,C# 🐂👃。
以上是关于nameof() 到底是编译时还是运行时行为?的主要内容,如果未能解决你的问题,请参考以下文章