显示页面讨论反向链接回到顶部 本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。 ====== C# 中的 nameof 关键字 ====== **nameof** 表达式是 C# 6.0 引入的一个非常实用的特性。它用于在**编译时**获取变量、类型或成员的名称(字符串形式)。 ===== 1. 为什么要使用 nameof? ===== 在 `nameof` 出现之前,我们通常使用硬编码的字符串来引用参数名或属性名。这样做有很大的弊端: * **重构困难**:如果你重命名了一个变量,硬编码的字符串不会自动更新。 * **容易出错**:拼写错误在编译时无法发现,只有在运行时才会报错。 **nameof** 解决了这些问题,因为它在编译时进行求值。如果引用的名称不存在,编译器会报错。 ===== 2. 基本语法 ===== 语法非常简单: <code csharp> nameof(element) </code> * **element**: 可以是类名、方法名、属性名、参数名或变量名。 * **返回值**: 一个字符串字面量。 ===== 3. 常见使用场景 ===== ==== 3.1 参数验证 (Argument Validation) ==== 这是 `nameof` 最常见的用途。当抛出 `ArgumentNullException` 或 `ArgumentException` 时,需要提供参数的名称。 **旧写法 (不推荐):** <code csharp> public void ProcessUser(User user) { if (user == null) { // 如果 user 参数改名,这里容易忘记修改 throw new ArgumentNullException("user"); } } </code> **使用 nameof (推荐):** <code csharp> public void ProcessUser(User user) { if (user == null) { // 编译时检查,重构安全 throw new ArgumentNullException(nameof(user)); } } </code> ==== 3.2 INotifyPropertyChanged 实现 ==== 在 WPF、WinForms 或 MAUI 开发中,实现 `INotifyPropertyChanged` 接口时,需要传递属性名称的字符串。 <code csharp> 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; } </code> ==== 3.3 日志记录 (Logging) ==== 在记录日志时,自动获取当前方法或类的名称,避免手动输入。 <code csharp> public void Execute() { try { // ... 业务逻辑 } catch (Exception ex) { // 输出: "Error in method: Execute" Logger.LogError($"Error in method: {nameof(Execute)}", ex); } } </code> ==== 3.4 路由与控制器 (ASP.NET Core) ==== 在生成链接或重定向时,引用控制器或动作的名称。 <code csharp> public IActionResult Index() { // RedirectToAction("Privacy"); // 旧写法 return RedirectToAction(nameof(Privacy)); // 推荐写法 } public IActionResult Privacy() { return View(); } </code> ===== 4. 进阶细节与注意事项 ===== ^ 特性 ^ 说明 ^ 示例 ^ 结果 ^ | **获取限定名称** | `nameof` 只返回最后一部分的名称,不包含命名空间或类前缀。 | `nameof(System.String)` | "String" | | **数组属性** | 可以获取数组的 Length 属性。 | `nameof(array.Length)` | "Length" | | **泛型** | 可以用于开放泛型类型。 | `nameof(List<T>)` | "List" | | **别名** | 如果使用了 `using` 别名,`nameof` 返回别名。 | `using Sys = System;` <br> `nameof(Sys)` | "Sys" | ==== 示例代码演示 ==== <code csharp> 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 } } </code> ===== 5. 总结 ===== * **安全性**:将运行时错误转变为编译时错误。 * **可维护性**:支持 IDE 的重构工具(重命名)。 * **可读性**:代码意图更清晰。 建议在任何需要使用代码元素名称作为字符串的地方,优先使用 **nameof**。 登录 Detach Close 该主题尚不存在 您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。 csharp/系统关键词/nameof.txt 最后更改: 2026/01/14 09:32由 张叶安 登录