咨询区
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: nopIL_0001: ldstr "Gigi"IL_0006: stloc.0IL_0007: ldstr "firstname"IL_000c: stloc.1IL_000d: ldloc.1IL_000e: call void [System.Console]System.Console::WriteLine(string)IL_0013: nopIL_0014: call string [System.Console]System.Console::ReadLine()IL_0019: popIL_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# 🐂👃。