C# 风格指南
对于每个项目而言, 拥有定义良好且一致的编码约定非常重要,Godot也不例外. 本页面包含一份编码风格指南,Godot 本身的开发人员和贡献者都遵循该指南。因此,它的目标读者是希望为该项目做出贡献的人员,但是由于本文中提到的约定和准则被该语言用户最广泛采用,所以我们建议你也这样做,尤其是如果你还没有这样的指南。 注解 C #编码约定 或 框架设计指南.
语言规范
C# 7.0 版本 . 因此, 在我们迁移使用较新版本之前, 必须注意避免混合仅在 C# 7.1 或更高版本中可用的语言功能. C #中的新功能 .
格式
一般性指导
- LF )来换行, 而不是
CRLF或CR. - 在每个文件末尾使用一个换行符, 但 csproj 文件除外.
- 字节顺序标记(BOM) 的 UTF-8 编码.
- 4空格 代替制表符进行缩进(称为 “软制表符”).
- 如果长度超过100个字符, 请考虑将其分成几行.
换行符和空白行
Allman 风格, 它建议将与控制语句关联的大括号放在下一行, 缩进到同一级别:
但是, 您可以选择省略括号内的换行符:// Use this style:if (x > 0){ DoSomething();}// NOT this:if (x > 0) { DoSomething();}
- 对于简单的属性访问者.
- 对于简单对象, 数组, 或集合初始化.
- 对于抽象的自动属性, 索引器, 或事件声明.
插入一个空行:// You may put the brackets in a single line in following cases:public interface MyInterface{ int MyProperty { get; set; }}public class MyClass : ParentClass{ public int Value { get { return 0; } set { ArrayValue = new [] {value}; } }}
using语句之后.- 在方法, 属性, 和内部类型声明之间.
- 在每个文件的末尾. 字段声明和常量声明可以根据相关性编组在一起. 在这种情况下, 请考虑在编组之间插入空白行以便于阅读. 避免插入空白行:
{之后.}之前.- 在注释块或单行注释之后.
- 与另一个空白行相邻.
using System;using Godot; // Blank line after `using` list.public class MyClass{ // No blank line after `{`. public enum MyEnum { Value, AnotherValue // No blank line before `}`. } // Blank line around inner types. public const int SomeConstant = 1; public const int AnotherConstant = 2; private Vector3 _x; // Related constants or fields can be private Vector3 _y; // grouped together. private float _width; private float _height; public int MyProperty { get; set; } // Blank line around properties. public void MyMethod() { // Some comment. AnotherMethod(); // No blank line after a comment. } // Blank line around methods. public void AnotherMethod() { }}
使用空格
插入空格: - 围绕二元和三元运算符.
if,for,foreach,catch,while,lock或using关键字之间.- 在单行访问器块之前和之内.
- 在单行访问器块中的访问器之间.
- 在不是在行尾的逗号之后.
for语句中的分号之后.case语句中的冒号之后.- 在类型声明中的冒号周围.
- 围绕一个lambda箭头.
//)之后, 并且如果在行末使用, 则在它之前. 不要使用空格:- 在类型转换括号后.
- 在单行初始化括号内侧.
下面的示例根据上述的一些约定显示了对空格的正确使用:
public class MyClass<A, B> : Parent<A, B>{ public float MyProperty { get; set; } public float AnotherProperty { get { return MyProperty; } } public void MyMethod() { int[] values = {1, 2, 3, 4}; // No space within initializer brackets. int sum = 0; // Single line comment. for (int i = 0; i < values.Length; i++) { switch (i) { case 3: return; default: sum += i > 2 ? 0 : 1; break; } } i += (int)MyProperty; // No space after a type cast. }}
命名约定
PascalCase , 私有字段除外:
camelCase 用于所有其他标识符(即局部变量, 方法参数), 并使用下划线(namespace ExampleProject{ public class PlayerCharacter { public const float DefaultSpeed = 10f; public float CurrentSpeed { get; set; } protected int HitPoints; private void CalculateWeaponDamage() { } }}
_)作为私有字段的前缀(但不能用于方法或属性, 如上所述):private Vector3 _aimingAt; // Use a `_` prefix for private fields.private void Attack(float attackStrength){ Enemy targetFound = FindTarget(_aimingAt); targetFound?.Hit(attackStrength);}
UI, 应当使用PascalCase的大写字母, 否则使用小写字母.id不是 首字母缩略词, 因此应将其视为普通标识符:public string Id { get; }public UIManager UI{ get { return uiManager; }}
string strText或float fPower. 但是, 对于接口来说是个例外, 实际上, 接口 应该 在其名称前加上大写字母I, 例如IInventoryHolder或IDamageable. 最后, 考虑选择描述性名称, 如果它影响可读性, 请不要尝试过多地缩短描述性名称. 例如, 如果您想编写代码来查找附近的敌人并用武器击中它, 请选择:
而不是:FindNearbyEnemy()?.Damage(weaponDamage);
FindNode()?.Change(wpnDmg);
成员变量
如果变量只在方法中使用, 勿声明其为成员变量, 因为我们难以定位在何处使用了该变量. 相反, 你应该将它们在方法内部定义为局部变量.局部变量
声明局部变量的位置离首次使用它的位置越近越好. 这让人更容易跟上代码的思路, 而不需要上下翻找该变量的声明位置.隐式类型的局部变量
var)声明局部变量, 但是 仅当类型明显时 即可从右侧的赋值推断类型:// You can use `var` for these cases:var direction = new Vector2(1, 0);var value = (int)speed;var text = "Some value";for (var i = 0; i < 10; i++){}// But not for these:var value = GetValue();var velocity = direction * 1.5;// It's generally a better idea to use explicit typing for numeric values, especially with// the existence of the `real_t` alias in Godot, which can either be double or float// depending on the build configuration.var value = 1.5;
其他注意事项
- 使用显式访问修饰符.
- 使用属性而代替非私有字段.
public/protected/private/internal/virtual/override/abstract/new/static/readonly.this.前缀.using语句和不必要的括号.- 考虑省略类型的默认初始值.
- 考虑使用空条件运算符或类型初始化器来使代码更紧凑.
- 当值可能会成为另一种不同的类型, 请使用安全类型转换, 否则使用直接类型转换.
