前言
为统一公司内部程序员编码的规范性,特制定此编码规范,具体内容包括:
注释
- 文件头 每个单独的C#代码文件头注释
- 类、接口、属性及方法注释o 类、接口、属性及方法等的注释
- 代码注释 代码中注释
命名规则
- 大小写约定o 描述不同的大小写系统和每个系统的使用场合。
- 通用命名约定o 描述选择明确的可读名称的一般规则。
- 程序集和 DLL 的名称o 描述命名托管程序集的约定。
- 命名空间的名称o 描述用于命名空间名称的约定以及如何最小化命名空间之间的冲突。
- 类、结构和接口的名称o 描述命名类型时应遵循或避免的约定。
- 类型成员的名称o 描述为方法、属性、字段和事件选择名称的最佳做法。
- 参数名o 描述选择有含义的参数名称的最佳做法。
- 资源的名称o 描述为可本地化的资源选择名称的最佳做法。
4
注释
合理书写注释,可以使代码整洁、易读,并且可以帮助阅读者及自己理解代码。所以在此对注释规
范如下。
文件头
每个单独的代码文件(.cs文件)都应该有文件头,用以说明该文件的文件名、作用、作者及日期以及历史等信息,如下例:
//********************************************************************
//
// 文 件 名: Employee.cs
//
// 描 述: 表示一个雇员实体
//
// 作 者: Baiynui
//
//********************************************************************
类、接口、属性及方法等的注释
C# 提供一种机制,使程序员可以使用含有 XML 文本的特殊注释语法为他们的代码编写文档。在源代码文件中,具有某种格式的注释可用于指导某个工具根据这些注释和它们后面的源代码元素生成
XML。具体应用当中,类、接口、属性、方法必须有节,另外方法如果有参数及返回值,则必须有及节。如下列代码
///
/// Employee class
///
[ServiceContract]
public class Employee
{
///
/// Unique ID of the employee
///
private string _id;
///
/// set or get the _id
///
public string Id
5
{
get { return _id; }
set { _id = value; }
}
///
/// First Name of the employee
///
private string _firstName;
///
/// title of the employee
///
private string _title;
///
/// birth date of the employee
///
private DateTime _birthDate;
///
/// address of the employee
///
private string _address;
///
/// mobile number of the employee
///
private string _mobile;
///
/// phone number of the employee
///
private string _phone;
///
/// email of the employee
///
private string _email;
///
/// msn id of the employee
///
private string _msn;
///
/// set or get the first name
///
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
///
6
/// Last Name of the employee
///
private string _lastName;
///
/// set or get the last name
///
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
///
/// Display name of the employee
///
private string _displayName;
///
/// set or get the display name
///
public string DisplayName
{
get { return _displayName; }
set { _displayName = value; }
}
///
/// Constructor
///
public Employee()
{
this._id = "";
this._firstName = "";
this._lastName = "";
this._displayName = "";
this._title = "";
this._phone = "";
this._msn = "";
this._mobile = "";
this._email = "";
}//end method
/// constructor
/// id of employee
/// first name of employee
/// last name of employee
/// display name of employee
public Employee(string id, string firstName, string lastName, string displayName)
{
this._id = id;
this._firstName = firstName;
this._lastName = lastName;
this._displayName = displayName;
this._title = "";
7
this._phone = "";
this._msn = "";
this._mobile = "";
this._email = "";
}//end class
}//end class
代码中的注释
凡需要记忆或者具有复杂逻辑的代码段前应有注释。每个条件转向的条件前应加注释,以说明每
个条件,如下列代码:///
/// Generate employee id
///
/// employee type
/// employee id
public string GenerateID(int employeeType)
{
//generate employee id from employee type
string result = "";
switch (employeeType)
{
case 0: //first type
result += "First";
break;
case 1: //second type
result = "Second";
break;
case 2: //third type
result = "Third";
break;
default: //default
result = "";
break;
}
return result;
}//end method
命名规则
为保持代码的一致性及可维护性,公司内所有程序员应遵循一致的命名规则,具体描述如下。
大小写约定
8
大小写样式
下列术语描述了标识符的不同大小写形式。
PascalPascalPascalPascal大小写
将标识符的首字母和后面连接的每个单词的首字母都大写。可以对三字符或更多字符的标识符使用 Pascal 大小写。例如:
BackColor
大小写混合(骆驼命名法,Camel)
标识符的首字母小写,而每个后面连接的单词的首字母都大写。例如:
backColor
大写
标识符中的所有字母都大写。例如:
IO
标识符的大小写规则
如果标识符由多个单词组成,请不要在各单词之间使用分隔符,如下划线("_")或连字符("-")等。而应使用大小写来指示每个单词的开头。
下列准则是用于标识符的通用规则。
对于由多个单词组成的所有公共成员、类型及命名空间名称,要使用 PascalPascalPascalPascal大小写。
对参数名称使用大小写混合。
下表汇总了标识符的大小写规则,并提供了不同类型标识符的示例。
标识符 大小写方式 示例
类 Pascal AppDomain
枚举类型 Pascal ErrorLevel
枚举值 Pascal FatalError
事件 Pascal ValueChanged
异常类 Pascal WebException
只读的静态字段 Pascal RedValue
接口 Pascal IDisposable
方法 Pascal ToString
命名空间 Pascal System.Drawing
参数 Camel typeName
属性 Pascal BackColor
9
首字母缩写词的大小写规则
首字母缩写词是由术语或短语中各单词的首字母构成的单词。例如,HTML 是 HypertextMarkup Language 的首字母缩写。只有在公众广为认知和理解的情况下,才应在标识符中使用首字母缩写词。首字母缩写词不同于缩写词,因为缩写词是一个单词的缩写。例如,ID 是
identifier 的缩写。通常情况下,库名不应使用缩写词。
可在标识符中使用的两个缩写词是 ID 和 OK。在采用 Pascal 大小写格式的标识符中,这两个缩写词的大小写形式应分别为 Id 和 Ok。如果在采用大小写混合格式的标识符中将这两个缩写词用作首个单词,则它们的大小写形式应分别为 id 和 ok。
首字母缩写词的大小写取决于首字母缩写词的长度。所有首字母缩写词应至少包含两个字符。为了
便于这些准则的实施,如果某一首字母缩写词恰好包含两个字符,则将其视为短型首字母缩写词。
包含三个或三个以上字符的首字母缩写词为长型首字母缩写词。
下列准则为短型和长型首字母缩写词指定了正确的大小写规则。标识符大小写规则优先于首字母缩
写词大小写规则。
两字符首字母缩写词的两个字符都要大写,但当首字母缩写词作为大小写混合格式的标识符的首个
单词时例外。
例如,名为 DBRate 的属性是一个采用 Pascal 大小写格式的标识符,它使用短型首字母缩写词(DB) 作为首个单词。又如,名为 ioChannel 的参数是一个采用大小写混合格式的标识符,它使用短型首字母缩写词 (IO) 作为首个单词。
包含三个或三个以上字符的首字母缩写词只有第一个字符大写,但当首字母缩写词作为大小写混合
格式的标识符的首个单词时例外。
例如,名为 XmlWriter 的类是一个采用 Pascal 大小写格式的标识符,它使用长型首字母缩写词作为首个单词。又如,名为 htmlReader 的参数是一个采用大小写混合格式的标识符,它使用长型
首字母缩写词作为首个单词。
如果任何首字母缩写词位于采用大小写混合格式的标识符开头,则无论该首字母缩写词的长度如
何,都不大写其中的任何字符。
例如,名为 xmlStreamxmlStreamxmlStreamxmlStream 的参数是一个采用大小写混合格式的标识符,它使用长型首字母缩写词((((xmlxmlxmlxml)))) 作为首个单词。又如,名为 dbServerNamedbServerNamedbServerNamedbServerName 的参数是一个采用大小写混合格式的标识符,它使用短型首字母缩写词 ((((dbdbdbdb)))) 作为首个单词。
复合词和常用术语的大小写规则
不要将所谓的紧凑格式复合词中的每个单词都大写。这种复合词是指写作一个单词的复合词,如
""""endpointendpointendpointendpoint""""。例如,hashtable 是一个紧凑格式的复合词,应将其视为一个单词并相应地确定大小写。如果采
用 Pascal 大小写格式,则该复合词为 Hashtable;如果采用大小写混合格式,则该复合词为hashtable。若要确定某个单词是否是紧凑格式的复合词,请查阅最新的词典。
10
下表列出了不是紧凑格式复合词的一些常用术语。术语先以 Pascal 大小写格式显示,后面的括号中的是其大小写混合格式。
BitFlag (bitFlag)FileName (fileName)LogOff (logOff)LogOn (logOn)SignIn (signIn)SignOut (signOut)UserName (userName)WhiteSpace (whiteSpace)
通用命名约定
通用命名约定讨论的是如何为库元素选择最适当的名称。这些准则适用于所有标识符。后面各节讨论特定元素(如
命名空间或属性)的命名。
选择名称请选择易读的标识符名称。例如,英文属性名称 HorizontalAlignmentHorizontalAlignmentHorizontalAlignmentHorizontalAlignment比 AlignmentHorizontalAlignmentHorizontalAlignmentHorizontalAlignmentHorizontal更具可读性。
可读性比简洁性更重要。属性名称 CanScrollHorizontallyCanScrollHorizontallyCanScrollHorizontallyCanScrollHorizontally比 ScrollableXScrollableXScrollableXScrollableX(指 XXXX轴,但意义不明确)更好。
不要使用下划线、连字符或任何其他非字母数字字符(类的私有字段前以下划线开始)。
不要使用匈牙利表示法。
匈牙利表示法是在标识符中使用一个前缀对参数的某些元数据进行编码,如标识符的数据类型。
避免使用与常用编程语言的关键字冲突的标识符。
缩写和首字母缩写
通常,不应使用缩写或首字母缩写词。这类名称的可读性较差。同样,要确定某个首字母缩写词是
否已受到广泛认可也是很困难的。
不要将缩写或缩略形式用作标识符名称的组成部分。例如,使用 OnButtonClick 而不要使用 OnBtnClick。
除非必要,不要使用任何未被广泛接受的首字母缩写词。
语言特定的名称对于类型名称,应使用语义上有意义的名称而不要使用语言特定的关键字。例如,名称
GetLengthGetLengthGetLengthGetLength比 GetIntGetIntGetIntGetInt更好。在标识符的语义含义仅限于其类型的极少数情况下,应使用一般公共语言运行时 (CLR)(CLR)(CLR)(CLR)类型名称,而不要使用语言特定的名称。
例如,将数据转换为 Int16 的方法应命名为 ToInt16 而不是 ToShort,因为 ShortShortShortShort 是 Int16Int16Int16Int16 的语言特定的类型名称。
下表显示的是公共编程语言和 CLR 的相应语言特定的类型名称。
11
C#C#C#C#类型名称
VisualVisualVisualVisual BasicBasicBasicBasic类型名称
JScriptJScriptJScriptJScript类型名称
VisualVisualVisualVisual C++C++C++C++类型名称
Ilasm.exeIlasm.exeIlasm.exeIlasm.exe表示形式
CLRCLRCLRCLR类型名称
sbyte SByte sByte char int8 SByte
byte Byte byte unsigned char unsigned int8 Byte
short Short short short int16 Int16
ushort UInt16 ushort unsigned short unsigned int16 UInt16
int Integer int int int32 Int32
uint UInt32 uint unsigned int unsigned int32 UInt32
long Long long __int64 int64 Int64
ulong UInt64 ulong unsigned__int64
unsigned int64 UInt64
float Single float float float32 Single
double Double double double float64 Double
bool Boolean boolean bool bool Boolean
char Char char wchar_t char Char
string string string string string string
object Object object Object object Object
在标识符没有语义含义且参数的类型不重要的极少数情况下,应使用通用名称(如值或项),而不
要重复类型名称。
程序集和 DLL 的名称大多数情况下,程序集包含全部或部分可重用库,且它包含在单个动态链接库 (DLL) 中。一个程序集可拆分到多个 DLL 中,但这非常少见,在此准则中也没有说明。程序集和 DLL 是库的物理组织,而命名空间是逻辑组织,其构成应与程序集的组织无关。命名空间可以且经常跨越多个程序集。
考虑按下面的模式命名 DLLDLLDLLDLL:
..dll
其中 包含一个或多个以圆点分隔的子句。
命名空间名称
12
为命名空间选择的名称应指示命名空间中的类型所提供的功能。例如,System.Net.Sockets 命名空间包含的类型允许开发人员使用套接字通过网络进行通信。
命名空间名称的一般格式如下:
.(|)[.][.]
例如,Microsoft.WindowsMobile.DirectX。
不要根据组织层次结构确定命名空间层次结构中的名称,因为公司的部门名称经过一段时间后可能
会改变。
命名空间名称是长期使用的、不会更改的标识符。组织的不断发展和变化不应使命名空间名称过
时。
命名空间和类型的名称冲突如果选择的命名空间或类型的名称与现有名称冲突,则库的用户将不得不对受影响的项的引用进行
限定。在大多数开发情况中,都不应出现这种问题。
本节提供的某些准则适用于下面的命名空间类别:
应用程序模型命名空间
基础结构命名空间
核心命名空间
技术命名空间组
应用程序模型中的命名空间提供特定于应用程序中的某个类的功能集。例如,
System.Windows.Forms 命名空间中的类型提供编写 Windows 窗体客户端应用程序所需的功能。System.Web 命名空间中的类型支持编写基于 Web 的服务器应用程序。通常,在同一应用程序中不会使用不同应用程序模型中的命名空间,因此,这降低了名称冲突影响使用您的库的开发
人员的可能性。
基础结构应用程序提供专门的支持,很少在程序代码中进行引用。例如,程序开发工具所使用的
*.DesignerDesignerDesignerDesigner 命名空间中的类型。*.Permissions.Permissions.Permissions.Permissions 命名空间是基础结构命名空间的另一个示例。与基础结构命名空间中的类型的名称冲突不可能影响使用您的库的开发人员。
核心命名空间是 System.System.System.System.* 命名空间(不包括应用程序命名空间和基础结构命名空间)。System和 System.Text 都是核心命名空间的示例。应尽可能避免与核心命名空间中的类型发生名称冲突。
属于特定技术的命名空间将具有相同的第一和第二级标识符 (Company.technology.*)。应避免在技术命名空间中出现名称冲突。
应用程序命名空间准则
不要在单个应用程序模型内为命名空间中的多个类型指定相同的名称。
例如,如果要编写 Windows 窗体应用程序开发人员要使用的特殊控件库,则不应引入名为 Checkbox 的类型,因为该应用程序模型已存在同名类型 (CheckBox)。
核心命名空间准则
不要指定会与核心命名空间中的任何类型发生冲突的类型名称。
例如,不要使用 Directory 作为类型名称,因为这会与 Directory 类型冲突。
技术命名空间准则
13
不要引入会导致技术命名空间的类型与应用程序模型命名空间中的类型发生冲突的类型名称(除非
该技术不用于该应用程序模型)。
类、结构和接口的名称
通常,类型名称应该是名词短语,其中名词是由类型表示的实体。例如,Button、Stack 和 File都具有名称,用于标识由类型表示的实体。从开发人员的角度选择标识实体的名称;名称应反映使
用场合。
下面的准则适用于如何选择类型名称。
按照 PascalPascalPascalPascal大小写格式,使用名词或名词短语(或偶尔使用形容词短语)为类、接口和值类型命名。
不要为类名加前缀(如字母 CCCC)。接口不适用此规则,它应以字母 I 开头。
考虑在派生类的末尾使用基类名称。
例如,从 Stream 继承的 Framework 类型以 Stream 结尾,从 Exception 继承的类型以Exception 结尾。
为接口名称加上字母 IIII前缀,以指示该类型为接口。在定义类接口对(其中类是接口的标准实现)时,一定要确保类和接口的名称除接口名称以字母 IIII为前缀外,二者应完全相同。
例如,Framework 提供 IAsyncResult 接口和 AsyncResult 类。
泛型类型参数的名称泛型是 .NET Framework 2.0 版的主要新功能。下面的准则适用于为泛型类型参数选择正确的名称。
用描述性名称为泛型类型参数命名,除非单个字母的名称已完全可以自我说明而无需描述性名称。
IDictionary(TKey, TValue)是一个符合此准则的接口的示例。
对具有一个单字母类型参数的类型,考虑将字母 TTTT用作这些类型的类型参数名称。将字母 TTTT作为描述性类型参数名称的前缀。考虑在参数名称中指示置于类型参数上的约束。例如,可以将带有 ISessionISessionISessionISession约束的参数命名为TSessionTSessionTSessionTSession。
常见类型的名称下面的准则提供的命名约定有助于开发人员了解某些类的使用场合。准则中提及的从某个其他类型
继承的类型,指的是所有的继承者,而不只是直接继承的类型。例如,"向从 Exception 继承的类型添加 Exception 后缀"这一准则意味着在继承层次结构中具有 Exception 的任何类型都应该使用以 Exception 结尾的名称。
每条这样的准则还用来保留指定的后缀;除非类型满足该准则表述的条件,否则不应使用该后缀。
例如,如果类型不是从 Exception 直接或间接继承的,则类型名称不能以 Exception 结尾。
向自定义属性类添加 AttributeAttributeAttributeAttribute后缀。ObsoleteAttribute 和 AttributeUsageAttribute 是符合此准则的类型名称。
向在事件中使用的类型(如 C#C#C#C#事件的返回类型)的名称添加 EventHandlerEventHandlerEventHandlerEventHandler后缀。
14
AssemblyLoadEventHandler 是符合此准则的委托名称。
向不是事件处理程序的委托的名称添加 CallbackCallbackCallbackCallback后缀。
不要向委托添加 DelegateDelegateDelegateDelegate后缀。
向扩展 System.EventArgsSystem.EventArgsSystem.EventArgsSystem.EventArgs的类添加 EventArgsEventArgsEventArgsEventArgs后缀。
不要从 System.EnumSystem.EnumSystem.EnumSystem.Enum类派生;使用当前所用语言支持的关键字。例如,在 C#C#C#C#中应使用 enumenumenumenum关键字。
向从 System.ExceptionSystem.ExceptionSystem.ExceptionSystem.Exception继承的类型添加 ExceptionExceptionExceptionException后缀。
向实现 System.Collections.IDictionarySystem.Collections.IDictionarySystem.Collections.IDictionarySystem.Collections.IDictionary或 System.Collections.Generic.IDictionaryTValue>TValue>TValue>的类型添加 DictionaryDictionaryDictionaryDictionary后缀。注意,System.Collections.IDictionarySystem.Collections.IDictionarySystem.Collections.IDictionarySystem.Collections.IDictionary是特定类型的集合,但此准则的优先级高于以下更为一般的集合准则。
向实现 System.Collections.IEnumerableSystem.Collections.IEnumerableSystem.Collections.IEnumerableSystem.Collections.IEnumerable、System.Collections.ICollectionSystem.Collections.ICollectionSystem.Collections.ICollectionSystem.Collections.ICollection、System.Collections.IListSystem.Collections.IListSystem.Collections.IListSystem.Collections.IList、System.Collections.Generic.IEnumerableSystem.Collections.Generic.IEnumerableSystem.Collections.Generic.IEnumerableSystem.Collections.Generic.IEnumerable、System.Collections.Generic.ICollectionSystem.Collections.Generic.ICollectionSystem.Collections.Generic.ICollectionSystem.Collections.Generic.ICollection或 System.Collections.Generic.IListSystem.Collections.Generic.IListSystem.Collections.Generic.IListSystem.Collections.Generic.IList的类型添加 CollectionCollectionCollectionCollection后缀。
向从 System.IO.StreamSystem.IO.StreamSystem.IO.StreamSystem.IO.Stream继承的类型添加 StreamStreamStreamStream后缀。向从 System.Security.CodeAccessPermissionSystem.Security.CodeAccessPermissionSystem.Security.CodeAccessPermissionSystem.Security.CodeAccessPermission继承的类型或实现System.Security.IPermissionSystem.Security.IPermissionSystem.Security.IPermissionSystem.Security.IPermission的类型添加 PermissionPermissionPermissionPermission后缀。
枚举的名称不要在枚举值名称中使用前缀。例如,不要对 ADOADOADOADO枚举使用 adadadad之类的前缀,也不要对多格式文本枚举使用 rtfrtfrtfrtf之类的前缀,依此类推。
不要将 EnumEnumEnumEnum用作枚举类型的后缀。
不要在标志枚举的名称中添加 FlagsFlagsFlagsFlags作为后缀。
对枚举使用单数名称,除非枚举值是位域。
对使用位域值的枚举(也称为标志枚举)使用复数名称。
类型成员的命名
类型包含以下几种成员:
方法
属性
字段
事件
本节中的准则有助于类库设计者为成员选择与 .NET Framework 一致的名称。
15
方法的名称使用动词或动词短语作为方法的名称。
通常,方法对数据进行操作,因此,使用动词描述方法的操作可使开发人员更易于了解方法所执行
的操作。定义由方法执行的操作时,应从开发人员的角度仔细选择明确的名称。不要选择描述方法
如何执行其操作的动词,也就是说,不要使用实现细节作为方法名称。
属性的名称
使用名词、名词短语或形容词作为属性的名称。
名词短语或形容词适合于属性,因为属性保存数据。
不要使用与 GetGetGetGet方法同名的属性。例如,不要将一个属性命名为 EmployeeRecord,又将一个方法命名为 GetEmployeeRecord。开
发人员会不知道使用哪个成员来完成其编程任务。
考虑为属性提供与其类型相同的名称。
如果某个属性已强类型化为某个枚举,则该属性可与该枚举同名。例如,如果有一个名为
CacheLevel 的枚举,则返回其中一个枚举值的属性也可以命名为 CacheLevel。
事件的名称在事件处理程序签名中使用命名为""""sendersendersendersender""""和""""eeee""""的两个参数。sender 参数的类型应为 Object,e 参数应是 EventArgs 的实例或继承自 EventArgs 的实例。
字段的名称字段的命名准则适用于静态公共字段和静态受保护字段。不要定义公共实例字段或受保护实例字
段。
不要在字段名称中使用前缀。例如,不要使用 g_g_g_g_或 s_s_s_s_来区分静态字段和非静态字段。
参数名选择适当的参数名称可极大改善库的可用性。适当的参数名称应指示该参数会影响的数据或功能。
使用描述性参数名称。
在大多数情况下,参数名称及其类型应足以确定参数的用法。
考虑使用反映参数含义的名称而不是反映参数类型的名称。
在开发人员工具和文档中,参数的类型通常都是可见的。通过选择一个说明参数的用法或含义的名
称,可以向开发人员提供有价值的信息,帮助他们找到任务所需的成员,也有助于向成员传递正确
的数据。
资源的名称
16
本主题中准则适用于可本地化的资源,如错误信息和菜单文本。
使用点分隔符(""""...."""")以清晰的层次结构表示标识符。例如,Menus.FileMenu.Close.Text 和 Menus.FileMenu.Close.Color 等名称符合此准则。
对异常消息资源使用下面的命名约定。资源标识符应由异常类型名称加上异常的短标识符构成,二
者之间以点分隔。
例如,ArgumentException.BadEnumValue 符合此准则。
参考资料
MSDNMSDNMSDNMSDN
- 文档历史
- 前言
- 注释
- 文件头
- 类、接口、属性及方法等的注释
- 代码中的注释
- 命名规则
- 大小写约定
- 大小写样式
- 标识符的大小写规则
- 首字母缩写词的大小写规则
- 复合词和常用术语的大小写规则
- 通用命名约定
- 选择名称
- 缩写和首字母缩写
- 语言特定的名称
- 程序集和DLL的名称
- 命名空间名称
- 命名空间和类型的名称冲突
- 应用程序命名空间准则
- 类、结构和接口的名称
- 泛型类型参数的名称
- 常见类型的名称
- 枚举的名称
- 类型成员的命名
- 方法的名称
- 属性的名称
- 事件的名称
- 字段的名称
- 参数名
- 资源的名称
- 大小写约定
- 参考资料
![dc55504912e97feeaa0ad8b5eb55e80b.png](https://i-blog.csdnimg.cn/blog_migrate/c80fec2f8446213c05fbf776a4a80196.jpeg)
更多开发教程视频就关注查看
![4a01982863000b7e170aed34035e95a1.png](https://i-blog.csdnimg.cn/blog_migrate/334fbba4d6539fc17bbb10a3e10a6e23.jpeg)