mcpField
C
coding-conventions

coding-conventions

github.com/icartsh开发224 次安装
代码仓库

关于 coding-conventions

coding-conventions 是面向 .NET/C# 开发者与团队的编码规范技能,涵盖命名、布局、语言功能、LINQ 和异常处理,并强调采用较新的 C# 与 .NET 规范。

主要功能

  1. 01较新 C# 与 .NET 功能指南
  2. 02命名与格式规范
  3. 03类型、字符串和集合规则
  4. 04LINQ 与 Lambda 建议
  5. 05异常处理实践

适用场景

  1. 01统一 .NET 项目的代码风格
  2. 02检查代码的命名与布局
  3. 03在新代码中选择现代 C# 语法

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/icartsh/icartsh_plugin --skill coding-conventions

安装后在 Claude Code 中输入/coding-conventions确认已加载。

详细介绍

编码规范

概述

此 SKILL 定义了适用于所有正在开发的 .NET 项目的编码规范。目标是积极运用 .NET 8 及更高版本的最新功能(C# 12/13/14、.NET 8/9/10),编写可读性、可维护性和性能俱佳的代码。

适用范围

此 SKILL 涵盖以下内容:

  • 运用 .NET/C# 最新功能(C# 12/13/14、.NET 8/9/10)的方针
  • 命名规范(Type、Member、Variable、Parameter)
  • 代码布局和格式
  • 语言功能使用方针(Type inference、Collection、Exception handling)
  • LINQ 和 Lambda 表达式的最佳实践
  • 现代 C# 语法的推荐模式

基本方针

  • 积极使用 .NET 8 及更高版本的最新功能(C# 12/13/14、.NET 8/9/10)
  • 除非需要与早期版本兼容,否则始终优先使用最新功能
  • 避免使用旧式语言语法
  • 重要:绝对禁止使用下划线前缀(_field)
  • 重要:绝对禁止省略大括号(即使可以写成一行,也不可省略)
  • 遵循 Microsoft 官方编码规范
  • 保持一致性,并在整个团队中采用统一风格

.NET/C# 最新功能(按版本)

积极使用 .NET 8 及更高版本各版本引入的主要功能。除非需要与早期版本兼容,否则始终优先使用最新功能。

C# 12(.NET 8)— 2023 年 11 月正式发布
主构造函数
  • 可在 class 或 struct 声明中定义参数,并在整个类中使用
  • 减少显式字段声明,简化初始化

良好示例:

public class Person(string name, int age)
{
    public string Name => name;
    public int Age => age;

    public void Display()
    {
        Console.WriteLine($"{name} is {age} years old");
    }
}

不良示例:

public class Person
{
    private string name;
    private int age;

    public Person(string name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public string Name => name;
    public int Age => age;
}
集合表达式
  • 使用方括号和展开运算符简洁地创建集合
  • 合并多个集合时非常有用

良好示例:

int[] array = [1, 2, 3, 4, 5];
List<string> list = ["one", "two", "three"];

int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];

// 스프레드 연산자로 결합
int[] combined = [..row0, ..row1];
Lambda 默认参数
  • 可为 Lambda 表达式指定默认参数值

良好示例:

var incrementBy = (int source, int increment = 1) => source + increment;

Console.WriteLine(incrementBy(5));
Console.WriteLine(incrementBy(5, 3));
为任意类型创建别名
  • 可使用 using 指令为复杂类型创建别名

良好示例:

using Point = (int x, int y);
using ProductList = System.Collections.Generic.List<(string Name, decimal Price)>;

Point origin = (0, 0);
ProductList products = [("Product1", 100m), ("Product2", 200m)];
C# 13(.NET 9)— 2024 年 11 月正式发布
Params 集合
  • params 修饰符现在可用于数组以外的集合类型
  • 可用于 List<T>、Span<T>、ReadOnlySpan<T>、IEnumerable<T> 等

良好示例:

public void ProcessItems(params List<string> items)
{
    foreach (var item in items)
    {
        Console.WriteLine(item);
    }
}

// 메모리 효율이 중요한 경우
public void ProcessData(params ReadOnlySpan<int> data)
{
    foreach (var value in data)
    {
        Process(value);
    }
}
新的 Lock 类型
  • 使用 System.Threading.Lock 类型实现更快的线程同步
  • 比基于 Monitor 的传统锁更快

良好示例:

private readonly Lock lockObject = new();

public void UpdateData()
{
    lock (lockObject)
    {
        // Critical section
    }
}

不良示例:

// 기존 object 기반 락 (C# 13에서는 권장되지 않음)
private readonly object lockObject = new();

public void UpdateData()
{
    lock (lockObject)
    {
        // Critical section
    }
}
Partial 属性和索引器
  • 现在可以使用 partial 属性和索引器
  • 可分离定义和实现

良好示例:

// 정의 부분
public partial class DataModel
{
    public partial string Name { get; set; }
}

// 구현 부분
public partial class DataModel
{
    private string name;

    public partial string Name
    {
        get => name;
        set => name = value ?? throw new ArgumentNullException(nameof(value));
    }
}
隐式索引访问
  • 现在可以在对象初始化器中使用 ^ 运算符

良好示例:

var countdown = new TimerBuffer
{
    buffer =
    {
        [^1] = 0,
        [^2] = 1,
        [^3] = 2
    }
};
Ref Struct 增强功能
  • ref struct 类型现在可以实现接口
  • 现在可以在泛型类型中使用 ref struct(allows ref struct 约束)

良好示例:

public ref struct SpanWrapper<T> : IEnumerable<T>
{
    private Span<T> span;

    public IEnumerator<T> GetEnumerator()
    {
        foreach (var item in span)
        {
            yield return item;
        }
    }
}
C# 14(.NET 10)— 预计于 2025 年 11 月发布
扩展成员
  • 利用扩展成员实现简洁的 API 扩展
  • 无需污染原始类型即可添加功能

良好示例:

extension<TSource>(IEnumerable<TSource> source)
{
    public bool IsEmpty => !source.Any();
    public int Count => source.Count();
}
字段支持的属性
  • 使用 field 关键字减少显式的 backing field
  • 可简洁地编写验证逻辑
  • 绝对禁止使用带下划线前缀的显式 backing field

良好示例:

// C# 14의 field 키워드 사용
public string Name
{
    get;
    set => field = value ?? throw new ArgumentNullException(nameof(value));
}

// 어쩔 수 없이 명시적인 backing field가 필요한 경우에도 언더스코어 없음
private string name;

public string Name
{
    get => name;
    set => name = value ?? throw new ArgumentNullException(nameof(value));
}

不良示例:

// 언더스코어 접두사는 절대 금지
private string _name;

public string Name
{
    get => _name;
    set => _name = value ?? throw new ArgumentNullException(nameof(value));
}
空条件赋值
  • 使用 ?. 简洁地编写 null 检查
  • 减少重复的 null 检查

良好示例:

customer?.Order = GetCurrentOrder();

不良示例:

if (customer != null)
{
    customer.Order = GetCurrentOrder();
}
隐式 Span 转换
  • 在注重性能的代码中使用 Span<T> 和 ReadOnlySpan<T>
  • 利用数组和 Span 类型之间的自动转换

命名规范(Naming Conventions)

Pascal 命名法
  • 类型名称(class、record、struct、interface、enum)
  • 公共成员(属性、方法、事件)
  • 命名空间

良好示例:

public class CustomerOrder
{
    public string OrderId { get; set; }
    public void ProcessOrder() { }
}
Camel 命名法
  • 局部变量
  • 方法参数
  • 私有字段(绝不使用下划线前缀)

良好示例:

public class OrderProcessor
{
    // 언더스코어 없음
    private string customerName;

    // 언더스코어 없음
    private int orderCount;

    public void ProcessOrder(string orderId)
    {
        var customerName = GetCustomerName(orderId);
        string processedResult = Process(customerName);
    }
}

不良示例:

public class OrderProcessor
{
    // 언더스코어 접두사는 절대 금지
    private string _customerName;

    // 언더스코어 접두사는 절대 금지
    private int _orderCount;
}
接口命名
  • 使用前缀 I

良好示例:

public interface IOrderProcessor
{
    void Process(Order order);
}
类型参数命名
  • 使用前缀 T
  • 使用有意义的名称

良好示例:

public class Repository<TEntity> where TEntity : class
{
    public void Add(TEntity entity) { }
}

代码布局(Code Layout)

缩进
  • 使用 4 个空格(Space)
  • 不使用制表符(Tab)
大括号(Curly Braces)
  • 使用 Allman 风格(将左大括号和右大括号分别放在单独一行)
  • 绝对禁止省略大括号(即使可以写成一行,也必须使用大括号)

良好示例:

public void ProcessOrder(Order order)
{
    if (order != null)
    {
        order.Process();
    }
}

// 1행이라도 중괄호를 사용함
if (isValid)
{
    Execute();
}

for (int i = 0; i < 10; i++)
{
    Process(i);
}

不良示例:

// 중괄호 생략 금지
if (isValid)
    Execute();

// 중괄호 생략 금지
for (int i = 0; i < 10; i++)
    Process(i);

// 중괄호 생략 금지
if (order != null) order.Process();
行书写规范
  • 每行只写一条语句
  • 每行只写一个声明
  • 方法定义和属性定义之间空一行

良好示例:

public class Order
{
    public string OrderId { get; set; }

    public void Process()
    {
        var result = Validate();
        Execute(result);
    }

    private bool Validate()
    {
        return OrderId != null;
    }
}
命名空间
  • 使用文件范围的命名空间(File-scoped namespace)

良好示例:

namespace YourProject.Orders;

public class OrderProcessor
{
    // Implementation
}

不良示例:

namespace YourProject.Orders
{
    public class OrderProcessor
    {
        // Implementation
    }
}
using 指令
  • 放在命名空间声明之外
  • 按字母顺序排序

良好示例:

using System;
using System.Collections.Generic;
using System.Linq;

namespace YourProject.Orders;

类型和变量

类型指定
  • 使用语言关键字(string、int、bool)
  • 不使用运行时类型(System.String、System.Int32)

良好示例:

string name = "John";
int count = 10;
bool isValid = true;

不良示例:

String name = "John";
Int32 count = 10;
Boolean isValid = true;
类型推断(var)
  • 仅当类型可从赋值内容中明确判断时使用 var
  • 显式指定内置类型(Built-in type)

良好示例:

// 명백함
var orders = new List<Order>();

// 명백함
var customer = GetCustomer();

// 기본 타입은 명시
int count = 10;

// 기본 타입은 명시
string name = "John";

不良示例:

// 기본 타입에서 var는 피함
var count = 10;

// 기본 타입에서 var는 피함
var name = "John";

字符串

字符串插值(String Interpolation)
  • 短字符串拼接时使用字符串插值

良好示例:

string message = $"Order {orderId} processed successfully";

不良示例:

string message = "Order " + orderId + " processed successfully";
StringBuilder
  • 在循环中追加大量文本时使用 StringBuilder

良好示例:

var builder = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
    builder.Append($"Line {i}\n");
}
原始字符串字面量(Raw String Literals)
  • 优先使用原始字符串字面量,而不是转义序列

良好示例:

string json = """
{
    "name": "John",
    "age": 30
}
""";

集合和对象初始化

集合初始化
  • 使用 C# 12 及更高版本的集合表达式(参见前文“C# 12 最新功能”)
对象初始化器(Object Initializer)
  • 使用对象初始化器简化创建过程

良好示例:

var customer = new Customer
{
    Name = "John",
    Email = "[email protected]"
};

异常处理(Exception Handling)

捕获具体异常
  • 捕获具体异常,而不是通用的 System.Exception

良好示例:

try
{
    ProcessOrder(order);
}
catch (ArgumentNullException ex)
{
    Logger.Error("Order is null", ex);
}

不良示例:

try
{
    ProcessOrder(order);
}
catch (Exception ex) // 너무 일반적임
{
    Logger.Error("Error", ex);
}
using 语句
  • 使用 using 语句,而不是 try-finally

良好示例:

using var connection = new SqlConnection(connectionString);
connection.Open();
// Process

不良示例:

SqlConnection connection = null;
try
{
    connection = new SqlConnection(connectionString);
    connection.Open();
    // Process
}
finally
{
    connection?.Dispose();
}

LINQ

有意义的变量名
  • 为查询变量使用有意义的名称

良好示例:

var activeCustomers = from customer in customers
                      where customer.IsActive
                      select customer;
提前筛选
  • 使用 where 子句提前筛选数据

良好示例:

var result = customers
    .Where(c => c.IsActive)
    .Select(c => c.Name)
    .ToList();
隐式类型指定
  • 在 LINQ 声明中使用隐式类型指定

良好示例:

var query = from customer in customers
            where customer.IsActive
            select customer;

Lambda 表达式(Lambda Expressions)

事件处理程序
  • 对于无需删除的处理程序,使用 Lambda 表达式

良好示例:

button.Click += (s, e) => ProcessClick();
参数修饰符
  • 利用 C# 14 功能,在保留类型推断的同时使用修饰符

良好示例:

TryParse<int> parse = (text, out result) => int.TryParse(text, out result);

注释(Comments)

单行注释
  • 对于简洁的说明,使用 //
  • 在注释分隔符后添加一个空格
  • 注释必须单独成行(禁止与代码写在同一行)
  • 在注释前添加一个空行

良好示例:

// 고객 주문을 처리함
ProcessOrder(order);

var processor = new OrderProcessor();

// 주문을 실행함
var result = processor.ProcessOrder(order);

不良示例:

ProcessOrder(order); // 고객 주문을 처리함 (코드와 같은 행은 금지)

var processor = new OrderProcessor();
// 이 행의 앞에 빈 행이 없음 (나쁜 예)
var result = processor.ProcessOrder(order);
XML 文档
  • 为公共成员编写 XML 文档

良好示例:

/// <summary>
/// 지정된 주문을 처리함
/// </summary>
/// <param name="order">처리할 주문</param>
/// <returns>처리 결과</returns>
public bool ProcessOrder(Order order)
{
    // Implementation
}

静态成员(Static Members)

通过类名调用
  • 通过类名调用静态成员

良好示例:

var result = OrderProcessor.ProcessOrder(order);

不良示例:

var processor = new OrderProcessor();

// 정적 메서드를 인스턴스를 통해 호출하는 것은 오해의 소지가 있음
var result = processor.ProcessOrder(order);

检查清单(Checklist)

编写代码前
  • 了解 .NET/C# 的最新功能(C# 12/13/14)
  • 项目的目标框架设置为 .NET 8 或更高版本
  • 了解命名规则
编写代码时

必需规则:

  • 绝不使用下划线前缀
  • 不省略大括号(即使只有 1 行也必须使用)
  • 注释必须单独成行(不得与代码写在同一行)
  • 在注释前添加一个空行

C# 12 及更高版本的功能:

  • 使用 Primary Constructors(适用时)
  • 使用 Collection Expressions
  • 利用 Default Lambda Parameters(适用时)
  • 使用 Alias Any Type 为复杂类型创建别名(适用时)

C# 13 及更高版本的功能:

  • 使用 Params Collections(适用时)
  • 使用 New Lock Type(需要线程同步时)
  • 利用 Partial Properties and Indexers(适用时)
  • 在对象初始化器中使用 Implicit Index Access(适用时)

C# 14 及更高版本的功能:

  • 使用 field 关键字简洁地编写 backing field
  • 利用 Extension Members(适用时)
  • 利用 Null-Conditional Assignment
  • 使用 Lambda Parameters with Modifiers(适用时)

基本规则:

  • 使用文件范围命名空间
  • 使用语言关键字(string、int)
  • 适当使用 var(仅在类型明确时)
  • 使用字符串插值
  • 使用 Raw String Literals(适用时)
  • 使用 Object Initializers
  • 使用 using 语句
  • 捕获具体异常
  • 在 LINQ 表达式中提前筛选
  • 使用有意义的变量名
  • 注释简洁明了
  • 为公共成员编写 XML 文档
  • 使用 Allman 风格放置大括号
  • 使用 4 个空格缩进
编写代码后
  • 代码风格保持一致
  • 利用 .NET 8 及更高版本的最新功能(C# 12/13/14)
  • 遵循命名规则
  • 代码易于阅读和维护

评论

支持 Markdown