C#中的nameof运算符

在日常 C# 开发中,我们经常需要获取变量名、属性名、方法名或类型名的字符串形式,比如:

  • 抛出参数异常时提示参数名
  • 日志记录字段名称
  • 数据绑定、反射、序列化
  • MVVM / ASP.NET 中的属性通知

在 C# 6.0 之前,这些字符串往往是硬编码的魔法字符串(Magic String),维护成本极高。而 nameof 的出现,几乎是一次“工程级”的体验升级。

什么是 nameof

nameof 是 C# 6.0 引入的一个编译期运算符,用于在编译时获取一个符号(变量、属性、方法、类型等)的名称字符串。

1
2
int count = 10;
Console.WriteLine(nameof(count)); // count

核心特性:

  • 编译时解析
  • 零运行时开销
  • 重构安全(重命名不会出 Bug)

为什么要用 nameof

先看一个例子:

1
2
3
4
5
6
7
void SetAge(int age)
{
    if (age < 0)
    {
        throw new ArgumentOutOfRangeException("Age cannot be negative.", "age");
    }
}

如果某天把参数age改成userAge

1
void SetAge(int userAge)

那么问题来了:

  • 编译不会报错
  • 异常参数名仍然是字符串age
  • IDE 重构也没有用

但如果使用nameof的话:

1
2
3
4
5
6
7
void SetAge(int userAge)
{
    if (userAge < 0)
    {
        throw new ArgumentOutOfRangeException("Age cannot be negative.", nameof(userAge));
    }
}

优点立刻显现:

  • 参数名永远正确
  • 重构自动同步
  • 编译期校验

nameof 的常见用法

参数校验

1
2
3
4
public void Login(string username) {
  if (username == null)
    throw new ArgumentNullException(nameof(username));
}

这是.NET 官方源码中最常见的 nameof 使用场景。

获取属性名

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class User: INotifyPropertyChanged
{
  private string _name;

  public string Name {
    get => _name;
    set
    {
      _name = value;
      OnPropertyChanged(nameof(Name));
    }
  }
}

相比:

1
OnPropertyChanged("Name");

nameof更安全、更优雅。

日志 & 诊断信息

1
_logger.Debug("Current value of {Field}", nameof(order,TotalPrice));

避免字段名写错、重构友好。

获取类型名

1
2
Console.WriteLine(nameof(List<int>)); // List
Console.WriteLine(nameof(UserService)); // UserService

nameof(List<int>)返回的是类型名,不包含泛型参数。

方法名 / 事件名

1
2
Console.WriteLine(nameof(DoWork));
Console.WriteLine(nameof(PropertyChanged));

适用于 AOP、日志以及诊断追踪。

nameof 的一些注意点

nameof 不会求值

1
2
int count = 10;
Console.WriteLine(nameof(count + 1)); // 编译错误

nameof只接受符号,不接受表达式。

支持命名空间 & 成员访问

1
2
Console.WriteLine(nameof(System.Text.StringBuilder)); // StringBuilder
Console.WriteLine(nameof(user.Name)); // Name

只返回最后一个标识符。

推荐


相关内容

请作者喝杯咖啡!
AndyFree96 支付宝支付宝
AndyFree96 微信微信
0%