程式碼命名規範
阿新 • • 發佈:2019-02-01
詞語選擇
避免使用由經常使用的名稱空間複製的型別名。型別名不能使用下列詞語。
System Collections Forms UI
避免使用與常用關鍵詞衝突的識別符號。例如,避免使用下列詞語。
識別符號(包括引數名)中不要使用縮寫。
如果必須使用縮寫:
任何超過兩個字元以上的縮寫都使用camel大寫格式,即使這不是標準縮寫。
名稱空間
命名名稱空間的一般規則如下:
CompanyName.TechnologyName
這樣,我們看到的名稱空間應該是這樣的:
Microsoft.Office
PowerSoft.PowerBuilder
注意:這只是一個原則。第三方公司可以選擇其它的名字。
避免用公司名稱或其它著名品牌的名稱作為名稱空間的字首,這樣會造成兩個公佈的名稱空間有同一個名稱的可能性。(例如,將微軟提供的Office自動類命名為Microsoft.Office。)
使用Pascal大寫方式,用逗號分隔邏輯成分(例如,Microsoft.Office.PowerPoint)。如果你的品牌使用的是非傳統大寫方式,那麼一定要遵循你的品牌所確定使用的大寫方式,即使這種方式背離了通常的名稱空間大寫規則(例如,NeXT.WebObjects,和ee.cummings。)
該用複數的時候要使用複數的名稱空間名。例如,使用System.Collections而不是System.Collection。本規則的特例是品牌名稱和縮寫。例如:使用System.IO而不是System.IOs。
名稱空間和類不能使用同樣的名字。例如,有一個類被命名為Debug後,就不要再使用Debug作為一個名稱空間名。
類和類成分
類的命名原則
用名詞或名詞短語命名類。
使用Pascal大寫。
減少類名中縮寫的使用量。
不要使用任何類字首(比如C)。
不要使用帶下劃線的字元。
下面是一些正確命名的類名的例子。
public class FileStream {
}
public class Button {
}
public class String {
}
介面命名原則
使用名詞或名詞短語,或者描述行為的形容詞來命名介面。例如,IComponent(描述性名詞),ICustomAttributeProvider(名詞短語),和IPersistable(形容詞)。
使用Pascal大寫。
減少介面名中縮寫的使用量。
不要使用帶下劃線的字元。
在介面名前加字首I,以表示這個型別是一個介面。
不要在類名前加上字首C。偶而情況下,需要在類名前加上I而並不表示它是一個介面。在這種情況下,只要I後面的字元是小寫就可(例如,IdentityStore。)
當類是介面的標準執行時,定義這一對類/介面組合就要使用相似的名稱。兩個名稱的不同之處只是介面名前有一個I字首。
下面我們舉個例子,來看看介面IComponent和它的標準執行,類Component。
public interface IComponent {
}
public class Component : IComponent {
}
public interface IServiceProvider{
}
public interface IFormatable {
}
屬性命名原則
在屬性的後面加上Attribute字尾,來自定義屬性類。如下例所示。
public class ObsoleteAttribute{
}
Enum命名原則
Enum需使用Pascal大寫。
Enum值名需使用Pascal大寫。
減少enum名中縮寫的使用量。
Enum名前不要加字首(例如,adxxx表示ADO enums,rtfxxx表示多資訊文字enum,等等。)。
在enum型別上不要加Enum字尾。
Enum名稱需使用單數名詞。
位元域使用複數名詞。
如果列舉值在引數或屬性中使用,需用一個enum來定義列舉值。這樣工具就可以知道一個屬性或引數可能的值了。
public enum FileMode{
Create,
CreateNew,
Open,
OpenOrCreate,
Truncate
}
如果數字值to be bitwise or'ed together,就使用Flags對屬性進行自定義。
[Flags]
public enum Bindings {
CreateInstance,
DefaultBinding,
ExcatBinding,
GetField,
GetProperty,
IgnoreCase,
InvokeMethod,
NonPublic,
OABinding,
SetField
SetProperty,
Static
}
在封裝一個Win32 API時,這個規則有一個特例。從一個Win32標頭產生內部定義是很常見的。你可以使用Win32大寫,這種形式下字母通常全部大寫。
使用Int32作為一個enum的基礎型別。
如果這個enum代表標誌,而且標誌又非常多(大於32),或者這個enum在將來可以發展成許多標誌,或者型別需要與型別int有所不同以便向後相容時,在這種情況下就產生了特例。
只有在值可以被完全表示為一組位標誌時,才使用enum。開集不能使用enum(例如作業系統版,等等)。
只讀和Const欄位名
用名詞,名詞短語,或名詞的縮寫命名靜態欄位。
用Pascal大寫命名靜態欄位。
不要用匈牙利文型別的符號作靜態欄位名的字首。
引數名
使用描述性引數名。引數名應該具有足夠的描述性,這樣在大多數情況下引數名和它的種類可以用來確定它的意思。
用camel大寫方式命名引數。
根據引數的意思來命名引數,而不是根據引數的種類來命名。我們希望開發工具可以用很方便的方式提供關於引數種類的資訊,這樣引數名可以得到更好的使用,可以對語義而不是對種類進行描述。但是偶爾使用根據型別命名的引數名也是完全可以的。
不要使用保留引數。如果在下一個版本中需要更多的資料,可以增加進來。
不要用匈牙利文型別的符號作為欄位名的字首。
Type GetType (string typeName)
string Format (string format, object [] args)
方法命名原則
用動詞或動詞短語命名方法。
用下述範例所示的Pascal大寫方式命名方法。
RemoveAll()
GetCharArray()
Invoke()
屬性命名原則
用名詞或名詞短語命名屬性。
用Pascal大寫命名屬性。
屬性與型別要一樣。
用與一個型別的名稱相同的名字來命名屬性時,就使這個屬性的型別成為那個型別。雖然聽起來有些奇怪,但這是正確的。下面的例子正確使用了屬性命名原則。
public enum Color {...}
public class Control {
public Color Color { get {...} set {...} }
}
下例就是不正確的。
public enum Color {...}
public class Control {
public int Color { get {...} set {...} }
}
在那個不正確的例子中,要想引用Color enum是不可能的,因為Color,Xxx會被翻譯成一個成員訪問,它會首先獲得Color屬性的值(int種類),然後再訪問那個值的成員(它應該是System.Int32的一個例項成員)。
事件命名原則
用EventHandloer字尾命名事件處理程式,如下列所示。
public delegate void MouseEventHandler(object sender, MouseEvent e);
使用名為sender和e的兩個引數。
Sender引數代表提出事件的物件。Sender引數永遠是一個型別物件,即使它可能使用了更為特定的型別。
與事件相關的狀態被封裝在一個名為e的事件類範例中。要使用這個型別的正確的、特定的事件類。
public delegate void MouseEventHandler(object sender, MouseEvent e);
用EventArgs字尾命名事件自變數類,如下例所示。
public class MouseEventArgs : EventArgs {
int x;
int y;
public MouseEventArgs(int x, int y)
{ this.x = x; this.y = y; }
public int X { get { return x; } }
public int Y { get { return y; } }
}
命名事件名時,需要有之前和之後的時態概念,因此要使用現在時態和過去時態(不要使用BeforeXxx/AfterXxx的方式)。例如,可以被取消的結束事件就有Closing事件和Closed事件。
public event ControlEventHandler ControlAdded {
//..
}
用動詞命名事件。
區分大小寫
不要使用需要對大小寫作出區分的名稱。各成分不論是在區分大小寫還是不區分大小寫的語言下都必須是完全可用的。因為不區分大小寫的語言不能在同樣的環境下對只有大小寫不同的兩個名稱作出辯別,所以成分必須避免這種情況。
不要產生兩個名稱相同只有大小寫不同的名稱空間。
namespace ee.cummings;
namespace Ee.Cummings;
帶有兩個引數的一個型別,其兩個引數的名稱不能只有大小寫不同。
void foo(string a, string A)
System.WinForms.Point p;
System.WinForms.POINT pp;
帶有兩個屬性的一個型別,其屬性的名稱不能只有大小寫不同。
int Foo {get, set};
int FOO {get, set}
帶有兩種方法的一個型別,其方法的名稱不能只有大小寫不同。
void foo();
void Foo();
避免型別名出現混淆
不同的語言使用不同的術語以識別基本管理型別。設計人員必須避免使用對語言有專門要求的術語。遵照本章說明的規則,避免出現型別名稱混淆的情況。
使用語義上有意義的名稱,而不要使用型別名稱。
在很少見的情況下,引數除了型別以外語義上沒有任何意義,這時使用類屬名。例如,一個類支援將多種資料型別寫進一個流中,這個類可能有下列方法:
void Write(double value);
void Write(float value);
void Write(long value);
void Write(int value);
void Write(short value);
上面的例子在下述對語言有專門要求的情況下是首選。
void Write(double doubleValue);
void Write(float floatValue);
void Write(long longValue);
void Write(int intValue);
void Write(short shortValue);
在極端情況下,每一個基本資料型別需要有唯一的命名方式,此時使用下面的通用型別名稱。
一個支援從流中讀取多種資料型別的類可以有下列方法。
double ReadDouble();
float ReadSingle();
long ReadIn64();
int ReadInt32();
short ReadInt16();
上面的例子在下述對語言有專門要求的情況下是首選。
double ReadDouble();
float ReadFloat();
long ReadLong();
int ReadInt();
short ReadShort();
避免使用由經常使用的名稱空間複製的型別名。型別名不能使用下列詞語。
System Collections Forms UI
避免使用與常用關鍵詞衝突的識別符號。例如,避免使用下列詞語。
AddHandler |
AddressOf |
Alias |
And |
Ansi |
As |
Assembly |
Auto |
BitAnd |
BitNot |
BitOr |
BitXor |
Boolean |
ByRef |
Byte |
ByVal |
Call |
Case |
Catch |
CBool |
CByte |
CChar |
CDate |
CDec |
CDbl |
Char |
CInt |
Class |
CLng |
CObj |
Const |
CShort |
CSng |
CStr |
CType |
Date |
Decimal |
Declare |
Default |
Delegate |
Dim |
Do |
Double |
Each |
Else |
ElseIf |
End |
Enum |
Erase |
Error |
Event |
Exit |
ExternalSource |
False |
Finally |
For |
Friend |
Function |
Get |
GetType |
Goto |
Handles |
If |
Implements |
Imports |
In |
Inherits |
Integer |
Interface |
Is |
Let |
Lib |
Like |
Long |
Loop |
Me |
Mod |
Module |
MustInherit |
MustOverride |
MyBase |
MyClass |
Namespace |
New |
Next |
Not |
Nothing |
NotInheritable |
NotOverridable |
Object |
On |
Option |
Optional |
Or |
Overloads |
Overridable |
Overrides |
ParamArray |
Preserve |
Private |
Property |
Protected |
Public |
RaiseEvent |
ReadOnly |
ReDim |
Region |
REM |
RemoveHandler |
Resume |
Return |
Select |
Set |
Shadows |
Shared |
Short |
Single |
Static |
Step |
Stop |
String |
Structure |
Sub |
SyncLock |
Then |
Throw |
To |
True |
Try |
TypeOf |
Unicode |
Until |
Variant |
When |
While |
With |
WithEvents |
WriteOnly |
Xor |
eval |
extends |
instanceof |
package |
var |
識別符號(包括引數名)中不要使用縮寫。
如果必須使用縮寫:
任何超過兩個字元以上的縮寫都使用camel大寫格式,即使這不是標準縮寫。
名稱空間
命名名稱空間的一般規則如下:
CompanyName.TechnologyName
這樣,我們看到的名稱空間應該是這樣的:
Microsoft.Office
PowerSoft.PowerBuilder
注意:這只是一個原則。第三方公司可以選擇其它的名字。
避免用公司名稱或其它著名品牌的名稱作為名稱空間的字首,這樣會造成兩個公佈的名稱空間有同一個名稱的可能性。(例如,將微軟提供的Office自動類命名為Microsoft.Office。)
使用Pascal大寫方式,用逗號分隔邏輯成分(例如,Microsoft.Office.PowerPoint)。如果你的品牌使用的是非傳統大寫方式,那麼一定要遵循你的品牌所確定使用的大寫方式,即使這種方式背離了通常的名稱空間大寫規則(例如,NeXT.WebObjects,和ee.cummings。)
該用複數的時候要使用複數的名稱空間名。例如,使用System.Collections而不是System.Collection。本規則的特例是品牌名稱和縮寫。例如:使用System.IO而不是System.IOs。
名稱空間和類不能使用同樣的名字。例如,有一個類被命名為Debug後,就不要再使用Debug作為一個名稱空間名。
類和類成分
類的命名原則
用名詞或名詞短語命名類。
使用Pascal大寫。
減少類名中縮寫的使用量。
不要使用任何類字首(比如C)。
不要使用帶下劃線的字元。
下面是一些正確命名的類名的例子。
public class FileStream {
}
public class Button {
}
public class String {
}
介面命名原則
使用名詞或名詞短語,或者描述行為的形容詞來命名介面。例如,IComponent(描述性名詞),ICustomAttributeProvider(名詞短語),和IPersistable(形容詞)。
使用Pascal大寫。
減少介面名中縮寫的使用量。
不要使用帶下劃線的字元。
在介面名前加字首I,以表示這個型別是一個介面。
不要在類名前加上字首C。偶而情況下,需要在類名前加上I而並不表示它是一個介面。在這種情況下,只要I後面的字元是小寫就可(例如,IdentityStore。)
當類是介面的標準執行時,定義這一對類/介面組合就要使用相似的名稱。兩個名稱的不同之處只是介面名前有一個I字首。
下面我們舉個例子,來看看介面IComponent和它的標準執行,類Component。
public interface IComponent {
}
public class Component : IComponent {
}
public interface IServiceProvider{
}
public interface IFormatable {
}
屬性命名原則
在屬性的後面加上Attribute字尾,來自定義屬性類。如下例所示。
public class ObsoleteAttribute{
}
Enum命名原則
Enum需使用Pascal大寫。
Enum值名需使用Pascal大寫。
減少enum名中縮寫的使用量。
Enum名前不要加字首(例如,adxxx表示ADO enums,rtfxxx表示多資訊文字enum,等等。)。
在enum型別上不要加Enum字尾。
Enum名稱需使用單數名詞。
位元域使用複數名詞。
如果列舉值在引數或屬性中使用,需用一個enum來定義列舉值。這樣工具就可以知道一個屬性或引數可能的值了。
public enum FileMode{
Create,
CreateNew,
Open,
OpenOrCreate,
Truncate
}
如果數字值to be bitwise or'ed together,就使用Flags對屬性進行自定義。
[Flags]
public enum Bindings {
CreateInstance,
DefaultBinding,
ExcatBinding,
GetField,
GetProperty,
IgnoreCase,
InvokeMethod,
NonPublic,
OABinding,
SetField
SetProperty,
Static
}
在封裝一個Win32 API時,這個規則有一個特例。從一個Win32標頭產生內部定義是很常見的。你可以使用Win32大寫,這種形式下字母通常全部大寫。
使用Int32作為一個enum的基礎型別。
如果這個enum代表標誌,而且標誌又非常多(大於32),或者這個enum在將來可以發展成許多標誌,或者型別需要與型別int有所不同以便向後相容時,在這種情況下就產生了特例。
只有在值可以被完全表示為一組位標誌時,才使用enum。開集不能使用enum(例如作業系統版,等等)。
只讀和Const欄位名
用名詞,名詞短語,或名詞的縮寫命名靜態欄位。
用Pascal大寫命名靜態欄位。
不要用匈牙利文型別的符號作靜態欄位名的字首。
引數名
使用描述性引數名。引數名應該具有足夠的描述性,這樣在大多數情況下引數名和它的種類可以用來確定它的意思。
用camel大寫方式命名引數。
根據引數的意思來命名引數,而不是根據引數的種類來命名。我們希望開發工具可以用很方便的方式提供關於引數種類的資訊,這樣引數名可以得到更好的使用,可以對語義而不是對種類進行描述。但是偶爾使用根據型別命名的引數名也是完全可以的。
不要使用保留引數。如果在下一個版本中需要更多的資料,可以增加進來。
不要用匈牙利文型別的符號作為欄位名的字首。
Type GetType (string typeName)
string Format (string format, object [] args)
方法命名原則
用動詞或動詞短語命名方法。
用下述範例所示的Pascal大寫方式命名方法。
RemoveAll()
GetCharArray()
Invoke()
屬性命名原則
用名詞或名詞短語命名屬性。
用Pascal大寫命名屬性。
屬性與型別要一樣。
用與一個型別的名稱相同的名字來命名屬性時,就使這個屬性的型別成為那個型別。雖然聽起來有些奇怪,但這是正確的。下面的例子正確使用了屬性命名原則。
public enum Color {...}
public class Control {
public Color Color { get {...} set {...} }
}
下例就是不正確的。
public enum Color {...}
public class Control {
public int Color { get {...} set {...} }
}
在那個不正確的例子中,要想引用Color enum是不可能的,因為Color,Xxx會被翻譯成一個成員訪問,它會首先獲得Color屬性的值(int種類),然後再訪問那個值的成員(它應該是System.Int32的一個例項成員)。
事件命名原則
用EventHandloer字尾命名事件處理程式,如下列所示。
public delegate void MouseEventHandler(object sender, MouseEvent e);
使用名為sender和e的兩個引數。
Sender引數代表提出事件的物件。Sender引數永遠是一個型別物件,即使它可能使用了更為特定的型別。
與事件相關的狀態被封裝在一個名為e的事件類範例中。要使用這個型別的正確的、特定的事件類。
public delegate void MouseEventHandler(object sender, MouseEvent e);
用EventArgs字尾命名事件自變數類,如下例所示。
public class MouseEventArgs : EventArgs {
int x;
int y;
public MouseEventArgs(int x, int y)
{ this.x = x; this.y = y; }
public int X { get { return x; } }
public int Y { get { return y; } }
}
命名事件名時,需要有之前和之後的時態概念,因此要使用現在時態和過去時態(不要使用BeforeXxx/AfterXxx的方式)。例如,可以被取消的結束事件就有Closing事件和Closed事件。
public event ControlEventHandler ControlAdded {
//..
}
用動詞命名事件。
區分大小寫
不要使用需要對大小寫作出區分的名稱。各成分不論是在區分大小寫還是不區分大小寫的語言下都必須是完全可用的。因為不區分大小寫的語言不能在同樣的環境下對只有大小寫不同的兩個名稱作出辯別,所以成分必須避免這種情況。
不要產生兩個名稱相同只有大小寫不同的名稱空間。
namespace ee.cummings;
namespace Ee.Cummings;
帶有兩個引數的一個型別,其兩個引數的名稱不能只有大小寫不同。
void foo(string a, string A)
System.WinForms.Point p;
System.WinForms.POINT pp;
帶有兩個屬性的一個型別,其屬性的名稱不能只有大小寫不同。
int Foo {get, set};
int FOO {get, set}
帶有兩種方法的一個型別,其方法的名稱不能只有大小寫不同。
void foo();
void Foo();
避免型別名出現混淆
不同的語言使用不同的術語以識別基本管理型別。設計人員必須避免使用對語言有專門要求的術語。遵照本章說明的規則,避免出現型別名稱混淆的情況。
使用語義上有意義的名稱,而不要使用型別名稱。
在很少見的情況下,引數除了型別以外語義上沒有任何意義,這時使用類屬名。例如,一個類支援將多種資料型別寫進一個流中,這個類可能有下列方法:
void Write(double value);
void Write(float value);
void Write(long value);
void Write(int value);
void Write(short value);
上面的例子在下述對語言有專門要求的情況下是首選。
void Write(double doubleValue);
void Write(float floatValue);
void Write(long longValue);
void Write(int intValue);
void Write(short shortValue);
在極端情況下,每一個基本資料型別需要有唯一的命名方式,此時使用下面的通用型別名稱。
C# type name |
Visual Basic type name |
JScript type name |
Visual C++ type name |
IL representation |
Universal type name |
sbyte |
SByte |
SByte |
char |
I1 |
SByte |
byte |
Byte |
byte |
unsigned char |
U1 |
Byte |
short |
Short |
short |
short |
I2 |
Int16 |
ushort |
UInt16 |
UInt16 |
unsigned short |
U2 |
UInt16 |
int |
Integer |
int |
int |
I4 |
Int32 |
uint |
NA |
NA |
unsigned int |
U4 |
UInt32 |
long |
Long |
long |
__int64 |
I8 |
Int64 |
ulong |
UInt64 |
UInt64 |
Unsigned __int64 |
U8 |
UInt64 |
float |
Single |
float |
float |
R4 |
Single |
double |
Double |
double |
double |
R8 |
Double |
bool |
Boolean |
boolean |
bool |
I4 |
Boolean |
char |
Char |
char |
wchar_t |
U2 |
Char |
string |
String |
String |
String |
System.String |
String |
object |
Object |
Object |
Object |
System.Object |
Object |
一個支援從流中讀取多種資料型別的類可以有下列方法。
double ReadDouble();
float ReadSingle();
long ReadIn64();
int ReadInt32();
short ReadInt16();
上面的例子在下述對語言有專門要求的情況下是首選。
double ReadDouble();
float ReadFloat();
long ReadLong();
int ReadInt();
short ReadShort();