The Elements of C# Style -Naming
1.一般原则
1.1 使用有意义的名称
使用对阅读代码的人始终有意义的名称。例如:
if (a < 65) { y = 65 - a ; } else { y = 0; }
改为
if( age < RetirementAge) { yearToRetirement = RetirementAge - age ; } else { yeaerToRetirement = 0; }
本规则例外情况:当足以从上下文中判断出其目的时,可以用简约的方式命名临时变量,例如在循环内部作计数器或索引的变量:
for ( int i = 0 ; i < numberOfStudents ; ++i) { EnrllStudent(i) ; }
1.2 根据含义而非类型来命名
类型信息一般可以从其语法和使用场景中推断出来。有意义的名称才有用。例如,使用Customer而不用CustomerClass。
本规则例外情况:GUI控件的命名。有时,以名称来区分GUI元素的类型非常有用。例如,区分customerNameLabel(窗体上的标记控件)和customerNameTextbox(窗体上的文本框控件)。
1.3 使用熟悉的名称
使用目标领域术语表中存在的单词。如果客户喜欢用“customer”,则用Customer命名类,而不用Client(客户)。
1.4 不要用大小写来区分名称
编译器能够区分仅以大小写不同的名称,但人可能注意不到其差异。这等同于名字隐藏。例如XMLStream和XmlStream。
1.5 避免使用过长的名称
对象的名称足以描述其目的。如果类、接口、变量或方法的名称过长,则该实体可能企图实现太多功能。
1.6 加上元音-使用完整的单词
切勿通过去除元音来缩短名称。
public class Msg { public Msg AppendSig(string sig) { } } 最好改成 public class Message { public Message AppendSignature(string signature) { } }
2. 缩略形式
2.1 除非全称太长,否则不用缩略形式
坚决不用不必要的缩略次迷惑人。
2.2 像普通词一样书写缩略词
如果缩略词是类型或常量名称的首个单词,只大写缩略词的第一个字母。 XMLString -> XmlString LoadXM
条件编译指示符的名称中的缩略词不适用这一规则,因为这类名称只能用大写字母写出。
[conditional(GUI)]
本规则不适用情况:在变量或参数名开始处的缩略词,因为这些名称总以小写字母开头:
Document xmlDocument
3. 预处理器符号
3.1 用大写字母和下划线表示预处理器符号
#define EVAL_VERSION
3.2 给预处理器名称添加唯一前缀
建议使用所在组织名称的缩略形式,可自行选择是否加上产品名称的缩略形式。
4. 类型和常量
4.1 使用Pascal写法给命名空间、类、结构、属性、枚举。常量以及函数命名
每个单词的首字母大写,区分名称中每个独立的单词。第一个字母大写提供了一种使其与参数或变量相区分的 机制。
4.2 使用名称命名复合类型
应该用名词来命名定义对象或其他事物的类、结构或属性。
4.3 用复数形式书写集合名称
List<Shape> shapes=...
4.4 .给抽象基类类型加上“Base”后缀
public abstract class AccountBase ; public class PersonalAccount : AccountBase ; public class BusinessAccount : AccountBase ;
4.5.给实现一种设计模式的类添加模式名称
MessagerFactory
4.6 使用单个大写字母命名泛型参数
public static Lsit<T> Uniquify(List<T>) { ... }
5. 枚举
5.1 用单数形式为枚举命名
public enum SortOrder
5.2 用复数形式给位域命名
位域通常用于可以组合形式出现的元素的列表,应使用复数形式:
[Flags] public enum PrintSettings { Draft = 0, Doplex = 1, Color = 2, }
6. 接口
6.1 用大写字母“I”作为接口名称的前缀
6.2 使用名词或形容词给接口命名
接口声明了对象提供的服务,或描述了对象的能力。
使用名词给用于用于声明服务的接口命名:
public interface IMessageListener { public void MessageReceived( Message message) ; }
使用形容词给用于描述能力的接口命名。大多数描述能力的接口使用在动词后面加上-able或-ible后缀创造的形容词来命名:
public interface IReversible { public ICollection Reverse(); }
7. 属性
7.1 依附值或赋值想给属性命名
public Date ExpirationDate { get { return expirationDate_; } }
7.2 避免冗长的属性名称
YES: public ICollection Customers NO:public ICollection CustomerCollection;
7.3 能用体系布尔值特性的名称给布尔型属性命名
如果某个属性返回一个布尔值,给其名称加上“is”、"has"或"are"前缀。
public bool IsGood ; public bool HasCompleted ;
8. 方法
8.1 使用Pascal 写法为方法命名
函数名中第一个单词首字母大写,后面每个单词首字母大写,可区分开名称中的每个单词。
public class DataMainpulator { public void ComputeStatistics(DoubleMatrix m) ; }
8.2 用动词命名方法
public class Account { public void Withdraw(double amount) { balance_ -= amount ; } public void Deposit(double amount) { Withdraw( - amount); } }
8.3 避免使用冗长的方法名
在Book的类中使用public void Open() ;而不使用 public void OpenBook () ;
9. 变量和参数
9.1 使用骆驼写法给变量和方法参数命名
变量中的第一个单词的首字母小写,后面的每个单词的首字母大写,区分开名称中每个单词。
public class Customer { public string firstName_; public string lastName_; public string ToString() { return lastName_ + ", " + firstName_; } }
9.2 给成员变量名称加上前缀后后缀,使之与其他变量区分开
例如可以加上后缀下划线。
public class Customer { private string homePhone_; private string workPhone_; }
9.3 依所赋值的字段名称给构造函数和属性参数命名
依成员变量名称给方法参数命名,向阅读者指出参数赋值给成员。
public class Customer { private string name_; public Customer(string name) { name_ = name; } public string Name { get { return name_; } } }
9.4 用一系列标准名称为“一次性”变量和参数命名
可以使用下列命名:
循环指示符(通常是int) i,j,k
Object o
String s
Exception e或ex
EventArgs ea
Graphics g
10. 特性
10.1 给自定义的特性实现加上“Attribute”后缀
public class MyFavoriteAttribute : Attribute
11. 命名空间
11.1 用机构名称给根命名空间命名,加上项目、产品或小组名来缩小范围
namespace Company.Group.Project { ... }
12. 事件处理
12.1 使用适当的名称清晰区分事件处理部分
事件类的名称应该包括对动作的描述,例如:MessageReceived.
引发事件的类的名称应该是名词,如Messager。
为事件定义数据的类的名称应该类似MessageReceivedEventArgs.
MessageReceivedEventHandler是委托。
13. 异常
13.1 给自定义异常类型添加“Exception”后缀
public BadArgumentException :ApplicationException { ... }