nameof 表达式是 C# 6.0 引入的一个非常实用的特性。它用于在编译时获取变量、类型或成员的名称(字符串形式)。
在 `nameof` 出现之前,我们通常使用硬编码的字符串来引用参数名或属性名。这样做有很大的弊端:
nameof 解决了这些问题,因为它在编译时进行求值。如果引用的名称不存在,编译器会报错。
这是 `nameof` 最常见的用途。当抛出 `ArgumentNullException` 或 `ArgumentException` 时,需要提供参数的名称。
旧写法 (不推荐):
public void ProcessUser(User user) { if (user == null) { // 如果 user 参数改名,这里容易忘记修改 throw new ArgumentNullException("user"); } }
使用 nameof (推荐):
public void ProcessUser(User user) { if (user == null) { // 编译时检查,重构安全 throw new ArgumentNullException(nameof(user)); } }
在 WPF、WinForms 或 MAUI 开发中,实现 `INotifyPropertyChanged` 接口时,需要传递属性名称的字符串。
public class ViewModel : INotifyPropertyChanged { private string _name; public string Name { get { return _name; } set { _name = value; // 使用 nameof(Name) 替代 "Name" PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name))); } } public event PropertyChangedEventHandler PropertyChanged; }
在记录日志时,自动获取当前方法或类的名称,避免手动输入。
public void Execute() { try { // ... 业务逻辑 } catch (Exception ex) { // 输出: "Error in method: Execute" Logger.LogError($"Error in method: {nameof(Execute)}", ex); } }
在生成链接或重定向时,引用控制器或动作的名称。
public IActionResult Index() { // RedirectToAction("Privacy"); // 旧写法 return RedirectToAction(nameof(Privacy)); // 推荐写法 } public IActionResult Privacy() { return View(); }
| 特性 | 说明 | 示例 | 结果 |
|---|---|---|---|
| 获取限定名称 | `nameof` 只返回最后一部分的名称,不包含命名空间或类前缀。 | `nameof(System.String)` | “String” |
| 数组属性 | 可以获取数组的 Length 属性。 | `nameof(array.Length)` | “Length” |
| 泛型 | 可以用于开放泛型类型。 | `nameof(List<T>)` | “List” |
| 别名 | 如果使用了 `using` 别名,`nameof` 返回别名。 | `using Sys = System;` <br> `nameof(Sys)` | “Sys” |
using System; using System.Collections.Generic; public class Program { public static void Main() { Console.WriteLine(nameof(System.String)); // 输出: String Console.WriteLine(nameof(List<int>)); // 输出: List Console.WriteLine(nameof(Program)); // 输出: Program Console.WriteLine(nameof(Main)); // 输出: Main var myVar = 10; Console.WriteLine(nameof(myVar)); // 输出: myVar // 即使是成员访问,也只取最后一部分 Console.WriteLine(nameof(Program.Main)); // 输出: Main } }
建议在任何需要使用代码元素名称作为字符串的地方,优先使用 nameof。