一致地使用一种命名约定,能给那些阅读代码的人留下极有价值的直观线索。可以让代码更为可读,更易于项目维护。
1使用有意义的名称
使用对读代码的人始终有意义的名称。使用有意义的单词创建名称。使用可被未来程序员所理解的一致的语言。避免使用单个字符或太一般性的名称,那样对定义所命名的实体无所助益。
在下面的代码中,变量a和常量65的目的不清晰:
If(a<65 )
{
//’a’的属性是什么?
//这里正在计算什么
Y=65 – a;
}
else
{
Y=0;
}
改用有意义的名称后,下面这段代码更易于理解:
If(age<RetirementAge)
{
yearsToRetirement=RetirementAag-age;
}
else
{
yearsToRetirement=0;
}
本条规则的唯一例外是,当足以从上下文中判断出其目的时,可用简约方式命名临时变量,例如在循环内部用作计数器或索引的变量:
for(int i=0;i<numberOfStudents;++i)
{
EnrollStudent(i);
}
2根据含意而非类型来命名
类型信息一般可从其用法和使用场景中推断出来。有意义的名称才有用。例如,使用Customer而不用CustomerClass。
本条规则的一个例外是GUI控件的命名。有时,以名称来区分GUI元素的类型非常用用。例如,区分customerNameLabel和customerNameTextbox。
3使用熟悉的名称
使用目标领域术语表中存在的单词。如果统一术语使用“customer”,则用Customer命名类,而不用Client。不在尝试在已存在固有命名习惯的项目和团队内去使用新创的术语。要保持团队风格。
4不要用大小写来区分名称
编译器能够区别仅大小写不同的名称,但人可能注意不到其差异。这等同于名字隐藏。例如,如果已经有名为XMLStream的类存在,就别将其他类命名为XmlStream。假若两个类在同一作用域内出现,从人阅读和理解代码的角度来看,其中一个就会把别一个隐藏掉。
5避免使用过长的名称
对象的名称应足以描述其目的。如果类,接口,变量或方法的名称过长,则该实体可能企图实现太多功能。不要简单地用包含更少意义的名称重命名实体,首先要考虑其设计或目的。通过实体的重构可以得到功能更集中,用更简洁的名称即可涵括其意义的新类,新接口,新方法或新变量。
6使用完整的单词
切勿通过去除元音来缩短名称。这种做法降低了代码的可读性,如果有多个本来具有实际意义的名称被缩减为同一类形式,就会产生岐义。
下面的代码不好:
Publicclass Msg
{
PublicMsg AppendSig(string sig)
{
….
}
}
最好改成:
Publicclass Message
{
Public Message AppendSignature(string signature)
{
…
}
}
这样,偶然读到代码的人才能看懂后面的实现。
如果只为了缩短名称而去除元音,那么需要考虑一下原来的名称是否合适。
7 除非全称太长,否则不用缩略形式
坚决不用不必要的缩略词迷惑人。没有必要用Grph取代Graphical,使用GuiListener比GraphicalUserInterfaceListener要好。如果必须使用缩略词,就用广为使用和接受的缩略词。
8 像普通词一样书写缩略词
如果缩略词是类型或常量名称的首个单词,只大写缩略词的第一个字母。
当大写字母用作隔离符时,这种写法能消除名称中的含糊之处。如果缩略词后面还有一个缩略词时,这一点尤为重要:
XMLString --àXmlString
LoadXMLDocument()--àLoadXmlDocument()
条件编译指示符的名称中的缩略词不适用这一规则,因为这类名称只能用大写字母写出
[conditional(GUI)]
本规则不适用于在变量或参数名开始处的缩略词。因为这些名称总以小写字母开头:
DocumentxmlDocument;
9用大写字母和下划线表示预处理器符号
用大写字母表示预处理器符号,使之与用C#语法定义的符号区分开来:
#define EVAL_VERSION
10给预处理器名称添加唯一前缀
给预处理器名称添加前缀,避免与用户定义或第三方软件中的预处理器名称相冲突。建议使用公司名称的缩略形式,可自行选择是否加上产品名称的缩略形式,例如:
COMPANY_DB_USER。
11使用Pascal写法给命名空间,类,结构,属性,枚举,常量及函数命名
每个单词的首字母大写,区分名称中每个独立的单词,第一个字母大写提供了一个使其与参数或变量相区分的机制
Publicenum BackgroundColor
{
None=0,
Red=1,
Green=2,
Blue=3
} ;
Const int FixedWidth=10;
Classs BankAccount
{
}
Publicdouble CalculatePercentile(doule percent)
12使用名词命名复合类型
应该用名词来命名定义了对象或其他事物的类,结构或属性
Public class Customer
{
Publicstring Name
{
Get
{
Return _name;
}
}
}
13用复数形式书写集合名称
对象集合的名称应该有能反映集合中对象的类型的复数形式。这样阅读代码时才能区分表示多个值的变量和表示单个值的变量:
List<Shape> shapes=…
Shape shape= shapes[index];
14 给抽象基类加上”Base”后缀
清晰定义的基类更易于管理
Public abstract class AccountBase
Public class PersonalAccount:AccountBase
Public class BusinessAccount:AccountBase
15给实现一种设计模式的类添加模式名称
例如,名为MessageFactory的类对熟悉设计模式的开发人员来说有某种特定含义。
16使用单个大写字母命名泛型参数
Public static List<T>Uniquify(List<T>)
{
…
}
17用单数形式为枚举命名
枚举类型通常用于相互独立的元素组成的列表,应使用单数形式:
Public enum SortOrder
18用复数形式给BitFields命名
BitFields通常用于可以组合形式出现的元素的列表应使用复数形式:
[Flags]
Public enum PrintSettings
{
Draft=0,
Duplex=1,
Color=2
};
19用大写字母“I”作为接口名称的前缀
如果知道某个类是继承自父类还是实现一个接口,这样做会比较方便。
Publicclass Worker:IWorkabel
20使用名词或形容词给接口命名
接口声明了对象提供的服务,或描述了对象的能力。
使用名词给用于声明服务的接口命名:
Public interface IMessageListener
{
Publicvoid MessageReceived(Message message);
}
使用形容词给用于描述能力的接口命名。大多数描述能力的接口使用在动词后面加上-able和-ible后缀创造的形容词来命名:
Public interface IReversible
{
PublicICollection Reverse();
}
21依取值或赋值项给属性命名
例如:对于一个取得过期日的属性:
Date _expirationDate;
Public Date ExpirationDate
{
Get
{
Return _expirationDate;
}
}
22避免冗长的属性名称
使用
PublicICollection Customers
不用
PublicICollection CustomerCollection
23用能体现布尔值特性的名称给布尔型属性命名
如果某个属性返回一个布尔值,给其名称加上”is”,”has”或”are”前缀
Public bool IsGood
Public bool HasCompleted
24使用Pascal写法为方法命名
函数名中第一个单词首字母大写,后面每个单词首字母大写,可区分开名称中每个单词。
Public class DateManipulator
{
Publicvoid ComputeStatistics(Double m);
}
25用动词命名方法
方法通常定义动作,应该用动词描述:
Public class Account
{
Publicvoid Withdraw(decimal amount)
{
_balance-=amount;
}
}
26避免冗长的方法名
在名为Book的类中,使用
Public void Open()
不用
Public void OpenBook()
27使用骆驼写法给变量和方法参数命名
变量名中第一个单词的首字母小写,后面每个单词的首字母大写,区分开名称中每个单词。
Public class Customer
{
Publicstring name;
Publicstring Tostring()
{
Return name;
}
}
第一个小写的字母把变量与常量区分开来:
Const int ConstantValue=10;
Int variableValue=1;
28用名词命名变量
变量代指对象或类似事物,应该用名词描述。复数形式的变量名表示集合:
Publicclass Customer
{
Publicstring name;
Privatedecimal _deposit;
Publicorder[] orders;
}
29给成员变量名称加上前缀或后缀,使之与其他变量区分开
这样能减少名称隐藏的可能性,提高代码可读性。
使用原则根据成员变量的对外可访问性,将private成员变量名前面加上”_”,其余访问修饰符限定的成员变量首字母小写。
Public class Customer
{
Publicstring name;
Privatedecimal _deposit;//前面加上”_”,标识为私有成员变量
Publicorder[] orders;
}
这样可以利用CodeRush模板功能,方便生成私有成员变量的属性成员。
30依所赋值的字段名称给构造函数和属性参数命名
Public class Customer
{
Privatestring _name; /前面加上”_”,标识为私有成员变量
Public Customer(string name)
{
_name=name;
}
Public string Name
{
Get
{return _name;}
}
}
31用一系列标准名称为“一次性”变量和参数命名
应使用足具描述性的名称给大多数变量命名,但在C#代码中频繁出现的许多变量类型拥有共用的短名称,
循环指示符(for中的int) I,j,k
Object o
String s
Exception e或ex
EventArgs ea
Graphics g
32给自定义属性实现加上”Attribute”后缀
在C#中,给属性类名称加上”Attribute”后缀是标准做法
Public class MyFavoriteAttribute:Attribute
33用公司名称给根命名空间命名,加上项目,产品来缩小范围
Namespace NetDragon.Web.Store
{
}
34使用适当的名称清晰区分事件处理部分
事件类的名称就包括对动作的描述,如MessageReceived。
引发事件的类的名称应该是名词,如Message。
为事件定义数据的类的名称应该类似MessageReceiveEventArgs.
MessageReceiverEventHandler是委托。
MessageReceiver是一个类,有一个名为OnMessageReceived()方法,该方法处理MessageReceived事件。
35给自定义异常类型添加”Exception”后缀
异常要特殊一些,用易于识记的名称命名:
PublicBadArgumentException:ApplicationException
{
}
36 WEB开发过程中页面控件变量声明前缀表
在asp.net编辑过程中,将页面控件对应的控件变量加入以下前缀,方便在编程过程中定位控件类型。
控件 | 前缀 | 控件 | 前缀 |
Form | frm | Class | cls/C |
Module | mod | Label | lbl |
LinkLabel | lnk | Button | btn |
TextBox | txt | CheckBox | chk |
RadioButton | rad | GroupBox | grp |
PictureBox | pic | DataGrip | grd |
ListBox | lst | CheckedListBox | clst |
ComboBox | cbo | TreeView | tvw |
ListView | lvw | TabControl | tab |
DateTimePicker | dtp | Timer | tmr |
Splitter | spl | ProgressBar | pbar |
RichTextBox | rtf | ImageList | imgl |
ToolBar | tlb | MenuItem | mnu |
37源码注释
通过IDE模板功能完成,通过在类成员上方键入”\\\”生成注释模板,填充模板内容尽可能详细,并描述程序模块功能。后期利用NDOC或者SandCastle生成项目开发文档。利用后期维护。