# DotNetProgrammingDevelopmentSpecification **Repository Path**: tanxin1/dot-net-programming-development-specification ## Basic Information - **Project Name**: DotNetProgrammingDevelopmentSpecification - **Description**: 为了降低协同成本,提升沟通效率,适当的规范和标准代码的编写,以一种普遍认可的统一方式一起做事,提升协作效率。质量的提升是尽可能少踩坑,杜绝踩重复的坑,切实提升质量意识。 - **Primary Language**: C# - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2022-07-02 - **Last Updated**: 2022-07-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # DotNetProgrammingDevelopmentSpecification .NET 编程开发规范 # 代码规范(v1.0) ## 编写目的 为了降低协同成本,提升沟通效率,适当的规范和标准代码的编写,以一种普遍认可的统一方式一起做事,提升协作效率。质量的提升是尽可能少踩坑,杜绝踩重复的坑,切实提升质量意识。 ## 命名规范 1. 变量和参数使用【Camel】命名规范,即第一个单词首字母小写,其余单词首字母大写(其他都必须使用【Pascal】命名规范,即每个单词首字母必须大写),并尽量使用能描述变量作用的英文单词。 > 例如存放学生姓名的变量可以定义成`name`或者`studentName`。另外,变量名字也不建议过长,最好是 1个单词,最多不超过3个单词。**(避免无意义的命名如:`aaa`,`b`,`xxx`)** 2. 变量命名以英文为准,严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。 > 如商品订单命名为`goodsOrders`或者`orders`**(建议使用`goodsOrders`而不是`orders`,命名尽量力求语义表达完整清楚)** 而不是`SPDD`。 3. 属性命名也遵循变量命名规则,但以大写字母开头。私有属性以下划线开头,首字母小写。 > 如 `_studentRepository`,`_context` 4. 特别说明:一些布尔类型的变量可以用`is`开头,后面跟上名词或动词。 > 例如是否存在可以命名为`isExists`,是否已经检查过命名为`isChecked` 5. 获取多条数据需在名词后加上`s`,或者`List`。 > 如`var users = GetUserList()` 或者`var userList = GetUserList()` 6. 建议:对实体增删改查的时候可以命名为`entity`,`entities`,`updatedEntity`,`deletedEntity`。 例如: ``` var entity = await GetUserByIdAsync(id); entity.UserName = "张三"; var updatedEntity = await _userRepository.UpdateAsync(entity); return updatedEntity; ``` 7. 接口以大写I开头,实现类的命名也需要依据接口名称。 > 如: `UserReposiory : IRepository`,`ProductAppService : IAppService`,`DeviceManagement : IDeviceManagement` 8. 枚举声明使用英文名词复数形式,枚举项采用【Pascal】命名规范,并且设置每一个项的值。枚举项的要有一个未知的项,并且值用 0 来表示。可以使用 None或 Unknow 来作为第一项的枚举选项。 ``` public enum SqlOption { Unknow = 0, SqlServer = 1, MySql = 2 } ``` ### 补充: 9. 变量声明使用关键字 var 来替代强制声明的数据类型,并务必对变量进行初始化。 > 例如 `var users = GetUserList()` ## 方法命名规则 1. 对方法名采用一致的动词/宾语顺序。例如,插入数据:`InsertStudents` 和 `InsertRecords`。 2. 推荐名称应该为动词或动词短语。例如`Save`,`SaveCustomer`,而不要使用`CustomerSave`。 3. 异步方法以`Async`结尾,用以与同步方法区分开。例如:`InsertStudentAsync`,`InsertStudent`。 ### 补充: 4. 服务端api方法遵循RESTful风格。 ``` GET(SELECT):从服务器取出资源(一项或多项) POST(CREATE):在服务器新建一个资源 PUT(UPDATE):在服务器更新资源(客户端提供完整资源数据) PATCH(UPDATE):在服务器更新资源(客户端提供需要修改的资源数据) DELETE(DELETE):从服务器删除资源 ``` 例如需要获取学生信息的方法可以命名为`GetStudentInfoAsync`或者`GetStudentInfo`,方法为`GET`,路由映射为`StudentInfo`(路由不需要加上`Get`)。获取全部的学生信息命名为`GetAllAsync`,路由映射为`All`。删除、新增、修改命名为`AddStudentAsync`、`DeleteStudentAsync`、`UpdateStudentAsync`,方法为`POST`、`DELETE`、`PUT` ## 编码规则建议 1. 大括号使用。如果大括号内容为空,则写成{}即可;若大括号内容不为空,则:左大括号前换行左大括号后换行右括号前换行右大括号后必须换行。 ``` if(true) { } ``` 2. if使用规范 > 1. 如果if主体是直接返回,则不需要写大括号,并且直接跟在if条件之后 ``` if(isChecked) return; ``` > 2. 多使用三目运算符代替if语句 使用: ``` return isChecked ? await GetCurrentUserAsync() : await GetUserByIdAsync(id); ``` 而不是: ``` if(isChecked) { return await GetCurrentUserAsync(); } else { return await GetUserByIdAsync(id); } ``` > 3. 尽量减少if嵌套层数。如的确需要嵌套多层if,考虑封装这部分代码。 使用: ``` var byteData = new [] byte {}; if(byteData.Length != 10 || byteData[0] != 0xff || byteData[9] != 0xff || byteData[1] != 0xff) return null; // do something ``` 而不是: ``` var byteData = new [] byte {}; if(byteData.Length == 10) { if(byteData[0] == 0xff) { if(byteData[9] == 0xff) { if(byteData[1] == 0xff) { // do something } } } } ``` > 4. 一行代码处理多个任务时,需要换行。调用多个参数的方法时指定参数名称并换行。 ``` var sb = new StringBuilder(); sb.Append("xxx1") .Append("xxx2") .Append("xxx3") .Append("xxx4") ... // 参数超过了5个,每个参数换行对齐 public void Add(object arg1, object arg2, object arg3, object arg4, object arg5, object arg6 ) { // to do } // 调用此方法时: entity.Add(arg1:arg1, arg2:arg2, arg3:arg3, arg4:arg4, arg5:arg5, arg6:arg6); ``` > 5. 集合处理:查询使用linq 或者lambda表达式,尽量避免使用循环。 ## 代码格式 1. 以上都是胡编乱造的,大可不必这么弄