.NET编码规范03-C#命名规范大全

.NET编码规范

第 3 篇:命名规范大全 ------ 让你的c#代码"自文档化"

前言

"There are only two hard things in Computer Science: cache invalidation and naming things."

--- Phil Karlton

命名是编程中最难的事,也是最重要的基本功。一个好的命名让阅读者不需要翻文档就能理解代码意图;一个糟糕的命名则可能直接导致线上 Bug。

本文系统梳理 C# 命名规范的方方面面,从基础的大小写规则到各种前缀后缀约定,帮助你建立一套可落地的命名体系。


一、两大命名约定:PascalCase 与 camelCase

C# 采用两种核心的大小写风格:

约定 规则 示例
PascalCase(帕斯卡) 每个单词首字母大写 StudentService、GetUserById、MaxRetryCount
camelCase(驼峰) 首单词小写,其余首字母大写 userName、pageIndex、isActive

快速判断表

代码元素 大小写 示例
类 class、记录 record、结构体 struct PascalCase CustomerRepository
接口 interface PascalCase + I 前缀 ICustomerRepository
枚举 enum PascalCase OrderStatus
枚举成员 PascalCase OrderStatus.Pending
公共属性 public property PascalCase FirstName
公共字段 public field PascalCase MaxItems
公共方法 public method PascalCase GetCustomerById
私有字段 private field camelCase + _ 前缀 _customerId
私有静态字段 camelCase + s_ 前缀 s_instanceCount
局部变量 camelCase customerName
方法参数 camelCase userId
常量 const PascalCase 或 UPPER_SNAKE MaxFileSize / MAX_FILE_SIZE

二、前缀约定详解

2.1 接口:I 前缀(强制)

csharp 复制代码
// ✅ 正确
public interface IUserRepository { }
public interface IDisposable { }
public interface IEnumerable<T> { }

// ❌ 错误
public interface UserRepositoryInterface { }  // 不要用 Interface 后缀
public interface UserRepository { }           // 缺少 I 前缀

.editorconfig 强制规则:

ini 复制代码
dotnet_naming_rule.interface_rule.severity = error
dotnet_naming_rule.interface_rule.symbols = interface_symbols
dotnet_naming_rule.interface_rule.style = i_prefix_style
dotnet_naming_symbols.interface_symbols.applicable_kinds = interface
dotnet_naming_style.i_prefix_style.required_prefix = I
dotnet_naming_style.i_prefix_style.capitalization = pascal_case

2.2 私有字段:_ 前缀(建议)

csharp 复制代码
public class OrderService
{
    // ✅ 正确
    private readonly IOrderRepository _orderRepository;
    private int _retryCount;
    
    // ❌ 错误
    private IOrderRepository orderRepository;  // 缺少 _
    private int m_retryCount;                  // 不要用匈牙利命名
}

_ 前缀的好处:

  • 一眼区分局部变量和成员变量
  • this._field 可以省略 this.
  • 避免参数名与字段名冲突

2.3 静态字段:s_ 前缀(建议)

csharp 复制代码
public class ConnectionManager
{
    // 静态私有字段
    private static readonly object s_lock = new object();
    private static int s_activeConnections;
    
    // 线程静态字段
    [ThreadStatic]
    private static int t_currentCount;
}

2.4 只读静态字段的命名抉择

csharp 复制代码
// 选项 A:PascalCase(微软官方风格)
public static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30);

// 选项 B:s_ 前缀(私有)
private static readonly HttpClient s_httpClient = new();

// 常量:全大写下划线分隔
public const int MAX_RETRY_COUNT = 3;

建议 :公共字段用 PascalCase,私有字段统一 s_ 前缀。


三、特殊类型命名约定

3.1 抽象类:Base 后缀或 Abstract 前缀

csharp 复制代码
// ✅ 推荐(Base 后缀更自然)
public abstract class RepositoryBase { }
public abstract class CommandBase { }

// ✅ 也可以
public abstract class AbstractRepository { }

// ❌ 不要仅用 "Base" 作为整个类名
public abstract class Base { }

3.2 异常类:Exception 后缀

csharp 复制代码
// ✅ 正确
public class UserNotFoundException : Exception { }
public class ValidationException : Exception { }

// ❌ 错误
public class UserNotFound : Exception { }
public class UserError : Exception { }

3.3 测试类:Tests 后缀

csharp 复制代码
// ✅ 正确
public class OrderServiceTests { }
public class UserControllerIntegrationTests { }

// ❌ 错误
public class TestOrderService { }
public class OrderTest { }

3.4 枚举命名

csharp 复制代码
// ✅ 枚举类型:PascalCase,单数形式
public enum OrderStatus
{
    Pending,         // 成员名:PascalCase
    Processing,
    Shipped,
    Delivered,
    Cancelled
}

// ✅ 位标志枚举:复数形式 + Flags 特性
[Flags]
public enum FilePermissions
{
    None = 0,
    Read = 1,
    Write = 2,
    Execute = 4,
    ReadWrite = Read | Write
}

// ❌ 错误
public enum EOrderStatus { }    // 不要用 E 前缀(C# 不推荐)
public enum OrderStatusEnum { } // 不要用 Enum 后缀

3.5 泛型参数命名

csharp 复制代码
// ✅ 单字母命名(约定俗成)
public interface IRepository<T> where T : class { }
public TResult Map<TSource, TResult>(TSource source);

// ✅ 描述性命名(多参数时)
public interface IRepository<TEntity, TKey> 
    where TEntity : class 
    where TKey : notnull
{ }

