整洁代码1
代码命名规范
1.用Pascal规则来命名方法和类型。
/// <summary> /// 数据表格 /// </summary> public class DataGrid { /// <summary> /// 数据绑定 /// </summary> public void DataBind() { } }
2.用Camel规则来命名局部变量和方法的参数。
/// <summary> /// 产品 /// </summary> public class Product { /// <summary> /// 产品Id /// </summary> private string _productId; /// <summary> /// 产品名称 /// </summary> private string _productName; /// <summary> /// 添加产品 /// </summary> /// <param name="productId">产品Id</param> /// <param name="productName">产品名称</param> public void AddProduct(string productId, string productName) { } }
3.所有的成员变量前加前缀“_” 或者 “m_”。
/// <summary> /// 数据基础处理 /// </summary> public class DataBase { /// <summary> /// 链接字符串 /// </summary> private string _connectionString; /// <summary> /// 数据集 /// </summary> private string m_dataSet; }
4.接口的名称加前缀 “I”。
/// <summary> /// 转化接口 /// </summary> public interface IConvertible { /// <summary> /// 转化成byte类型 /// </summary> /// <returns>结果</returns> byte ToByte(); }
5.自定义的属性以“Attribute”结尾。
/// <summary> /// Table属性 /// </summary> public class TableAttribute : Attribute { }
6.自定义的异常以Exception结尾。
/// <summary> /// 空异常 /// </summary> public class NullEmptyException : Exception { }
7.方法的命名。一般将其命名为动宾短语。
/// <summary> /// 文件 /// </summary> public class File { /// <summary> /// 创建文件 /// </summary> /// <param name="filePath">文件路径</param> public void CreateFile(string filePath) { } }
8.局部变量的名称要有意义。
不要用x,y,z等等,用For循环变量中可使用i, j, k, l, m, n。
/// <summary> /// 用户 /// </summary> public class User { /// <summary> /// 获取用户 /// </summary> public void GetUser() { string[] userIds = { "ziv ", "zorywa ", "zlh " }; for (int i = 0, k = userIds.Length; i < k; i++) { } } }
9.所有的成员变量声明在类的顶端,用一个换行把它分开。
/// <summary> /// 产品 /// </summary> public class Product { /// <summary> /// 产品Id /// </summary> private string _productId; /// <summary> /// 产品名称 /// </summary> private string _productName; /// <summary> /// 添加产品 /// </summary> /// <param name="productId">产品Id</param> /// <param name="productName">产品名称</param> public void AddProduct(string productId, string productName) { } }
10.用有意义的名字命名namespace,如:公司名、产品名。
11.建议局部变量在最接近使用它时再声明。
12.命名规范。
(1)控件命名规范:
(2)类名、方法名、属性名、命名空间、解决方案、文件名,采用每个单词首字母大写的形式。Pascal规则
(3)变量,采用首字母小写,其他单词首字母大写的形式。Camel规则
(4)命名必须采用英文单词命名,并且有实际意义,禁止使用无意义的命名,比如a,b,a1,b1等。
(5)接口、抽象类,统一采用I+接口名(类名)的方式命名。
(6)数据访问层,统一采用D+类名的方式命名。或者类名+Repository
(7)模型类或结构,统一采用M+类名的方式命名或者 类名+行为 如果 类名+Result(表示某某结果)
(8)WCF服务层,统一采用S+类名的方式命名。
(9)枚举,统一采用E+枚举名的方式命名。(不推荐)
(10) 委托,统一带上Handler后缀。
(11)事件,不使用任何的前缀和后缀,只有事件的方法采用On或者Before等前缀。
(12)常量,采用全部单词字母大写,每个单词以"_"分割的方式命名。
(13)禁止使用看不懂的缩写。禁止使用看不懂的英语 禁止使用拼音 禁止使用中国式英语(这个很难做到)
(14)缩写只有2个字符的,全部采用大写,如ID,而不是Id,大于2个长度的,仅保留第一个字母大写。
(15)bool变量或属性,必须包含Is或者Has等能够表明是一个bool值的单词。
(16)类中的属性或变量名,不能包含类名,比如Book.BookName,应为Book.Name。
(17)命名空间采用四段式,前三段分别表示公司.产品.解决方案,第四段表示项目名。
13.把引用的系统的namespace和自定义或第三方的用一个换行把它们分开。
using System; using System.Web.UI; using System.Windows.Forms; using CSharpCode; using CSharpCode.Style;
14.文件名要能反应类的内容,最好是和类同名,一个文件中一个类或一组关连类。
15.目录结构中要反应出namespace的层次。
16.大括号 "{“要新起一行。
public Sample()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
// v1新增
// 严格使用换行和缩进;避免因为代码短而在if语句后紧跟return的写法以及类似写法,如
if(!checkBussinessStatus(bussinessCode)) return;
书写为
if(!checkBussinessStatus(bussinessCode))
{
return;
}
17. 局部变量,看情况使用var,尽量不使用var关键字。
18.对象初始化,能简写最好简写:
ValueText vt=new ValueText{Value=10, Text="Age"};
19.注释规则
/// <summary> /// 账单 /// </summary> public class Bill { /// <summary> /// 名称(注释的时候此处名称跟///必须有一个空格) /// </summary> private string m_name; /// <summary> /// Initializes a new instance of the <see cref="Bill"/> class. /// </summary> /// <param name="amount">金额</param> public Bill(decimal amount) { // 使用当前对象属性必须加this this.Amount = amount; } /// <summary> /// 金额 /// </summary> public decimal Amount { get; set; } /// <summary> /// 添加公司信息(当方法参数超过5个以上必须封装) /// </summary> /// <param name="company">公司信息</param> public void AddCompany(Company company) { // 方法体代码最多150行 // 单行注释必须跟//有一个空格 if (company == null) { return; } // 跟}结尾代码必须有一个换行符号 this.m_name = company.CompanyName; } }
20.命名空间书写
// 命名空间建议在头部采用using的方式引用 除非是为了解决命名空间冲突问题 // 错误的写法 System.DateTime date = System.DateTime.Now; // 正确的写法 DateTime date = DateTime.Now;
21.所有代码块,都必须以"{}"包括,如if-else,就算代码块只有一行,也必须这样。
/// <summary> /// 测试 /// </summary> /// <param name="left">左字符串</param> /// <param name="right">右字符串</param> public static void Test(string left, string right) { // 正确 if (left == right) { Console.WriteLine("OK"); } //错误(注释文本与//少一个空格) if (left == right) { Console.WriteLine("OK"); } // 错误(注释文本与//多一个空格) if (left == right) { Console.WriteLine("OK"); } // 错误left==right等号前后少一个空格 if (left==right) { Console.WriteLine("OK"); } // 错误所有代码块,都必须以"{}"包括,如if-else,就算代码块只有一行,也必须这样。 if (left == right) { Console.WriteLine("OK"); } }
22.一行只能写一句代码,禁止多句代码写在一行。
/// <summary> /// 测试 /// </summary> public static void Test() { // 正确 var anonymous = new { Key = "Key", Value = "Value" }; // 错误 var anonymous1 = new { Key = "Key", Value = "Value" }; // 错误 var anonymous2 = new { Key = "Key", Value = "Value" }; // 错误 var anonymous3 = new { Key="Key", Value="Value" }; }
23.缩进要采用VS默认缩进,代码编写完之后,按Ctrl+E,D格式化代码缩进。
/// <summary> /// 测试 /// </summary> public static void Test() { // 正确 var anonymous = new { Key = "Key", Value = "Value" }; // 错误 格式错误 var anonymous1 = new { Key = "Key", Value = "Value" }; // 错误 结尾2个;号 var anonymous2 = new { Key = "Key", Value = "Value" };; // 错误多了一个空格缩进 var anonymous3 = new { Key = "Key", Value = "Value" }; }
24.使用VS工具,对using引用进行排序。
(1). 系统命名空间 排最前面,按字母重a-z升序排序
(2). 第三方命名空间排在系统命名空间后面,按字母重a-z升序排序
(3).项目内部命名空间排在第三方命名空间后面按字母重,a-z升序排序
(4).系统命名空间 和第三方命名空间 或者项目内部命名空间 之间必须有一个空行
(5).命名空间必须定格编写(如果代码文件有编辑作者注释 必须在注释空一行在编写命名空间)
(6).命名空间必须写在namespace之外 并且之间有空行
25.编码规范
(1)实现了Idisposable接口的,必须通过using来保证资源的释放。
(2)提供了Close方法的,必须采用try-finlly方式手动调用。
(3)使用StringBuilder来处理超过10个字符的字符串,而不是string。
(4)采用string.Format来格式化字符串,而不是采用"+"来拼接 或者 $"{变量}";
(5)禁止使用GOTO语句
(6)解决编译器产生的所有警告
(7)所有输入参数都必须进行检查,null、空字符串、边界值、索引超出数组界限等。
(8)数据转换使用TryParse,禁止直接转换。
(9)同一个方法,禁止循环嵌套超过3层。
(10)变量定义都有合适的初始值。
(11)除数为0、数值溢出(累加值,乘法,超出既定类型的长度)的现象都做了处理。
(12)禁止出现死循环。
(13)禁止捕获异常而不处理,直接抛出,或者抛出新异常。
(14)禁止吃掉异常(非特殊情况)。
(15)一个方法禁止超过200行代码 一行代码不要过长,在必要时将一行代码分拆成多行。
(16)禁止在一个cs文件中声明多个类、接口。
(17)cs文件应该与其中的类型命名空间存放在同样的目录结构中。
(18)方法严格按照作用范围声明private、protected、internal或public,杜绝一概使用public修饰符,不应该被重写的类应该添加sealed修饰符 不对外公开的接口,都不使用public,应使用private、internal、protect。
(19)使用string.Empty替换””
(20)禁止使用DataSet、DataTable。
(21)代码应该自注释,禁止无意义的注释,禁止在注释中涉及谩骂等负面信息。
(22)类文件必须包含文档注释,包含创建人,最后修改人,最后修改时间。
(23)方法必须包含文档注释,说明方法用途以及注意事项。
(24)方法参数必须包含在方法文档注释中,并且保持参数顺序一致。
(25)代码块,理论上每5句代码应该有一个注释,不强制,但是对复杂逻辑强制要求有注释。
(26)外部dll,必须统一存放在一个单独的目录中。
(27)MVC的引用,必须引用项目本地的文件,禁止引用.NET的MVC文件。
(28)禁止在一个方法内部,多次访问数据库查询同一条数据。
(29)禁止在主方法和子方法中,多次访问数据库查询同一条数据。
(30)insert、update、delete,必须采用事务处理,并且判断受影响行数。
(31)事务处理,统一使用公用组件数据库DbTransaction进行处理。
(32)读取数据时,必须验证DbNull。
(33)禁止进行SQL语句拼接,只能使用参数化查询。
(34)参数化查询时,必须显示指定参数类型。
(35)禁止使用DataSet、DataTable,而是使用DataReader。
(36)数据库连接和事务的管理,必须放在业务层,而非数据库访问层。
(37)数据库连接必须使用using语句进行资源的合理释放。
(38)禁止物理删除数据,仅允许通过标志位进行逻辑删除。
(39)数据库连接必须设计读库连接和写库连接。
(40)对同一个数据库操作,禁止在一个方法中重复连接和关闭。
(41)查询语句,禁止使用"*"号,必须显示指定字段名列表。
(42)表名采用单数形式,不采用复数形式。
(43)不设计外键关联。
(44)合理设计索引,常用查询条件字段必须添加索引。
(45)合理使用自增字段,理论上来说,不推荐使用自增字段。
(46)bool类型用"Is”、"Can”、"Has”等表示,并且采用tinyint(2),而不是bit。
(47)日期类型命名必须包含"Date”。
(48)时间类型命名必须包含"Time”。
(49)不采用视图,不采用存储过程,不采用触发器,不采用定时器。
(50)不能使用数据库系统关键字作为字段名。
(51)定长的字段,应该采用char,而不是varchar。
(52)每个表都必须包含ModifyTime(timestamp)时间戳。
(53)每个表都必须包含主键,如果可以设计出业务主键,禁止使用自增主键。
(54)索引命名:IDX_表名_字段名
(55)主键命名:PK_表名_字段名
(56)原则上,单表字段应该不超过40个字段,超过需要公司备案。
(57)字段都必须保证非空,即不能为null。
(58)禁止使用游标。
(59)禁止使用临时表。
(60)禁止insert时不指定字段名。
(61)字段命名,采用单词首字母大写的形式,禁止使用无意义的字段名。
(61)禁止字段名与实际存储数据不一致。
(63)所有sql语句 关键字全部统一 大写 或者小写 (推荐全部大写)
(64) 禁止在代码中直接使用绝对路径
(65) 变量类型定义使用系统特有类型,而不是命名空间中定义的别名类型,如int、long、string来定义变量而不适用Int32、Int64、String
(66) 未使用的变量、参数和私有方法应该删除
(67) 带有预设值的变量定义式因使用var来定义变量,可以在将来可能的代码重构或定义发生变化时简化重构工作量
(68) 在引用不可预测值的属性或变量时进行null值检测避免空值异常
(69) 不要通过实例方法给静态变量赋值,在不可避免时必须进行上锁操作
(70)循环嵌套不宜过于复杂,当循环嵌套超过三层时考虑将每层循环分解到新的方法中
(71)switch语句应该以default结束,即使default块很可能不会被执行
(72)避免在构造函数中调用实例的可重写方法
(73)在逻辑运算表达式中尽量使用明确的括号来确定分子式的优先级避免出现弄错运算符优先级导致结果错误,运算符优先级错误使用很难被发现
(74)对具有固定含义的数值用枚举代替代码中的数字,如业务状态,类型等;
(75)公共无上下文的功能优先考虑采用静态定义和方法扩展,降低内存消耗
(76)避免在循环中请求数据库或者服务
(77)正则表达式编译会占用大量的运算资源,杜绝在方法内实例化正则表达式对象或通过实例字段定义正则表达式对象,除非正则表达式不是确定的,明确的正则表达式应该被定义成静态字段或者定义于集中的静态类中,且进行预编译
(78)检测可枚举类型变量时候包含元素时使用Any()方法不使用Count()方法,使用Count()方法可能会在底层代码中重新实例化对象并复制集合内容影响代码性能
(79)在大量可枚举类型中多次查找固定字段或属性时考虑通过对该字段或属性建立字典,然后通过字典查找
(80)代码提交前需IDE编译通过,无法通过编译的代码禁止提交至GIT
(81) 在创建任何提交之前进行提取操作
(82)新功能代码提交时需详细说明本次提交的内容
(83)修复的BUG提交时注修复的具体BUG编号
26.数据规范
(1).SQL脚本编写关键字全部大写
(2).数据库字段命名Pascal规则
(3).库名(表)命名单词之间用下划线隔开
(4).表名字段长度 姓名 名称 没有特需说明 varchar(64)
(5).金钱数字类 deciaml(18,4) or deciaml(18,2)
(6).枚举 tinyint(4)