1. 前言
本文档是按照Maxlab日常C#代码书写规范化需要而对MSDN中《类库开发的设计准则》的具体化,其中若有不详之处可以参考《准则》一文。MaxLab所有.NET项目都应严格遵守本代码规范中的代码书写要求,代码书写规范将作为项目审核标准之一,所以请务必认真阅读本文档。
2. 大小写约定
大小写样式
本文中将出现两种大小写样式,这里先分别定义:
Pascal大小写
将标识符的首字母和后面连接的每个单词的首字母都大写。可以对三字符或更多字符的标识符使用 Pascal 大小写。例如:BackColor
Camel大小写
标识符的首字母小写,而每个后面连接的单词的首字母都大写。例如:backColor
标识符大小写规则
下表中列出常见的代码元素的样式规范和示例
除了遵循以上大小写约定外还需注意以下约定(除常量为特例):
1.如果标识符由多个单词组成,请不要在各单词之间使用分隔符,如下划线(“_”)或连字符(“-”)等。而应使用大小写来指示每个单词的开头。
2.所有公共的成员如:方法、属性,都应使用Pascal大小写样式
首缩写词的大小写规则
缩写词分为以下两种:
首字母缩写词
首字母缩写词是由术语或短语中各单词的首字母构成的单词。
例如,HTML 是 Hypertext Markup Language 的首字母缩写。
为了方便编码规范的实施,本文规定受字母缩写词必须至少为两个单词,正好为两个单词的首字母缩写词称其为“短型首字母缩写词”
两个单词以上的称其为“长型首字母缩写词”
单缩写词
单缩写词是一个单词的缩写。例如,ID 是 identifier 的缩写。
注意:可在标识符中使用的两个缩写词是 ID 和 OK。在采用 Pascal 大小写格式的标识符中,这两个缩写词的大小写形式应分别为 Id 和 Ok。
如果在采用大小写混合格式的标识符中将这两个缩写词用作首个单词,则它们的大小写形式应分别为 id 和 ok。
首字母缩写词有以下大小写规则:
短型首字母缩写词在Pascal大小写样式中,两个字母都应大写。在Camel大小写样式中,如果是首个单词,两个字母都应小写。
例如,名为 DBRate 的属性是一个采用 Pascal 大小写格式的标识符,它使用短型首字母缩写词 (DB) 作为首个单词。
又如,名为 ioChannel 的参数是一个采用大小写混合格式的标识符,它使用短型首字母缩写词 (IO) 作为首个单词。
长型首字母缩写词,在任何大小写样式中都视为一个单词。
例如,名为 XmlWriter 的类是一个采用 Pascal 大小写格式的标识符,它使用长型首字母缩写词作为首个单词。
又如,名为 htmlReader 的参数是一个采用大小写混合格式的标识符,它使用长型首字母缩写词作为首个单词。
复合词的大小写规则:
所有复合词在任何大小写样式中都视为一个完整单词。
例如,hashtable 是一个紧凑格式的复合词,应将其视为一个单词并相应地确定大小写。
如果采用 Pascal 大小写格式,则该复合词为 Hashtable;如果采用大小写混合格式,则该复合词为 hashtable。
若要确定某个单词是否是紧凑格式的复合词,请查阅最新的词典。
区分大小写
大小写准则只是为了使标识符更易于阅读和辨认。不能将大小写规则用作避免库元素之间的命名冲突的手段。
3. 通用命名约定
通用命名约定讨论的是如何为库元素选择最适当的名称。这些准则适用于所有标识符。后面各节讨论特定元素(如命名空间或属性)的命名。
选择名称
1.请选择易读的标识符名称
例如,英文属性名称 HorizontalAlignment 比 AlignmentHorizontal 更具可读性。
2.可读性比简洁性更重要
例如,属性名称 CanScrollHorizontally 比 ScrollableX(指 X 轴,但意义不明确)更好。
3.不要使用下划线、连字符或任何其他非字母数字字符
4.不要使用匈牙利表示法
匈牙利表示法是在标识符中使用一个前缀对参数的某些元数据进行编码,如标识符的数据类型。
5.避免使用与常用编程语言的关键字冲突的标识符
虽然符合 CLS 的语言必须提供将关键字用作普通字的方法,最佳做法不要求强制开发人员了解如何实现。
对于大多数编程语言,语言参考文档都会提供语言所使用的关键字列表。下表提供了某些常用编程语言的参考文档的链接。
缩写和首字母缩写单词
尽量避免使用缩写或首字母缩写词。这类名称的可读性较差。同样,要确定某个首字母缩写词是否已受到广泛认可也是很困难的。
不要将缩写或缩略形式用作标识符名称的组成部分。
例如,使用 OnButtonClick 而不要使用 OnBtnClick。
除非必要,不要使用任何未被广泛接受的首字母缩写词。
有关缩写的大写规则,请参见-首缩写词的大小写规则
4. 程序集和DLL的名称
所有程序集名称都必须和项目的命名空间相对应。
程序集信息中都必须有且仅有一行[assembly: AssemblyCopyright("Copyright © 2007-2008 MaxLab.")]。
5. 命名空间的名称
所有命名空间都需以MaxLab为根命名空间。
为命名空间选择的名称应指示命名空间中的类型所提供的功能。
例如,System.Net.Sockets 命名空间包含的类型允许开发人员使用套接字通过网络进行通信。
命名空间名称的一般格式如下:
MaxLab.(<产品>|<技术>)[.<性质>][.<子命名空间>]
例如,MaxLab.MaxServer.Gui。
命名空间和其中的类型不要使用相同的名称。
例如,不要在将“Debug”用作命名空间名称的同时,又在该命名空间中提供一个名为“Debug”的类。
命名空间一般准则
不要引入宽泛的类型名称,如 Element、Node、Log 和 Message。在通常情况下,这样极可能导致类型名称冲突。
应对宽泛的类型名称进行限定(例如 FormElement、XmlNode EventLog、SoapMessage)。
应用程序命名空间准则
不要在单个应用程序模型内为命名空间中的多个类型指定相同的名称。
例如,如果要编写 Windows 窗体应用程序开发人员要使用的特殊控件库,则不应引入名为 Checkbox 的类型,
因为该应用程序模型已存在同名类型。
核心命名空间准则
不要指定会与核心命名空间中的任何类型发生冲突的类型名称。
例如,不要使用 Directory 作为类型名称,因为这会与 Directory 类型冲突。
技术命名空间准则
不要分配会与单个技术命名空间内的其他类型发生冲突的类型名称。
不要引入会导致技术命名空间的类型与应用程序模型命名空间中的类型发生冲突的类型名称(除非该技术不用于该应用程序模型)。
6. 接口、类和结构的名称
通常,类型名称应该是名词短语,其中名词是由类型表示的实体。
例如,Button、Stack 和 File 都具有名称,用于标识由类型表示的实体。
从开发人员的角度选择标识实体的名称;名称应反映使用场合。
下面的准则适用于如何选择类型名称:
1. 按照 Pascal 大小写格式,使用名词或名词短语(或偶尔使用形容词短语)为类、接口和值类型命名。
2. 不要为类名加前缀(如字母 C)。
3. 接口不适用此规则,它应以字母 I 开头。
4. 考虑在派生类的末尾使用基类名称。
例如,从 Stream 继承的 Framework 类型以 Stream 结尾,从 Exception 继承的类型以 Exception 结尾。
5. 为接口名称加上字母 I 前缀,以指示该类型为接口。
6. 在定义类/接口对(其中类是接口的标准实现)时,一定要确保类和接口的名称除接口名称以字母 I 为前缀外,二者应完全相同。
例如,Framework 提供 IAsyncResult 接口和 AsyncResult 类。
用描述性名称为泛型类型参数命名,除非单个字母的名称已完全可以自我说明而无需描述性名称。
IDictionary 是一个符合此准则的接口的示例。
对具有一个单字母类型参数的类型,考虑将字母 T 用作这些类型的类型参数名称。
将字母 T 作为描述性类型参数名称的前缀。
考虑在参数名称中指示置于类型参数上的约束。例如,约束于 ISession 的参数可称为 TSession。
常见类型的名称
下面的准则提供的命名约定有助于开发人员了解某些类的使用场合:
01. 向自定义属性类添加 Attribute 后缀。
02. ObsoleteAttribute 和 AttributeUsageAttribute 是符合此准则的类型名称。
03. 向在事件中使用的类型(如 C# 事件的返回类型)的名称添加 EventHandler 后缀。
04. AssemblyLoadEventHandler 是符合此准则的委托名称。
05. 向不是事件处理程序的委托的名称添加 Callback 后缀。
06. 不要向委托添加 Delegate 后缀。
07. 向扩展 System.EventArgs 的类添加 EventArgs 后缀。
08. 不要从 System.Enum 类派生;使用当前所用语言支持的关键字。例如,在 C# 中应使用 enum 关键字。
09. 向从 System.Exception 继承的类型添加 Exception 后缀。
10. 向实现 System.Collections.IDictionary 或 System.Collections.Generic.IDictionary<TKey, TValue> 的类型添加 Dictionary 后缀。
注意,System.Collections.IDictionary 是特定类型的集合,但此准则的优先级高于以下更为一般的集合准则。
11. 向实现
System.Collections.IEnumerable、
System.Collections.ICollection、
System.Collections.IList、
System.Collections.Generic.IEnumerable< T>、
System.Collections.Generic.ICollection<T>
或 System.Collections.Generic.IList<T> 的类型添加 Collection 后缀。
12. 向从 System.IO.Stream 继承的类型添加 Stream 后缀。
13. 向从 System.Security.CodeAccessPermission 继承的类型或实现 System.Security.IPermission 的类型添加 Permission 后缀。
注意:
以上准则中提及的从某个其他类型继承的类型,指的是所有的继承者,而不只是直接继承的类型。
例如,“向从 Exception 继承的类型添加 Exception 后缀”这一准则意味着在继承层次结构中具有 Exception 的任何类型都应该使用以 Exception 结尾的名称。
每条这样的准则还用来保留指定的后缀;除非类型满足该准则表述的条件,否则不应使用该后缀。
例如,如果类型不是从 Exception 直接或间接继承的,则类型名称不能以 Exception 结尾。
枚举的名称
不要在枚举值名称中使用前缀。例如,不要对 ADO 枚举使用 ad 之类的前缀,也不要对多格式文本枚举使用 rtf 之类的前缀,依此类推。
这还意味着不应在枚举值名称中包含枚举类型名称。下面的代码示例演示了不正确的枚举值命名。
public enum Teams
{
TeamsAlpha,
TeamsBeta,
TeamsDelta
}
不要将 Enum 用作枚举类型的后缀。
不要在标志枚举的名称中添加 Flags 作为后缀。
对枚举使用单数名称,除非枚举值是位域。
对使用位域值的枚举(也称为标志枚举)使用复数名称。
7. 类型成员的名称
类型包含以下几种成员:方法、属性、字段、事件
方法的名称
使用动词或动词短语作为方法的名称。通常,方法对数据进行操作,因此,使用动词描述方法的操作可使开发人员更易于了解方法所执行的操作。
定义由方法执行的操作时,应从开发人员的角度仔细选择明确的名称。不要选择描述方法如何执行其操作的动词,也就是说,不要使用实现细节作为方法名称。
属性的名称
使用名词、名词短语或形容词作为属性的名称。名词短语或形容词适合于属性,因为属性保存数据。
不要使用与 Get 方法同名的属性。
例如,不要将一个属性命名为 EmployeeRecord,又将一个方法命名为 GetEmployeeRecord。开发人员会不知道使用哪个成员来完成其编程任务。
使用肯定性短语作为布尔值属性的名称(如使用 CanSeek 而不使用 CantSeek)。
此外,还可以为布尔值属性添加前缀(如 Is、Can 或 Has),但要注意使用得当。
考虑为属性提供与其类型相同的名称。
如果某个属性已强类型化为某个枚举,则该属性可与该枚举同名。
例如,如果有一个名为 CacheLevel 的枚举,则返回其中一个枚举值的属性也可以命名为 CacheLevel。
事件的名称
使用动词或动词短语作为事件的名称。
在为事件命名时,使用现在时或过去时表示时间上的前后概念。
例如,在窗口关闭之前引发的关闭事件可命名为“Closing”,在窗口关闭之后引发的关闭事件可命名为“Closed”。
不要使用“Before”或“After”作为前缀或后缀来指示之前和之后发生的事件。
使用后缀 EventHandler 命名事件处理程序(用作事件类型的委托)。
在事件处理程序签名中使用命名为“sender”和“e”的两个参数。
sender 参数的类型应为 Object,e 参数应是 EventArgs 的实例或继承自 EventArgs 的实例。
使用 EventArgs 后缀命名事件参数类。
字段的名称
字段的命名准则适用于静态公共字段和静态受保护字段。不要定义公共实例字段或受保护实例字段。有关更多信息,请参见字段设计。
在字段名称中使用 Pascal 大小写格式。
使用名词或名词短语作为字段的名称。
使用m_前缀和s_前缀分别表示非静态字段和静态字段。(注意:这一点在.NET编码规范中是不推荐的)
8. 参数名称
选择适当的参数名称可极大改善库的可用性。适当的参数名称应指示该参数会影响的数据或功能。
对参数名称使用 Camel 大小写。
使用描述性参数名称。在大多数情况下,参数名称及其类型应足以确定参数的用法。考虑使用反映参数含义的名称而不是反映参数类型的名称。
在开发人员工具和文档中,参数的类型通常都是可见的。
9.资源的名称
本主题中准则适用于可本地化的资源,如错误信息和菜单文本。
在资源键中使用 Pascal 大小写格式。
提供描述性标识符,而不要提供短标识符。尽量保持标识符的简洁性,但不要牺牲可读性。
不要使用公共语言运行库 (CLR) 编程语言中特定于语言的关键字。
在命名资源中只能使用字母数字字符和下划线。
使用点分隔符(“.”)以清晰的层次结构表示标识符。
例如,Menus.FileMenu.Close.Text 和 Menus.FileMenu.Close.Color 等名称符合此准则。
对异常消息资源使用下面的命名约定。资源标识符应由异常类型名称加上异常的短标识符构成,二者之间以点分隔。
例如,ArgumentException.BadEnumValue 符合此准则。