csharp:系统关键词:nameof

C# 中的 nameof 关键字

nameof 表达式是 C# 6.0 引入的一个非常实用的特性。它用于在编译时获取变量、类型或成员的名称(字符串形式)。

在 `nameof` 出现之前,我们通常使用硬编码的字符串来引用参数名或属性名。这样做有很大的弊端:

  • 重构困难:如果你重命名了一个变量,硬编码的字符串不会自动更新。
  • 容易出错:拼写错误在编译时无法发现,只有在运行时才会报错。

nameof 解决了这些问题,因为它在编译时进行求值。如果引用的名称不存在,编译器会报错。

语法非常简单:

nameof(element)
  • element: 可以是类名、方法名、属性名、参数名或变量名。
  • 返回值: 一个字符串字面量。

这是 `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
    }
}
  • 安全性:将运行时错误转变为编译时错误。
  • 可维护性:支持 IDE 的重构工具(重命名)。
  • 可读性:代码意图更清晰。

建议在任何需要使用代码元素名称作为字符串的地方,优先使用 nameof

该主题尚不存在

您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。

  • csharp/系统关键词/nameof.txt
  • 最后更改: 2026/01/14 09:32
  • 张叶安