nameof(C# 和 Visual Basic 引用)

用于获取变量、类型或成员的简单(非限定)字符串名称。当报告代码中的错误、挂接“模型-视图-控制器”(MVC) 链接、触发属性更改事件等时,通常希望捕获方法的字符串名称。使用 nameof 有助于在重命名定义时使代码始终有效。在必须使用字符串来引用定义之前(在重命名代码元素时,此操作很脆弱,因为工具不知道要检查这些字符串)。

nameof 表达式具有此形式:

if (x == null) throw new ArgumentNullException(nameof(x));
WriteLine(nameof(person.Address.ZipCode)); // prints "ZipCode”

关键用例

这些示例显示 nameof 的关键用例。

验证参数:

void f(string s) {
    if (s == null) throw new ArgumentNullException(nameof(s));
}

MVC 操作链接:

<a>HTML</a>

&lt;%= Html.ActionLink("Sign up",
             @typeof(UserController),
             @nameof(UserController.SignUp))
%&gt;

INotifyPropertyChanged:

int p {
    get { return this.p; }
    set { this.p = value; PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.p)); } // nameof(p) works too
}

XAML 依赖项属性:

public static DependencyProperty AgeProperty = DependencyProperty.Register(nameof(Age), typeof(int), typeof(C));

日志记录:

void f(int i) {
    Log(nameof(f), "method entry");
}

特性:

[DebuggerDisplay("={" + nameof(GetString) + "()}")]
class C {
    string GetString() { }
}

示例

一些 C# 示例:

using Stuff = Some.Cool.Functionality
class C {
    static int Method1 (string x, int y) {}
    static int Method1 (string x, string y) {}
    int Method2 (int z) {}
    string f<T>() => nameof(T);
}

var c = new C()

nameof(C) -> "C"
nameof(C.Method1) -> "Method1" 
nameof(C.Method2) -> "Method2"
nameof(c.Method1) -> "Method1" 
nameof(c.Method2) -> "Method2"
nameof(z) -> "z" // inside of Method2 ok, inside Method1 is a compiler error
nameof(Stuff) = "Stuff"
nameof(T) -> "T" // works inside of method but not in attributes on the method
nameof(f) -> “f”
nameof(f<T>) -> syntax error
nameof(f<>) -> syntax error
nameof(Method2()) -> error “This expression does not have a name”

上面的很多示例都适用于 Visual Basic。下面是一些特定的 Visual Basic 示例:

VB

NameOf(a!Foo) -> ' error  "This expression does not have a name"
NameOf(dict("Foo")) -> ' error  "This expression does not have a name": default property access
NameOf(dict.Item("Foo")) -> ' error  "This expression does not have a name"
NameOf(arr(2)) -> ' error  "This expression does not have a name": array element index
Dim x = Nothing 
NameOf(x.ToString(2)) -> ' error  "This expression does not have a name"
Dim o = Nothing
NameOf(o.Equals) -> ' result "Equals".  Warning: "Access of static member of instance; instance will not be evaluated"

备注

nameof 的参数必须是简单名称、限定名称、成员访问、指定成员的基访问或指定成员的此类访问。参数表达式标识代码定义,但从不进行计算。

因为在语法上参数必须为表达式,因此有很多禁用内容无需列出。以下内容会产生错误,值得一提:预定义的类型(如 intvoid)、可以为 null 的类型(Point?)、数组类型(Customer[,])、指针类型 (Buffer*)、限定别名 (A::B)、未绑定的泛型类型 (Dictionary<,>)、预处理符号 (DEBUG) 和标签 (loop:)。

如果需要获取完全限定名,可以将 typeof 表达式和 nameof结合使用。

在这些示例中,显示了可使用类型名称并访问实例方法名称。按照计算表达式的要求,无需具有类型的实例。在某些情况下使用类型名称非常方便,因为只引用名称而不使用实例数据,因此不必构建实例变量或表达式。

你可以引用类中特性表达式的类成员。

没有任何方法可以获取租入“Method1 (str, str)”等签名信息。实现该操作的一种方法是使用表达式 Expression e = () => A.B.Method1("s1", "s2"),并从生成的表达式树中拉取 MemberInfo。

语言规范

有关详细信息,请参阅 C# 语言规范。该语言规范是 C# 语法和用法的权威资料。

有关详细信息,请参阅 Visual Basic 语言参考

请参阅

C# 参考

C# 编程指南

typeof(C# 参考)

Visual Basic 语言参考

Visual Basic 编程指南