105 lines
4.7 KiB
Markdown
105 lines
4.7 KiB
Markdown
# Coding Standards
|
||
|
||
本节定义**最小但关键**的编码规范,专注于项目特定的规则,防止常见错误。这些规范将被开发者和 AI Agent 遵循。
|
||
|
||
---
|
||
|
||
### Critical Rules
|
||
|
||
以下规则是**强制性**的,违反将导致代码审查不通过:
|
||
|
||
- **命名空间组织:** 所有控件必须放在 `Penguin.AvaloniaUI.Controls.*` 命名空间下,布局控件在 `Penguin.AvaloniaUI.Layouts`,主题在 `Penguin.AvaloniaUI.Themes`。不得跨命名空间引用内部实现细节。
|
||
- **依赖属性定义:** 所有公开的可绑定属性必须定义为 `StyledProperty`,使用 `AvaloniaProperty.Register<>` 注册,不得使用字段或普通属性。
|
||
- **XAML 资源引用:** 所有颜色、字体、间距必须从主题资源字典引用,禁止硬编码颜色值(如 `#FFFFFF`)。使用 `{DynamicResource TextPrimary}` 而非 `{StaticResource}`,确保主题切换生效。
|
||
- **ReactiveUI 集成:** ViewModel 必须继承 `ReactiveObject`,属性变化使用 `this.RaiseAndSetIfChanged(ref _field, value)`,不得直接触发 `PropertyChanged` 事件。
|
||
- **错误处理:** 公开 API 方法必须验证参数(如 `ArgumentNullException`),内部方法可使用 `Debug.Assert`。不得吞没异常(空 catch 块)。
|
||
- **XML 文档注释:** 所有 `public` 和 `protected` 成员必须有 XML 注释(`///`),包括 `<summary>`、`<param>`、`<returns>`。示例:
|
||
|
||
```csharp
|
||
/// <summary>
|
||
/// 应用指定的主题类型
|
||
/// </summary>
|
||
/// <param name="type">主题类型(Light 或 Dark)</param>
|
||
public static void ApplyTheme(ThemeType type)
|
||
```
|
||
- **禁止反射动态创建控件:** PropertyGrid 可以使用反射解析属性,但不得使用 `Activator.CreateInstance` 动态创建编辑器控件。使用工厂模式或字典映射。
|
||
- **主题资源命名约定:** 语义化颜色必须使用统一前缀:`TextPrimary`、`TextSecondary`、`BackgroundPrimary`、`SurfaceElevated`。不得使用 `Color1`、`MyBlue` 等非语义化命名。
|
||
- **API查询规则:** 在使用不熟悉的API的时候,优先使用 **mcp-context7** 进行上下文查找。
|
||
|
||
---
|
||
|
||
### Naming Conventions
|
||
|
||
| 元素类型 | 命名规则 | 示例 |
|
||
| --------- | ---------------------------------------------- | ---------------------------------------------------- |
|
||
| 控件类 | PascalCase,功能名称 + 控件类型后缀(可选) | `PropertyGrid`, `TwoColumnLayout` |
|
||
| 依赖属性 | PascalCase,属性名 +`Property` 后缀 | `SelectedObjectProperty` |
|
||
| 私有字段 | camelCase,下划线前缀 | `_currentTheme` |
|
||
| 事件 | PascalCase,动词过去式 | `ThemeChanged`, `PropertyValueChanged` |
|
||
| 方法 | PascalCase,动词开头 | `ApplyTheme()`, `RefreshProperties()` |
|
||
| XAML 文件 | PascalCase,与类名一致 | `PropertyGrid.axaml` |
|
||
| 测试方法 | PascalCase,MethodName_Scenario_ExpectedResult | `ApplyTheme_WithDarkTheme_ShouldUpdateResources()` |
|
||
|
||
---
|
||
|
||
### File Organization Rules
|
||
|
||
- **一个文件一个类**:每个控件类单独一个 `.cs` 文件,不得在同一文件中定义多个公开类(嵌套私有类除外)。
|
||
- **XAML 与代码分离**:控件的 XAML 模板放在 `Themes/` 子目录下,与类定义分离:
|
||
|
||
```
|
||
Controls/PropertyGrid/PropertyGrid.cs
|
||
Controls/PropertyGrid/Themes/PropertyGrid.axaml
|
||
```
|
||
- **数据模型独立文件**:数据模型类(如 `PropertyItem`, `GuideStep`)与控件类分离,放在同级目录下。
|
||
- **文件格式规范**:命名空间单独放在文件顶部,减少缩进层级:
|
||
|
||
```csharp
|
||
namespace Penguin.AvaloniaUI.Controls;
|
||
|
||
public class PropertyGrid : TemplatedControl
|
||
{
|
||
// 类实现
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### Code Style (基于 .editorconfig)
|
||
|
||
项目使用 `.editorconfig` 强制执行以下规则:
|
||
|
||
```ini
|
||
root = true
|
||
|
||
[*.cs]
|
||
indent_style = space
|
||
indent_size = 4
|
||
end_of_line = crlf
|
||
charset = utf-8
|
||
trim_trailing_whitespace = true
|
||
insert_final_newline = true
|
||
|
||
# C# 规则
|
||
csharp_new_line_before_open_brace = all
|
||
csharp_prefer_braces = true:warning
|
||
csharp_style_var_for_built_in_types = true:suggestion
|
||
csharp_style_var_when_type_is_apparent = true:suggestion
|
||
|
||
[*.axaml]
|
||
indent_size = 2
|
||
```
|
||
|
||
**代码风格要点:**
|
||
|
||
- 使用 `var` 声明局部变量(如 `var count = 100;`)
|
||
- 命名空间单独一行,不使用文件范围命名空间的花括号嵌套
|
||
|
||
**运行格式化检查:**
|
||
|
||
```bash
|
||
dotnet format --verify-no-changes
|
||
```
|
||
|
||
---
|