1、命名约定
Pascal 和 Camel命名约定
编程的命名方式主要有Pascal和Camel两种
(Pascal:每个单词的首字母大写,例如ProductType;Camel:首个单词的首字母小写,其余单词的首字母大写,例如productType)
以下是一些常用的C#成员及其推荐命名方法:
标志符
| 规则
| 实例与描述
| 备注 |
类class
| Pascal
| Application
|
|
枚举类型enum | Pascal
| Pascal | 记住,是以Pascal命名,切勿包含Enum,否则FXCop会抛出Issue
|
委托delegate
| Pascal
| MyDelegate | 以Pascal命名,不以任何特殊字符串区别于类名、函数名
|
常量const
| 全部大写
| FIXED_NUM | 全部大写,单词间以下划线隔开
|
接口interface
| Pascal
| IDisposable | 注:总是以 I 前缀开始,后接Pascal命名
|
方法function
| Pascal
| ToString
|
|
命名空间namespace
| Pascal
| ExcelQuicker.Framework
| 以.分隔,当每一个限定词均为Pascal命名方式 |
参数
| Camel
| sendMessage | 首字母小写
|
局部变量
| Camel
| strPrint | 也可以加入类型标识符,比如对于System.String类型,声明变量是以str开头,string strSQL = string.Empty;
|
数据成员
| Camel
| mProductType | 以m开头+Pascal命名规则 |
属性
| Pascal
| Employee |
|
数据库字段 | Pascal | UserName |
|
1.1、局部变量命名
在private 的局部变量命名时,使用Camel命名规则。
比如:int type = 0;
double count= 0;
对于string类型定义,通常使用str前缀+Pascal命名的方式,
比如string strSql = ""; //这是一种典型的命名SQL语句字符串的方式。
而对于此外的类型对象定义,通常的做法是使用obj前缀+Pascal命名的方式,来告知我们这个变量是一个对象。或者也可以直接使用类名的Camel命名规则。
比如:Application application = new Application(); ApplicationobjApplication = newApplication(); 个人更倾向于前者
1.2、参数命名
Camel命名规则,首字母小写 (可以认为参数就是方法中的局部变量)
1.3、类数据成员 / 属性命名
数据成员命名以Camel命名方式,而属性以Pascal命名。
通常如果数据成员与属性成对的话,数据成员与属性的命名区别仅在于变量名的第一个字母是小写还是大写。
public class Log
{
public Log()
{ }
private string username;
/// <summary>
/// 用户名称(操作人)
/// </summary>
public string UserName
{
set {username = value; }
get { returnusername; }
}
}
另外,类的成员数据 / 方法调用时,应该加上this限定符,this在编辑环境中是蓝色的。
更利于我们区分局部变量、参数或静态变量,并且利于FXCop检测区分。(如果使用FxCop扫描和检测代码的话)
1.4、命名空间命名
在dot之间的各限定字符串符合Pascal格式
System.Web.UI.Page
1.5、委托缩写
委托的命名方式我常常以Pascal命名,并且在命名的后面加EventHandler
比如public delegate voidMouseEventHandler (object sender, MouseEventArgse); //用于处理与鼠标相关的事件或委托
对于自定义的委托,其参数第一个建议仍然使用object sender,sender代表触发这个时间或委托的源对象。而第二个参数继承于EventArgs类,并且在派生类中实现自己的业务逻辑。
1.6、自定义异常类
自定义异常类以Exception结尾,并且在类名中能清楚的描述出该异常的原因。
比如NotFoundFileException,描述出了某个实体(文件、内存区域等)无法被找到。
1.7、枚举
枚举的命名是Pascal命名,不需要在枚举中加入Enum,枚举的名称能清楚的表明该枚举的用途。
1.8、常量命名
全部大写,单词间并且以下划线间隔。
如publicconst intLOCK_SECONDS = 3000;
虽然在MSDN中常量的命名推荐使用Pascal,但是从C++沿袭的命名规则来看,将常量全部大写更加能清楚的表示常量与普通变量之间的区别。
1.9、命名缩写
在 一般情况下,不推荐缩写命名,不要担心变量命名长,长的变量名能使变量的意义更加清晰。
其实从长变量名的负面作用三:
因为Ctrl+C和Ctrl+V加上 在VS中的智能感知,其负面追用已经很小。变量命名的原则是,尽最大努力让其他人在看到我们的变量/函数/…等的第一时间,大概能猜出它是做什么的。
比如:int productTypeCount = 0; //我们在第一时间就能知道它是记录产品的数量的变量
而 对于糟糕的命名方式:int prodTypeCount = 0; //它是productTypeCount的简写,我们一部分人也许知道prod是 product的缩写,但是每人能保证所有的人都知道它。
最 优秀的代码它本身就是注释。作为一流的程序员。并不仅仅实现功能,而是要让我们的代码更加优美,具备让他人维护或今后扩充的能力。作为现在的业务系统,其门槛的准入水平已大大降低,实现功能上的需求已没有什么难度,但是高手和菜鸟的区 别在于,高手的代码通俗易懂,在整个编码的过程中,不仅能考虑到性能、还会考虑代码可读性和维护性。
1.10、数据库命名
数 据库的字段、表名的命名都推荐采用Pascal命名方式,尽量不采用缩写。(建议最长不超过15字符)
当然,使用长的字段名、表名,可能会使SQL语句的编写带来负面影响。
我推荐大 家可以使用一些ORM,ORM的性能肯定不会比直接写SQL的好,但是如果做业务系统,更重要的是系统多久能交付用户使用,ORM不仅使开发时间可以缩短 不少,并且在后期的维护上也比直接写SQL便利很多。
2、注释规范
2.1、文件头部注释
在 代码文件的头部进行注释,这样做的好处在于,我们能对代码文件做变更跟踪。
在代码头部分标注出创始人、创始时间、修改人、修改时间、代码的功能。
这在团队开发中必不可少,它们可以使后来维护/修改的同伴在遇到问题时,在第一时间知道他应该向谁去寻求帮助,并且知道这个文件经历了多少次迭代、经历了多少个程序员的开发和修改。
/// <summary>
/// 创建人:jayfery
/// 创建时间:2012-04-01
/// 描述:会员用户数据访问
/// </summary>
public class UserService
{}
2.2、函数、属性、类等注释
使用///三斜线注释,这种注释是基于XML的,不仅能导出XML制作帮助文档,而且在各个函数、属性、类等的使用中,编辑环境会自动带出注释,方便你的开发。
以protected,protected Internal,public声明的定义注释都建议以这样命名方法。
/// <summary>
/// 通过UId查询User表中的某人的数据
/// </summary>
/// <param name="uid">会员编号</param>
/// <returns>会员对象</returns>
public static Users SelectUsers(int uid)
{}
2.3、逻辑点注释
逻辑性较强的地方加入注释,说明这段程序的逻辑是怎样的,以方便我们自己后来的理解以及其他人的理解,并且这样还可以在一定程度上排除BUG。
在 注释中写明我们的逻辑思想,对照程序 --> 判断程序是否符合我们的初衷,如果不是,则我们应该仔细思考耀修改的是注释还是程序了。
3、排版
1、 每行语句至少占一行,如果语句过长(超过一屏),则该语句断为两行显示;
2、 把 相似的内容放在一起,比如数据成员、属性、方法、事件等。
并 适当的使用#region…#endregion,我最喜欢把机器生成的代码都放在一 个#region里面,比如在编写ASP.NET程序时,对应自动产生的控件定义,我常 用#regionAutomaticGenerated Web Components … #endregion把他们框住
3、 使用空格,
(1) 双目操作符的前后加空格(+,=, && 等),index= index + 1;
(2) 单目操作符前加空格(!, ++,~ 等), index++;
(3) 逗号、分号只在后面加空格
4、 使用空行,在一段功能代码、或者函数、属性之间插入空行,这样会很直观。
4、代码可读性一些建议
(1)注意运算符的优先级,我们应该尽量使用括号明确表达式的操作顺序,避免使用默认优先级,给我们以及维护人带来困扰。
(2)避免使用不易理解的数字,用有意义的标识来替代(枚举和常量)
(3)尽量少用单独的字母变量(i k n m)排除在循环里。
比如:
if(productType == 0)
else if (productType == 1)
(不推荐使用)
if(productType ==ProductType.CD)
else if (productType == ProductType.DVD)
(推荐使用)
(3)在界面层中尽量使用异常处理try语句,不要将系统级别的错误直接暴露给用户,而更应该的是把系统抛出的错误信息记录到LOG日志文件中去,告诉用户友好的提示信息。
5、规范注意点
1、尽量有命名规范(见名知意)
2、程序集不必与命名空间同名
3、考虑在命名空间中使用复数
4、避免用FCL[关键词] 的类型名称和自己的类型名称相同
5、用名称和名词组给类型命名,用形容词组合给接口命名
6、考虑让派生类的名字以基类名字 做为后缀
7、泛型类型参数要以 T 作为前缀
8、以复数命名枚举类型,以单数命名枚举元素
9、用 PasalCasing 命名公开元素(属性、方法)
10、考虑用类名作为属性名
11、用CamelCasing 命名私用 字段 和 局部变量
12、考虑使用肯定性的短语命名布尔属性
13、优先使用后缀表示已有类型的新版本
14、委托和事件类型应添加上级后缀
15、事件和委托变量使用动词和形容词
16、事件处理命名用组合方式(事件变量所属对象+下划线+事件变量名)
6、代码整洁注意
1、使用默认的访问修饰符
2、不知道该不该用大括号时,就用
3、总是提供有意义的命名 (见名知功能)
4、方法抽象级别应在同一层次
5、一个方法只做一件事原则(SRP)
6、避免过长的方法和过长的类
7、只对外公布必要的操作
8、重构多个相关属性的类
9、尽量不要重复代码
10、使用表驱动法避免过长的 IF 和 switch
11、最少,甚至是不要注释(前提是命名很规范)
12、若抛出异常,则必须要注释