四、方法的命名艺术

4.1 动词开头

csharp 复制代码
// ✅ 正确 ------ 动词清晰表达动作
GetUserById(int id)
CreateOrder(OrderRequest request)
UpdateCustomer(CustomerDto dto)
DeleteItem(string itemId)
ValidateInput(string input)
CalculateTotal(IEnumerable<OrderLine> lines)
IsActive() / HasPermission()

// ❌ 错误 ------ 名词开头,歧义
User(int id)        // 构造函数?获取用户?转换?
OrderCreated(...)   // 事件?方法?

4.2 异步方法:Async 后缀

csharp 复制代码
// ✅ 正确
public async Task<User> GetUserByIdAsync(int id) { }
public async ValueTask SaveChangesAsync() { }

// ❌ 错误
public async Task<User> GetUserById(int id) { }  // 缺少 Async

注意 :如果有 async 和同步重载共存:

csharp 复制代码
public User GetUserById(int id) { }         // 同步版本
public Task<User> GetUserByIdAsync(int id) { } // 异步版本

4.3 布尔返回方法

csharp 复制代码
// 模式 1:Is + 形容词/名词
public bool IsValid { get; }
public bool IsActive { get; }
public bool IsAdministrator { get; }

// 模式 2:Has + 名词
public bool HasPermission(string permission) { }
public bool HasItems { get; }

// 模式 3:Can + 动词
public bool CanExecute() { }
public bool CanDelete(int id) { }

// 模式 4:动词(表示判断类操作)
public bool Contains(T item) { }
public bool Exists(int id) { }

五、常见命名反模式

5.1 匈牙利命名法(已过时,禁用)

csharp 复制代码
// ❌ 绝对不要
string strName;
int iCount;
bool bIsActive;
List<string> lstItems;
DateTime dtCreated;

// ✅ 现代 C#
string name;
int count;
bool isActive;
List<string> items;
DateTime createdDate;

5.2 拼音命名(禁止)

csharp 复制代码
// ❌ 绝对不要
string yongHuMing;  // 用户名
int shuLiang;       // 数量

// ✅ 正确
string userName;
int quantity;

5.3 缩写泛滥

csharp 复制代码
// ❌ 不清晰
int cnt;
string addr;
DateTime regDt;

// ✅ 清晰
int count;
string address;
DateTime registrationDate;

例外 :业界公认的缩写可以接受 ------ Id、Url、Http、Xml、Json、Sql、Pk(主键)、Fk(外键)。

5.4 类型信息重复

csharp 复制代码
// ❌ 类型信息已在声明中体现
string nameString;
int countInt;
List<User> userList;

// ✅ 简洁清晰
string name;
int count;
List<User> users;  // 复数表示集合即可

5.5 只有否定意义的变量

csharp 复制代码
// ❌ 双重否定,阅读困难
if (!isNotValid) { }
if (!isDisabled) { }

// ✅ 正向表达
if (isValid) { }
if (isEnabled) { }

六、命名空间与程序集命名

csharp 复制代码
// 格式:Company.Technology.Module
namespace Acme.ECommerce.Ordering.Domain;
namespace Acme.ECommerce.Ordering.Infrastructure;
namespace Acme.ECommerce.Ordering.Application;

// 或者用 Feature 维度
namespace Acme.ECommerce.Features.Orders;
namespace Acme.ECommerce.Features.Products;

七、命名清单速查表

代码元素 大小写 前缀/后缀 示例
类 PascalCase --- UserService
抽象类 PascalCase Base 后缀 RepositoryBase
接口 PascalCase I 前缀 IUserRepository
枚举类型 PascalCase --- OrderStatus
枚举成员 PascalCase --- OrderStatus.Pending
结构体 PascalCase --- Point3D
记录 PascalCase --- UserDto
公共属性 PascalCase --- FirstName
公共方法 PascalCase 动词开头 GetUserById
异步方法 PascalCase Async 后缀 GetUserByIdAsync
私有字段 camelCase _ 前缀 _userName
静态私有字段 camelCase s_ 前缀 s_instance
方法参数 camelCase --- userId
局部变量 camelCase --- userCount
常量 PascalCase 或 UPPER --- MaxRetryCount
异常类 PascalCase Exception 后缀 UserNotFoundException
事件参数 PascalCase EventArgs 后缀 UserCreatedEventArgs
特性类 PascalCase Attribute 后缀 RequiredAttribute
测试类 PascalCase Tests 后缀 UserServiceTests

相关推荐
l1t12 分钟前
修改两处,让SQLite求解数独SQL在datafusion上运行
服务器·数据库·sql
远方160934 分钟前
108-ORA-00600 [kdsgrp1-qetlbr] 内部错误排查与 RMAN 块级恢复
大数据·linux·数据库·oracle
TDTC_XQ1 小时前
模板类的写法
linux·c++
帷幕落秋1 小时前
经典命令场景与软硬链接
linux·运维
派小心.1 小时前
DAU和MAU怎么计算?先确定活跃事件、用户键和统计窗口
大数据·服务器·前端·人工智能·数据分析
CCCCCCCCharlie1 小时前
深入解析I/O底层:文件描述符与缓冲区真相
linux·开发语言·c++·算法
kmomo..2 小时前
Linux 驱动开发学习笔记:UART、触摸屏与 ADC 驱动实战
linux·驱动开发·学习
data analyse 4562 小时前
Session数怎么计算?明确会话切分、超时与跨页规则
java·服务器·数据库
先知后行。2 小时前
各种文件系统
linux·服务器·数据库