引用来源:
1、https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions
2、https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/coding-style.md
项目结构与文件夹命名
一般src,docs这些在vs sln中看不到的文件夹,都是小写
只有具体的vs project才会是Pascal,比如Core和Entrypoint,以及vs project中用来组织代码的文件夹也是Pascal
代码命名
Pascal
类、结构体
public class Person{}
public struct Person{}
接口
需要在Pascal前面加一个I前缀
public interface IEvent{}
public修饰的属性、字段、事件、方法
public class ExampleEvents
{
// A public field, these should be used sparingly
public bool IsValid;
// An init-only property
public IWorkerQueue WorkerQueue { get; private set; }
// An event
public event Action EventProcessing;
// Method
public void StartEventProcessing()
{
// Local function
static int CountQueueItems() => WorkerQueue.Count;
// ...
}
}
不过对于字段,尽量不要使用public,既然public了,就直接使用属性好了。
即如果是对外公开的,一定要用属性的方式
Camel
private修饰的私有字段,需要加前缀_,如果是静态私有,需要加前缀s_
public class DataService
{
private int _count;
private static IWorkerQueue s_workerQueue;
}
函数的形参以及局部变量
public T SomeMethod<T>(int someNumber, bool isValid)
{
string name = null;
}
对于const修饰的字段,不考虑,只看其是public还是private
public class DataService
{
private const int _count;
public const string Name;
}
protected修饰的,如果只希望子类才能使用的,使用camel,如果希望除了子类,其他类也可以用,就和public一样
public class DataService
{
protected int _count;//只有子类可以访问
protected string Name;//所有类都可以访问
}
布局规范
-
每行只写一个语句。
-
每行只写一个声明。
-
如果续行没有自动缩进,则将它们缩进一个制表位(四个空格)。
-
在方法定义和属性定义之间至少添加一个空行。
注释约定
将注释放在单独的行上,而不是在代码行的末尾。
注释文本以大写字母开头。
用句号结束评论文本。
在注释分隔符 (//) 和注释文本之间插入一个空格,如下例所示。
// The following declaration creates a query. It does not run
// the query.
隐式类型的局部变量
当变量的类型从赋值的右侧很明显时,或者当精确类型不重要时,对局部变量使用隐式类型。
var var1 = "This is clearly a string.";
var var2 = 27;
当赋值右侧的类型不明显时,不要使用var 。不要假设类型从方法名称中是明确的。如果变量类型是new运算符或显式强制转换,则该变量类型被认为是明确的。
int var3 = Convert.ToInt32(Console.ReadLine());
int var4 = ExampleClass.ResultSoFar();
var person = new Person();
避免使用this,除非必要,比如是在同名的情况下,为了区分函数中的形参和类内部的成员变量。
static readonly而不是readonly static
如果是private,就应该显式指定
尽可能的使用nameof(type/Property),而不是“”
字段应该在类型声明的顶部指定。
样例
namespace Core
{
// 枚举类型以及枚举值都采用PascalCase
public enum Condition
{
None = 0,
Wall = 1 << 0,
Element = 1 << 1,
All = ~None
}
// 类名采用PascalCase
public class Exporter
{
// 私有字段采用_camelCase,即驼峰加'_'前缀
private int _elementCount;
// readonly,除了在声明的时候赋值,只能在构造函数中进行赋值
private readonly string _fileName;
// 如果是const成员,不管是public还是private,都采用PascalCase
// const,声明的时候就得赋值
private const string Id = "MyTest";
public const string Version = "1.0.0";
// 私有静态字段,使用s_camelCase,即驼峰加's_'前缀
private static Dictionary<string, int> s_listeners;
// public静态字段,和public字段一致
public static Dictionary<string, int> Listeners;
private Action _action;
private IContext _context;
public bool IsValid { get; private set; }
public Exporter(string fileName)
{
_fileName = fileName;
}
// 函数名称PascalCase,参数camelCase
public void SetCount(int elementCount)
{
_elementCount = elementCount;
}
public string GetString()
{
return Id;
}
public void Export()
{
// 一行只能有一句。if大括号中如果只有一句,可以省略大括号,也可以不省略
// 这里想表达的不是csharp语法问题,而是编码规范中不强制要求该情况下的大括号
if (_elementCount == 0)
Console.WriteLine("Error");
if (_context != null)
{
_elementCount = 10;
}
}
public void Delete()
{
// 只有右边是new类型,即一眼就能看出是什么类型的时候,左边才可以使用var
var exporter = new Exporter("test");
// 其他任何情况下,都应该使用显式类型,不应该使用var,即使函数名能表达返回值类型也不行
string id = GetString();
}
}
}