format-style

star 3.0k

工程代码格式化风格指引

Pixeval By Pixeval schedule Updated 6/12/2026

name: format-style description: 工程代码格式化风格指引

Pixeval 格式化风格

若有未详尽覆盖的情况,可参考任意 src 下的代码,但不包括 src/lib 里的第三方或子模块代码

基本要求

  • 保留现有文件头。除非所在目录本身就有同类头部,否则不要给原本没有头部的文件新增头部。
  • 视图/控件的 .axaml.axaml.cs 文件要成对维护。
  • 默认按现代 C# 假设:主项目目标框架是 net10.0,启用了 nullable,LangVersionlatest,并且默认启用编译绑定。

C# 偏好

  • 基础代码风格遵循 .editorconfig 中的设置。
  • 使用 UTF-8、CRLF、末尾换行、4 空格缩进,不使用 tab。
  • using 指令不要用空行拆分导入组。
  • 使用 file-scoped namespace。
  • 尽量使用 var,包括内置类型和一眼可见的类型。
  • 使用 nullable,并在所有地方保证空安全,不要留下 null 警告。对于临时为 null 的瞬态,可以用 null!
  • 优先使用模式匹配:
    • 对常量优先使用 is 模式匹配而不是 ==!=count is 0count is not 0value is nullvalue is not nullvalue is not A and not B
    • obj is { } value 绑定非空值。
    • 使用属性/列表模式,例如 entry is { Width: > 0, Height: > 0 }
    • 对形状不匹配的情况,用 is not { ... } 做守卫。
  • 分支语句优先级: switch 表达式 > switch 语句 > if/else if 链,尤其适合枚举、类 union 的状态、命令和类型分发。
  • 当成员能在一行内清楚表达时,优先使用表达式主体:属性、访问器、简单方法、局部函数、转换器和运算符都适用。
  • 优先使用对象/集合初始化器、集合表达式([][.. items])、空条件运算、??throw 表达式、范围/索引运算符、元组命名,以及清晰时的匿名成员推断。
  • if-else 中若主体是一行以内,则可以省略大括号;若分支中有跳转语句(如returnbreakcontinue 等)则优先写在 if 中,并且省略 else 来减少嵌套层级。
  • 强制转换后面保留一个空格:(Type) value
  • 二元运算符两侧保持空格,换行时把运算符放在下一行开头。
  • 简单场景优先使用 using varawait using var,不要嵌套多层 using 块。
  • using varawait using var 若有初始化列表则拆开,避免初始化时发生异常导致资源未正确释放。例如:using var a = new A { X = 1 }; 应该改为 using var a = new A(); a.X = 1;
  • 当有意忽略一个非 void 返回值时,使用弃元(_ = ...;),表达式主体的方法除外。
  • 对“理论上穷尽”的 switch,使用 ArgumentOutOfRangeException(nameof(value)) 或等价的默认分支。
  • 如果所有构造函数都调用某一个构造函数,或只有一个构造函数,优先把这个构造函数改为主构造函数。
  • 对于返回 TaskTask<T> 的方法,若只有返回时用到 Task,则不需要将方法声明为异步(async)方法,而是直接返回 Task,但方法名仍然需要 Async 后缀。
  • 在非 UI 层的异步方法中,最后一个参数使用 CancellationToken token = default,并在其中所有 awaitTask 使用 ConfigureAwait(false) 避免切换线程上下文。但在 UI 代码中,不要这样做以避免死锁。
  • 对于变量名引用,使用 nameof(...) 而不是字符串字面量,包括字符串内插中。
  • 对可复用的查找/转换状态,使用 Lazy<T>FrozenDictionary、生成正则,或者静态只读转换器实例,不要每次调用都重建数据。
  • IDisposable,若需要则调用 GC.SuppressFinalize(this)
  • 如果可以,则将字段/属性/结构体/方法/局部方法设为 static/readonly/const/getonly/initonly 等以增强约束。
  • 不要使用旧的扩展方法,而使用 C# 14 中新的 extension blocks,并将同一类型的扩展聚在一起。
  • 尽量使用 stackallocSpan<T>Memory<T> 等来增强性能。
  • 抛出异常时提供要意义的消息、参数名称。
  • 编写 XML 注释时:
    • 对于继承自接口或基类的成员,优先使用 <inheritdoc /> 来继承文档。
    • 对于调用其他方法所以文档可以直接复用的成员,优先使用 <inheritdoc cref="..." /> 来复用文档。
    • 对于引用的类型、成员,使用 <see cref="..." />,并且不要使用全限定名,而是也用 using 引入。
    • 对于成员引用或泛型参数引用,<paramref name="..." /><typeparamref name="..." /> 来提供链接。
    • 对于其中的关键字,使用 <see langword="..." /> 来增强高亮。
  • 对于大段多换行的字符串,使用生字符串(""")来增强可读性,而且前引号之前必须换行。
  • 接口中的泛型若可以用协变/逆变,则使用。
  • 对于返回值,若无必要(如迭代器方法则除外),则优先使用 IReadOnlyCollection<T> 或更严格的 IReadOnlyList<T> 而不是 IEnumerable<T>,以表达集合内元素有限。
  • 优先使用 IReadOnlyList<T>ReadOnlySpan<T> 而不是 T[] 来表示数组,以避免潜在的数组协变。
  • 若一个类内容太多,可以拆成形如 .Commands.cs 的 partial 文件。
  • 对于每个类都较长的多个类,或者关系不大的多个类(例如某个类不是只在另一个类中使用),则拆分成每个类一个文件而不是放在同一个文件里。
  • 使用 Linq 时,优先使用方法链式调用而不是查询表达式。
  • 命名时:
    • 对非抛出式尝试使用 Try* 命名(例如 TryResetTryDelete)。
    • 类型、属性、事件、方法、可见字段和常量使用 PascalCase。
    • 接口以 I 开头。
    • 私有实例字段使用 _camelCase;私有静态字段和 static readonly 字段使用 _PascalCase

Avalonia XAML

  • 基础代码风格遵循 Settings.XamlStyler 中的设置。

  • 尽量使用有类型信息的 XAML:

    • x:DataType="{x:Type vm:SomeViewModel}"
    • TargetType="{x:Type Button}"
    • x:Key="{x:Type controls:SomeControl}"
    • BasedOn="{StaticResource {x:Type ListBox}}"
  • 对于 XAML 内的命名空间引用,使用 xmlns:prefix="using:..." 而不是 xmlns:prefix="clr-namespace:...;assembly=..."。对于根元素类所在的命名空间,使用 local 作为命名空间 xmlns:local="using:..."

  • 空元素使用自闭合标签。

  • 稳定的样式/模板优先用 StaticResource,和主题相关的画刷/颜色优先用 DynamicResource

  • 优先使用编译/有类型绑定配合 x:DataType

  • 对控件主题/模板,使用 ControlThemeControlTemplate、诸如 PART_ContentPresenter 的命名部件,以及 TemplateBinding 处理模板属性。

  • 优先使用标记扩展以减少代码行数,例如使用 {markup:SymbolIcon ...} 而不是 <fluent:SymbolIcon Symbol="..." />

  • 文本布局优先使用 TextTrimmingMaxLinesTextWrapping 和资源文本主题,而不是自己写测量逻辑。

  • 标准可绑定控件状态使用 Avalonia StyledProperty,非样式属性或用户控件中定义的需要绑定的属性使用 DirectPropertySetAndRaise

  • 绑定风格:

    • 优先使用 Avalonia 语法,如 $parent[...]#Name等。
    • 优先使用 Avalonia 语法而不是转换器,例如 IsVisible="{Binding !!Items.Count}"{Binding !IsFollowed}

简单示例

<ControlTheme x:Key="{x:Type controls:AvatarImage}" TargetType="{x:Type controls:AvatarImage}">
    <Setter Property="Template">
        <ControlTemplate TargetType="{x:Type controls:AvatarImage}">
            <Image Source="{TemplateBinding Source}" />
        </ControlTemplate>
    </Setter>
</ControlTheme>
Install via CLI
npx skills add https://github.com/Pixeval/Pixeval --skill format-style
Repository Details
star Stars 3,019
call_split Forks 204
navigation Branch main
article Path SKILL.md
More from Creator