nameof()是在编译时计算的吗?
在C#6中,可以使用nameof()
运算符来获取包含variables或types名称的string。
这是评估在编译时,或在运行时通过一些Roslyn API?
您可以在接受的答案中指出的官方讨论或我博客上的专门post中阅读有关nameof()
运算符的信息 。 在2000things.com上 ,你可以find它的描述和使用的例子。
是。 nameof()
在编译时被评估。 看最新版本的规格:
expression式的名字是一个常量。 在所有情况下,nameof(…) 在编译时被计算出来以产生一个string。 它的参数在运行时不被评估,被认为是无法访问的代码(但不会发出“无法访问的代码”警告)。
从运营商的名字 – v5
你可以看到这个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); } }
正如在注释中提到的那样,这意味着当您在genericstypes的types参数上使用nameof
时,不要期望获取用作types参数的实际dynamictypes的名称,而不仅仅是types参数的名称。 所以这:
public class Foo { public void Bar<T>() { Console.WriteLine(nameof(T)); } }
会成为这样的:
public class Foo { public void Bar<T>() { Console.WriteLine("T"); } }
我想丰富@ I3arnon提供的答案 ,certificate它在编译时被评估。
让我们假设我想要使用nameof
运算符在控制台中打印variables的名称:
var firstname = "Gigi"; var varname = nameof(firstname); Console.WriteLine(varname); // Prints "firstname" to the console
当你签出生成的MSIL时,你会发现它相当于一个string声明,因为一个string的对象引用被使用ldstr
操作符推送到堆栈:
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)
您会注意到声明名字string并使用nameof
运算符会在MSIL中生成相同的代码,这意味着nameof
与声明stringvariables的效率相同。