Files
ui/docs/architecture/coding-standards.md
2025-10-16 15:48:30 +08:00

105 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` |
| 测试方法 | PascalCaseMethodName_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
```
---