.NET開發程式設計規範

章程式的版式

版式雖然不會影響程式的功能,但會影響可讀性。程式的版式追求清晰、美觀,是程式風格的重要構成因素。

可以把程式的版式比喻為"書法"。好的"書法"可讓人對程式一目瞭然,看得興致勃勃。差的程式"書法"如螃蟹爬行,讓人看得索然無味,更令維護者煩惱有加。

1.1 版本和版權宣告

版本和版權的宣告寫在檔案的開頭,包含內容如下:

、版權資訊

、摘要

、當前版本

、作者

、修改作者

、完成日期

、版本歷史資訊

例:

///<copyright> Copyright (c) 2006,有限公司</copyright>

///<copyright> All rights reserved.</copyright>

///<abstract>描述檔案的內容,實現的功能和演算法等內容</abstract>

///<current_version>當前版本</current_version>

///<author>作者</author>

///<finish_date>完成日期</finish_date>

///<replace_version>取代版本</replace_version>

///<modify>修改</modify>

///<modify_author>修改作者</modify_author>

///<modify_date>修改日期</modify_date>

版本版權宣告示例

在C#中程式碼註釋這樣寫的好處是Visual Stuidio能夠在編譯的時候自動生成xml格式的註釋文件。

1.2空行

空行起著分隔程式段落的作用。空行得體(不過多也不過少)將使程式的佈局更加清晰。空行不會浪費記憶體,雖然列印含有空行的程式是會多消耗一些紙張,但是值得。所以不要捨不得用空行。

在每個類宣告之後、每個函式定義結束之後都要加空行。參見示例1-2(a)在一個函式體內,邏揖上密切相關的語句之間不加空行,其它地方應加空行分隔。參見示例1-2(b )

// 空行

void Function1(…)

{

}

// 空行

void Function2(…)

{

}

// 空行

void Function3(…)

{

}

// 空行

while (condition)

{

statement1;

// 空行

if (condition)

{

statement2;

}

else

{

statement3;

}

// 空行

statement4;

}

示例1-2(a) 函式之間的空行                  示例1-2(b) 函式內部的空行

1.3 程式碼行

(1)一行程式碼只做一件事情,如只定義一個變數,或只寫一條語句。這樣的程式碼容易閱讀,並且方便於寫註釋。

(2)if、for、while、do等語句自佔一行,執行語句不得緊跟其後。不論執行語句有多少都要加{}。這樣可以防止書寫失誤。

示例1-3(a)為風格良好的程式碼行,示例1-3(b)為風格不良的程式碼行。

int width; // 寬度

int height; // 高度

int depth; // 深度

int width, height, depth;

// 寬度高度深度

x = a + b;

y = c + d;

z = e + f;

X = a + b;   y = c + d; z = e + f;

if (width < height)

{

dosomething();

}

if (width < height) dosomething();

for (initialization; condition; update)

{

dosomething();

}

// 空行

other();

for (initialization; condition; update)

dosomething();

other();

示例1-3(a) 風格良好的程式碼行                示例1-3(b) 風格不良的程式碼行

【建議】儘可能在定義變數的同時初始化該變數(就近原則)

如果變數的引用處和其定義處相隔比較遠,變數的初始化很容易被忘記。如果引用了未被初始化的變數,可能會導致程式錯誤。本建議可以減少隱患。例如

int width = 10;     // 定義並初紿化width

int height = 10;    // 定義並初紿化height

int depth = 10;     // 定義並初紿化depth

1.4 程式碼行內的空格

(1)關鍵字之後要留空格。象const、case 等關鍵字之後至少要留一個空格,否則無法辨析關鍵字。象if、for、while等關鍵字之後應留一個空格再跟左括號'(',以突出關鍵字。

(2)函式名之後不要留空格,緊跟左括號'(',以與關鍵字區別。

(3)'('向後緊跟,')'、','、';'向前緊跟,緊跟處不留空格。

(4)','之後要留空格,如Function(x, y, z)。如果';'不是一行的結束符號,其後要留空格,如for (initialization; condition; update)。

(5)賦值操作符、比較操作符、算術操作符、邏輯操作符、位域操作符,如"="、"+=" ">="、"<="、"+"、"*"、"%"、"&&"、"||"、"<<","^"等二元操作符的前後應當加空格。

(6)一元操作符如"!"、"~"、"++"、"--"、"&"(地址運算子)等前後不加空格。

(7)象"[]"、"."、"->"這類操作符前後不加空格。

(8)對於表示式比較長的for語句和if語句,為了緊湊起見可以適當地去掉一些空格,如for (i=0; i<10; i++)和if ((a<=b) && (c<=d))

示例1-4 程式碼行內的空格

void Func1(int x, int y, int z)

void Func1 (int x,int y,int z)

if (year >= 2000)

if(year>=2000)

if ((a>=b) && (c<=d))

if(a>=b&&c<=d)

for (i=0; i<10; i++)

for(i=0;i<10;i++)

x = a < b ? a : b;

x=a<b?a:b;

示例1-4(a) 風格良好的程式碼行                示例1-4(b) 風格不良的程式碼行

1.5 對齊

(1)程式的分界符'{'和'}'應獨佔一行並且位於同一列,同時與引用它們的語句左對齊。

(2){ }之內的程式碼塊在'{'右邊數格處左對齊。

void Function(int x)

{

… // program code

}

void Function(int x){

… // program code

}

if (condition)

{

… // program code

}

else

{

… // program code

}

if (condition){

… // program code

}

else {

… // program code

}

for (initialization; condition; update)

{

… // program code

}

for (initialization; condition; update){

… // program code

}

While (condition)

{

… // program code

}

while (condition){

… // program code

}

如果出現巢狀的{},則使用縮排對齊,如:

{

{

}

}

示例1-5(a) 風格良好的對齊                      示例1-5(b) 風格不良的對齊

1.6長行拆分

至80個字元以內。程式碼行不要過長,否則眼睛看不過來,也不便於列印。

長表示式要在低優先順序操作符處拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要進行適當的縮排,使排版整齊,語句可讀。

if ((very_longer_variable1 >= very_longer_variable12)

&& (very_longer_variable3 <= very_longer_variable14)

&& (very_longer_variable5 <= very_longer_variable16))

{

dosomething();

}

for (very_longer_initialization;

very_longer_condition;

very_longer_update)

{

dosomething();

}

示例1-6 長行的拆分

1.7 註釋

C#語言中,程式塊的註釋常採用"/*…*/",行註釋一般採用"//…"。註釋通常用於:

)版本、版權宣告;

)函式介面說明;

)重要的程式碼行或段落提示。

(4) 雖然註釋有助於理解程式碼,但注意不可過多地使用註釋。

(5)註釋是對程式碼的"提示",而不是文件。程式中的註釋不可喧賓奪主,註釋太多了會讓人眼花繚亂。註釋的花樣要少。

(6)如果程式碼本來就是清楚的,則不必加註釋。否則多此一舉,令人厭煩。例如

,多餘的註釋

(7)邊寫程式碼邊註釋,修改程式碼同時修改相應的註釋,以保證註釋與程式碼的一致性。不再有用的註釋要刪除。

(8)註釋應當準確、易懂,防止註釋有二義性。錯誤的註釋不但無益反而有害。

(9)儘量避免在註釋中使用縮寫,特別是不常用縮寫。

(10)註釋的位置應與被描述的程式碼相鄰,可以放在程式碼的上方或右方,不可放在下方。

(11)當代碼比較長,特別是有多重巢狀時,應當在一些段落的結束處加註釋,便於閱讀。

/*

* 函式介紹:

* 輸入引數:

* 輸出引數:

* 返回值 :

*/

void Function(float x, float y, float z)

{

}

if (…)

{

while (…)

{

} // end of while

} // end of if

示例1-7 程式的註釋

章命名規則

所有識別符號的命名必須遵循如下三種大小寫規範進行命名:

風格

說明

樣例

Pascal 大小寫

首字母大寫,且後續單詞的首字母都必須大寫;

本規則一般用於三個或更多字母的標識 的情況

BackColor

Camel 大小寫

首字母小寫且後續單詞的首字母都必須大寫

本規則僅用於函式引數和保護例項成員的命名

backColor

大寫格

所有字母都必須大寫

本規則僅用於標識只有兩個或更少字母的情況

System.IO

System.Web.UI

2.1   大小寫規則

大寫識別符號中的所有字母都大寫。僅對於由兩個或者更少字母組成的識別符號使用該約定。例如:

System.IO

System.Web.UI

下表彙總了大寫規則,並提供了不同型別的識別符號的示例。

識別符號

大小寫

示例

Pascal

AppDomain

列舉型別

Pascal

ErrorLevel

列舉值

Pascal

FatalError

事件

Pascal

ValueChange

異常類

Pascal

WebException

注意總是以 Exception 字尾結尾。

只讀的靜態欄位

Pascal

RedValue

介面

Pascal

IDisposable

注意總是以 I 字首開始。

方法

Pascal

ToString

名稱空間

Pascal

System.Drawing

屬性

Pascal

BackColor

公共例項欄位

Pascal

RedValue

注意很少使用。屬性優於使用公共例項欄位。

受保護的例項欄位

Camel

redValue

注意很少使用。屬性優於使用受保護的例項欄位。

私有的例項欄位

Camel

redValue

引數

Camel

typeName

方法內的變數

Camel

backColor

2.2縮寫

為了避免混淆和保證跨語言互動操作,請遵循有關區縮寫的使用的下列規則:

(1) 不要將縮寫或縮略形式用作識別符號名稱的組成部分。例如,使用 GetWindow,而不要使用 GetWin。

(2) 不要使用計算機領域中未被普遍接受的縮寫。

(3) 在適當的時候,使用眾所周知的縮寫替換冗長的片語名稱。例如,用 UI 作為 User Interface 縮寫,用 OLAP 作為 On-line Analytical Processing 的縮寫。

(4) 在使用縮寫時,對於超過兩個字元長度的縮寫請使用 Pascal 大小寫或 Camel 大寫。例如,使用 HtmlButton 或 HTMLButton。但是,應當大寫僅有兩個字元的縮寫,如,System.IO,而不是 System.Io。

(5) 不要在識別符號或引數名稱中使用縮寫。如果必須使用縮寫,對於由多於兩個字元所組成的縮寫請使用Camel 大小寫,雖然這和單詞的標準縮寫相沖突。

2.3名稱空間

(1) 命名名稱空間時的一般性規則是使用公司名稱,後跟技術名稱和可選的功能與設計,如下所示。

CompanyName.TechnologyName[.Feature][.Design]

例如:

namespace Langchao.Procurement

namespace Langchao.Procurement.DataRules

(2) 名稱空間使用Pascal大小寫,用逗號分隔開。

(3) TechnologyName 指的是該專案的英文縮寫,或軟體名。
(4) 名稱空間和類不能使用同樣的名字。例如,有一個類被命名為Debug後,就不要再

使用Debug作為一個名稱空間名。

2.4類

(1) 使用 Pascal 大小寫。

(2) 用名詞或名詞短語命名類。

(3) 使用全稱避免縮寫,除非縮寫已是一種公認的約定,如URL、HTML

(4)  不要使用型別字首。例如,使用類名稱 FileStream

(5) 不要使用下劃線字元 (_)。

(6) 有時候需要提供以字母 I 開始的類名稱,雖然該類不是介面。只要 I 是作為類名稱組成部分的整個單詞的第一個字母,這便是適當的。例如,類名稱 IdentityStore 是適當的。在適當的地方,使用複合單詞命名派生的類。派生類名稱的第二個部分應當是基類的名稱。例如,ApplicationException 對於從名為 Exception 的類派生的類是適當的名稱,原因ApplicationException 是一種Exception。請在應用該規則時進行合理的判斷。例如,Button 對於從 Control 派生的類是適當的名稱。儘管按鈕是一種控制元件,但是將 Control 作為類名稱的一部分將使名稱不必要地加長。

public class FileStream

public class Button

public class String

2.5介面

以下規則概述介面的命名指南:

(1) 用名詞或名詞短語,或者描述行為的形容詞命名介面。例如,介面名稱 IComponent 使用描述性名詞。介面名稱 ICustomAttributeProvider 使用名詞短語。名稱 IPersistable 使用形容詞。

(2) 使用 Pascal 大小寫。

(3) 少用縮寫。

(4) 給介面名稱加上字母 I 字首,以指示該型別為介面。在定義類/介面對(其中類是介面的標準實現)時使用相似的名稱。兩個名稱的區別應該只是介面名稱上有字母 I 字首。

(5) 不要使用下劃線字元 (_)。

(6) 當類是介面的標準執行時,定義這一對類/介面組合就要使用相似的名稱。兩個名稱的不同之處只是介面名前有一個I字首。

以下是正確命名的介面的示例。

public interface IServiceProvider

public interface IFormatable

以下程式碼示例闡釋如何定義 IComponent 介面及其標準實現 Component 類。

public interface IComponent

{

// Implementation code goes here.

}

public class Component: IComponent

{

// Implementation code goes here.

}

2.6屬性 (Attribute)

應該總是將字尾 Attribute 新增到自定義屬性類。以下是正確命名的屬性類的示例。

public class ObsoleteAttribute

{

}

2.7列舉 (Enum)

列舉 (Enum) 值型別從 Enum 類繼承。以下規則概述列舉的命名指南:

(1) 對於 Enum 型別和值名稱使用 Pascal 大小寫。

(2) 少用縮寫。

(3) 不要在 Enum 型別名稱上使用 Enum 字尾。

(4) 對大多數 Enum 型別使用單數名稱,但是對作為位域的 Enum 型別使用複數名稱。

(5) 總是將 FlagsAttribute 新增到位域 Enum 型別。

2.8引數

以下規則概述引數的命名指南:

(1) 使用描述性引數名稱。引數名稱應當具有足夠的描述性,以便引數的名稱及其型別

可用於在大多數情況下確定它的含義。

(2) 對引數名稱使用 Camel 大小寫。

(3) 使用描述引數的含義的名稱,而不要使用描述引數的型別的名稱。開發工具將提

供有關引數的型別的有意義的資訊。因此,通過描述意義,可以更好地使用參

數的名稱。少用基於型別的引數名稱,僅在適合使用它們的地方使用它們。

(4) 不要使用保留的引數。保留的引數是專用引數,如果需要,可以在未來的版本中公

開它們。相反,如果在類庫的未來版本中需要更多的資料,請為方法新增新的過載。

(5) 不要給引數名稱加匈牙利語型別表示法的字首。

以下是正確命名的引數的示例。

Type GetType(string typeName)

string Format(string format, args() As object)

2.9方法

以下規則概述方法的命名指南:

(1) 使用動詞或動詞短語命名方法。

(2) 使用 Pascal 大小寫。

(3) 以下是正確命名的方法的例項。

RemoveAll()

GetCharArray()

Invoke()

2.10 屬性 (property)

以下規則概述屬性的命名指南:

(1) 使用名詞或名詞短語命名屬性。

(2) 使用 Pascal 大小寫。

(3) 不要使用匈牙利語表示法。

(4) 考慮用與屬性的基礎型別相同的名稱建立屬性。例如,如果宣告名為 Color 的屬性,則屬性的型別同樣應該是 Color。請參閱本主題中後面的示例。

以下程式碼示例闡釋正確的屬性命名。

public class SampleClass

{

public Color BackColor

{

// Code for Get and Set accessors goes here.

}

}

以下程式碼示例闡釋提供其名稱與型別相同的屬性。

public enum Color

{

// Insert code for Enum here.

}

public class Control

{

public Color Color

{

get

{

// Insert code here.

}

set

{

// Insert code here.

}

}

}

以下程式碼示例不正確,原因是 Color 屬性是 Integer 型別的。

public enum Color

{

// Insert code for Enum here.

}

public class Control

{

public int Color

{

// Insert code here

}

}

在不正確的示例中,不可能引用 Color 列舉的成員。Color.Xxx 將被解釋為訪問一個成員,

該成員首先獲取 Color 屬性( C# 中為 int 型別)的值,然後再訪問該值的某個成員(該成

員必須是 System.Int32 的例項成員)。

2.11事件

以下規則概述事件的命名指南:

(1) 對事件處理程式名稱使用 EventHandler 字尾。

(2) 指定兩個名為 sender 和 e 的引數。sender 引數表示引發事件的物件。sender 引數始終是object 型別的,即使在可以使用更為特定的型別時也如此。與事件相關聯的狀態封裝在名為 e 的事件類的例項中。對 e 引數型別使用適當而特定的事件類。

(3) 用 EventArgs 字尾命名事件引數類。

(4) 考慮用動詞命名事件。

(5) 使用動名詞(動詞的"ing"形式)建立表示事件前的概念的事件名稱,用過去式表示事件後。例如,可以取消的 Close 事件應當具有 Closing 事件和 Closed 事件。不要使用BeforeXxx/AfterXxx 命名模式。

(6) 不要在型別的事件宣告上使用字首或者字尾。例如,使用 Close,而不要使用 OnClose。

(7) 通常情況下,對於可以在派生類中重寫的事件,應在型別上提供一個受保護的方法(稱為OnXxx)。此方法只應具有事件引數 e,因為傳送方總是型別的例項。

以下示例闡釋具有適當名稱和引數的事件處理程式。

public delegate void MouseEventHandler(object sender, MouseEventArgs e);

以下示例闡釋正確命名的事件引數類。

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;

}

}

}

2.12 常量 (const)

以下規則概述常量的命名指南:

所有單詞大寫,多個單詞之間用 "_" 隔開。如

public const string PAGE_TITLE = "Welcome";

2.13 欄位

以下規則概述欄位的命名指南:

(1) private、protected 使用 Camel 大小寫。

(2) public 使用 Pascal 大小寫。

(3) 拼寫出欄位名稱中使用的所有單詞。僅在開發人員一般都能理解時使用縮寫。欄位名稱不要使用大寫字母。下面是正確命名的欄位的示例。

class SampleClass

{

string url;

string destinationUrl;

}

(4) 不要對欄位名使用匈牙利語表示法。好的名稱描述語義,而非型別。

(5) 不要對欄位名或靜態欄位名應用字首。具體說來,不要對欄位名稱應用字首來區分靜態和非靜態欄位。例如,應用 g_ 或 s_ 字首是不正確的。

(6)對預定義物件例項使用公共靜態只讀欄位。如果存在物件的預定義例項,則將它們宣告為物件本身的公共靜態只讀欄位。使用 Pascal 大小寫,原因是欄位是公共的。下面的程式碼示例闡釋公共靜態只讀欄位的正確使用。

public struct Color

{

public static readonly Color Red = new Color(0x0000FF);

public Color(int rgb)

{

// Insert code here.}

public Color(byte r, byte g, byte b)

{

// Insert code here.

}

public byte RedValue

{

get

{

return Color;

}

}

}

2.14 靜態欄位

以下規則概述靜態欄位的命名指南:

(1) 使用名詞、名詞短語或者名詞的縮寫命名靜態欄位。

(2) 使用 Pascal 大小寫。

(3) 對靜態欄位名稱使用匈牙利語表示法字首。

(4) 建議儘可能使用靜態屬性而不是公共靜態欄位。

2.15 集合

集合是一組組合在一起的類似的型別化物件,如雜湊表、查詢、堆疊、字典和列表,集合的命名

建議用複數。

章表達式和基本語句

3.1 運算子的優先順序

C#語言的運算子有數十個,運算子的優先順序與結合律如表3-1所示。注意一元運算子 + - * 的優先順序高於對應的二元運算子。

優先順序

運算子

結合律

( ) [ ] -> .

從左至右

! ~ ++ -- (型別) sizeof

+ - * &

從右至左

 

* / %

從左至右

+ -

從左至右

<< >>

從左至右

<   <=   > >=

從左至右

== !=

從左至右

&

從左至右

^

從左至右

|

從左至右

&&

從左至右

||

從右至左

?:

從右至左

= += -= *= /= %= &= ^=

|= <<= >>=

從左至右

表3-1 運算子的優先順序與結合律

如果程式碼行中的運算子比較多,用括號確定表示式的操作順序,避免使用預設的優先順序。

為了防止產生歧義並提高可讀性,應當用括號確定表示式的操作順序。例如:

word = (high << 8) | low

if ((a | b) && (a & c))

3.2 複合表示式

)書寫簡潔;(2)可以提高編譯效率。但要防止濫用複合表示式。

(1)不要編寫太複雜的複合表示式。

例如:

i = a >= b && c < d && c + f <= g + h ; // 複合表示式過於複雜

(2)不要有多用途的複合表示式。

例如:

d = (a = b + c) + r ;

該表示式既求a值又求d值。應該拆分為兩個獨立的語句:

a = b + c;

d = a + r;

(3)不要把程式中的複合表示式與"真正的數學表示式"混淆。

例如:

if (a < b < c)          // a < b < c是數學表示式而不是程式表示式

並不表示

if ((a<b) && (b<c))

而是成了令人費解的

if ( (a<b)<c )

3.3 if 語句

if語句是c# 語言中最簡單、最常用的語句,然而很多程式設計師用隱含錯誤的方式寫if語句。本節以"與零值比較"為例,展開討論。

3.3.1 布林變數與零值比較

、0進行比較。

,而Visual Basic.net則將TRUE定義為-1。

假設布林變數名字為flag,它與零值比較的標準if語句如下:

if (flag)   // 表示flag為真

if (!flag) // 表示flag為假

其它的用法都屬於不良風格,例如:

if (flag == TRUE)

if (flag == 1 )

if (flag == FALSE)

if (flag == 0)

3.3.2 整型變數與零值比較

比較。

假設整型變數的名字為value,它與零值比較的標準if語句如下:

if (value == 0)

if (value != 0)

不可模仿布林變數的風格而寫成

if (value)      // 會讓人誤解 value是布林變數

if (!value)

3.3.3 浮點變數與零值比較

不可將浮點變數用"=="或"!="與任何數字比較。

千萬要留意,無論是float還是double型別的變數,都有精度限制。所以一定要避免將浮點變數用"=="或"!="與數字比較,應該設法轉化成">="或"<="形式。

假設浮點變數的名字為x,應當將

if (x == 0.0)    // 隱含錯誤的比較

轉化為

if ((x>=-EPSINON) && (x<=EPSINON))

其中EPSINON是允許的誤差(即精度)。

3.4 迴圈語句的效率

C# 迴圈語句中,for語句使用頻率最高,while語句其次,do語句很少用。提高迴圈體效率的基本辦法是降低迴圈體的複雜性。

(1)在多重迴圈中,如果有可能,應當將最長的迴圈放在最內層,最短的迴圈放在最外層,以減少CPU跨切迴圈層的次數。例如示例3-4(b)的效率比示例3-4(a)的高。

for (row=0; row<100; row++)

{

for ( col=0; col<5; col++ )

{

sum = sum + a[row][col];

}

}

for (col=0; col<5; col++ )

{

for (row=0; row<100; row++)

{

sum = sum + a[row][col];

}

}

示例3-4(a) 低效率:長迴圈在最外層           示例3-4(b) 高效率:長迴圈在最內層

(2) 如果迴圈體記憶體在邏輯判斷,並且迴圈次數很大,宜將邏輯判斷移到迴圈體的外面。示例3-4(c)的程式比示例3-4(d)多執行了N-1次邏輯判斷。並且由於前者老要進行邏輯判斷,打斷了迴圈"流水線"作業,使得編譯器不能對迴圈進行優化處理,降低了效率。如果N非常大,最好採用示例3-4(d)的寫法,可以提高效率。如果N非常小,兩者效率差別並不明顯,採用示例3-4(c)的寫法比較好,因為程式更加簡潔。

for (i=0; i<N; i++)

{

if (condition)

DoSomething();

else

DoOtherthing();

}

if (condition)

{

for (i=0; i<N; i++)

DoSomething();

}

else

{

for (i=0; i<N; i++)

DoOtherthing();

}

表3-4(c) 效率低但程式簡潔                表3-4(d) 效率高但程式不簡潔

3.5 for 語句的迴圈控制變數

(1)不可在for 迴圈體內修改迴圈變數,防止for 迴圈失去控制。

(2)建議for語句的迴圈控制變數的取值採用"半開半閉區間"寫法。

示例3-5(a)中的x值屬於半開半閉區間"0 =< x < N",起點到終點的間隔為N,迴圈次數為N。

示例3-5(b)中的x值屬於閉區間"0 =< x <= N-1",起點到終點的間隔為N-1,迴圈次數為N。

相比之下,示例3-5(a)的寫法更加直觀,儘管兩者的功能是相同的。

for (int x=0; x<N; x++)

{

}

for (int x=0; x<=N-1; x++)

{

}

示例3-5(a) 迴圈變數屬於半開半閉區間           示例3-5(b) 迴圈變數屬於閉區間

3.6 switch語句

switch是多分支選擇語句,而if語句只有兩個分支可供選擇。雖然可以用巢狀的if語句來實現多分支選擇,但那樣的程式冗長難讀。這是switch語句存在的理由。

switch語句的基本格式是:

switch (variable)

{

case value1 :  …

break;

case value2 :  …

break;

default : …

break;

}

(1)每個case語句的結尾不要忘了加break,否則將導致多個分支重疊(除非有意使多個分支重疊)。

(2)不要忘記最後那個default分支。即使程式真的不需要default處理,也應該保留語句 default : break; 這樣做並非多此一舉,而是為了防止別人誤以為你忘了default處理。

章 Asp.net設計規範

本介面設計規範適用於Asp.net開發的所有頁面。

5.1 頁首、頁尾和樣式表

在主視窗中顯示的所有頁面應該包含相同的頁首檔案、頁尾檔案和樣式表

在單獨視窗中顯示的頁面應該包含和主視窗頁面一致的樣式表

頁面元素的樣式應該在單獨的樣式表中定義,而非直接在頁面中定義各種屬性

5.2頁面標題

在單獨窗體中呈現的頁面應該定義<title>元素,title必須能夠表達介面的功能

5.3 視窗大小和位置

彈出的新視窗應在螢幕上處於居中位置,如top=200,left=300

頁面元素的寬度應儘量使用百分比而避免直接使用畫素值,應當保證頁面在800x600滿屏的視窗中顯示時不用橫向移動滾動條

5.4超連結

連結到系統內部頁面的超連結使用相對路徑

5.5按鈕

含義相同的按鈕名稱應保持一致,如"確定"、"取消"、"重置"、 "搜尋"、"高階搜尋"、"新建"、"刪除"、"更改"等

多於一個的按鈕並排擺放時順序(左右/上下)應保持一致,如"確定"應該在"取消"的左邊

5.6處理結果

每次處理都應該有相應的處理結果頁面或提示資訊,不管該處理是成功還是失敗

相同處理結果的用語應保持一致,如避免同時使用"失敗"和"沒有成功"這樣意義相同的詞語

5.7 操作確認

當用戶在進行一些諸如刪除,查封,匯入,匯出等會對系統造成影響的操作的時候,系統必須用確認框或者確認頁面來提醒使用者,並且讓使用者進行確認。

任何一個操作頁面,都必須提供給使用者取消操作,並且返回的功能。

5.8 資料驗證

各個功能頁面,系統都必須進行嚴格的資料驗證,包括長度,型別,是否合法等等

在asp.net中所有的資料驗證都使用validator控制元件在客戶端實現。

5.9控制元件使用

在asp.net中,dot net framework提供了WebControls和HtmlControls兩種控制元件,但是兩種控制元件有本質的區別,WebControls是伺服器端的控制元件,伺服器在執行的時候需要保留相應控制元件的狀態等資訊,HtmlControls是和Html相關的控制元件,使用原則如下

所有需要伺服器端進行事件響應的使用WebControl

無需伺服器端相響應的比如超連線,圖片等等儘量使用HtmlControls這樣可以提高效率,減少伺服器的負擔,減少網路傳輸的資料量。

5.10 檢視狀態

Asp.net中每個頁面物件在輸出html結束之後,頁面物件將會被垃圾回收執行緒給回收掉,為了儲存頁面中各個WebControls的狀態,系統會自動將各個WebControl裡面的資料,狀態等資訊儲存在ViewState中,這樣就極大地加大了檔案的大小,為了減少頁面下載的量,試圖狀態的使用原則如下:

在頁面中判斷Page.IsPostBack屬性,將少物件初始化的量。

將一些無需保留資料WebControls的EnableViewState改為false

5.11 異常處理

在各個模組的類庫中,如果有異常出現則首先將異常寫到日誌檔案中,同時將異常丟擲

在頁面上儘可能的將所有從封裝的類中丟擲來的異常抓起來,並且給使用者比較友好的提示

當出現非常嚴重的異常時將頁面重定向到errorpage中。

5.12 HTML頁面中需要注意的地方

去掉頁面中所有的<font>標籤,因為在html標準4.0的時候這個tag就已經不建議使用了。

為頁面新增正確的DOCTYPE,DOCTYPE是document type的簡寫。主要用來說明你用的XHTML或者HTML是什麼版本。

設定一個名稱空間,一個namespace是收集元素型別和屬性名字的一個詳細的DTD,namespace宣告允許你通過一個線上地址指向來識別你的namespace。

宣告編碼語言(<meta http-equiv="Content-Type" content="text/html; charset=GB2312" />)。

用小寫字母寫所有的標籤。

為圖片新增alt屬性。

給所有的屬性新增引號

關閉所有的標籤,及時是<br>也應該寫成<br />。

所有和顯示顯示相關的控制用css來控制。

給每一個表格或者表單賦予一個唯一的ID。

5.13 資料庫訪問

在頁面檔案中不要出現任何訪問資料庫的程式碼

訪問資料庫的方式,推薦方式2

,通過字串拼接來生成一個完整的SQL語句,如下

SqlConnection objDbConn = new SqlConnection("連結字串");

String strSql = "select * from TUSER_USERINFO where UserID=" + strUserID;

SqlCommand objCommand = new Command(strSql,objDbConn);

SqlDataReader objReader = objCommand.ExecuteReader();

缺陷:SQL Injection漏洞

,通過引數來實現

SqlConnection objDbConn = new SqlConnection("連結字串");

String strSql = "select * from TUSER_USERINFO where UserID=@UserID";

SqlCommand objCommand = new Command(strSql,objDbConn);

objCommand.Paramters.Add("@UserID",strUserID);

SqlDataReader objReader = objCommand.ExecuteReader();

系統將呼叫Ms SQLServer2000中的sp_executesql儲存過程來實現,能夠避免漏洞

章 javascript編寫規範

6.1 在什麼地方插入 JavaScript

一種方法,JavaScript 出現在 HTML 的head 部分,使用標記<script>…</script>。

另外一種插入 JavaScript 的方法,是把 JavaScript 程式碼寫到另一個檔案當中(此檔案通常應該用".js"作副檔名),然後用格式為"<script src="javascript.js"></script>"的標記把它嵌入到文件中。注意,一定要用"</script>"標記。

6.2 JavaScript 中的變數

變數的命名有以下要求:只包含字母、數字和/或下劃線;要以字母開頭;不能太長不能與 JavaScript 保留字(Key Words,Reserved Words,數量繁多,不能一一列出;凡是可以用來做 JavaScript 命令的字都是保留字)重複。而且,變數是區分大小寫的,例如,variable 和 Variable 是兩個不同的變數。不僅如此,大部分命令和"物件"(請參閱"物件化程式設計"章)都是區分大小寫的。

提示給變數命名,最好避免用單個字母"a""b""c"等,而改用能清楚表達該變數在程式中的作用的詞語。這樣,不僅別人能更容易的瞭解你的程式,而且你在以後要修改程式的時候,也很快會記得該變數的作用。變數名一般用小寫,如果是由多個單片語成的,那麼第一個單詞用小寫,其他單詞的第一個字母用大寫。例如:myVariable 和 myAnotherVariable。這樣做僅僅是為了美觀和易讀,因為 JavaScript 一些命令(以後將用更具體的方法闡述"命令"一詞)都是用這種方法命名的:indexOf;charAt 等等。

變數的賦值一個變數聲明後,可以在任何時候對其賦值。賦值的語法是:

<變數> = <表示式>;

其中"="叫"賦值符",它的作用是把右邊的值賦給左邊的變數。下一節將討論到表示式。

JavaScript常數有下列幾個:

null
一個特殊的空值。當變數未定義,或者定義之後沒有對其進行任何賦值操作,它的值就是"null"。企圖返回一個不存在的物件時也會出現null值。
NaN "Not a Number"。出現這個數值比較少見,以至於我們可以不理它。當運算無法返回正確的數值時,就會返回"NaN"值。NaN 值非常特殊,因為它"不是數字",所以任何數跟它都不相等,甚至 NaN 本身也不等於 NaN 。
true
布林值"真"。用通俗的說法,"對"。
false
布林值"假"。用通俗的說法,"錯"。

6.3語句

6.3.1 註釋

JavaScript 註釋有兩種:單行註釋和多行註釋。單行註釋用雙反斜槓"//"表示。當一行程式碼有"//",那麼,"//"後面的部分將被忽略。而多行註釋是用"/*"和"*/"括起來的一行到多行文字。程式執行到"/*"處,將忽略以後的所有文字,直到出現"*/"為止

6.3.2 if 語句

if ( <條件> ) <語句1> [ else <語句2> ];本語句有點象條件表示式"?:":當<條件>為真時執行<語句1>,否則,如果 else 部分存在的話,就執行<語句2>。與"?:"不同的是,if 只是一條語句,不會返回數值。<條件>是布林值,必須用小括號括起來;<語句1>和<語句2>都只能是一個語句,欲使用多條語句,請用語句塊。

if (a == 1)
  if (b == 0) alert(a+b);
else
  alert(a-b);

if (a == 1)

{
  if (b == 0) alert(a+b);
} else {
  alert(a-b);
}

示例風格不良的對齊                      示例風格良好的對齊

6.3.3 迴圈體

for (<變數>=<初始值>; <迴圈條件>; <變數累加方法>)<語句>;

提示適當的使用 for 迴圈,能使 HTML 文件中大量的有規律重複的部分簡化,也就是用 for 迴圈重複寫一些 HTML 程式碼,達到提高網頁下載速度的目的。不過請在 Netscape 中重複進行嚴格測試,保證通過了才好把網頁傳上去。作者曾試過多次因為用 for 迴圈向文件重複寫 HTML 程式碼而導致 Netscape"猝死"。IE 中絕對沒有這種事情發生,如果你的網也是隻給 IE 看的,用多多的 for 也沒問題。

6.3.4 switch 語句

如果要把某些資料分類,例如,要把學生的成績按優、良、中、差分類。我們可能會用 if 語句,但使用太多的 if 語句的話,程式看起來有點亂。switch 語句就是解決這種問題的最好方法。

switch (e)

{
  case r1: (注意:冒號)
    ...
    [break;]
  case r2:
    ...
    [break;]
  ...
  [default:
    ...]
}

ADO.NET命名規範

資料型別

資料型別簡寫

標準命名舉例

Connection

con

conNorthwind

Command

cmd

cmdReturnProducts

Parameter

parm

parmProductID

DataAdapter

dad

dadProducts

DataReader

dtr

dtrProducts

DataSet

dst

dstNorthWind

DataTable

dtbl

dtblProduct

DataRow

drow

drowRow98

DataColumn

dcol

dcolProductID

DataRelation

drel

drelMasterDetail

DataView

dvw

dvwFilteredProducts

WinForm Control 命名規範

資料型別

資料型別簡寫

標準命名舉例

Label

lbl

lblMessage

LinkLabel

llbl

llblToday

Button

btn

btnSave

TextBox

txt

txtName

MainMenu

mmnu

mmnuFile

CheckBox

chk

chkStock

RadioButton

rbtn

rbtnSelected

GroupBox

gbx

gbxMain

PictureBox

pic

picImage

Panel

pnl

pnlBody

DataGrid

dgrd

dgrdView

ListBox

lst

lstProducts

CheckedListBox

clst

clstChecked

ComboBox

cbo

cboMenu

ListView

lvw

lvwBrowser

TreeView

tvw

tvwType

TabControl

tctl

tctlSelected

DateTimePicker

dtp

dtpStartDate

HscrollBar

hsb

hsbImage

VscrollBar

vsb

vsbImage

Timer

tmr

tmrCount

ImageList

ilst

ilstImage

ToolBar

tlb

tlbManage

StatusBar

stb

stbFootPrint

OpenFileDialog

odlg

odlgFile

SaveFileDialog

sdlg

sdlgSave

FoldBrowserDialog

fbdlg

fgdlgBrowser

FontDialog

fdlg

fdlgFoot

ColorDialog

cdlg

cdlgColor

PrintDialog

pdlg

pdlgPrint

WebControl 命名規範

資料型別

資料型別簡寫

標準命名舉例

AdRotator

adrt

Example

Button

btn

btnSubmit

Calendar

cal

calMettingDates

CheckBox

chk

chkBlue

CheckBoxList

chkl

chklFavColors

CompareValidator

valc

valcValidAge

CustomValidator

valx

valxDBCheck

DataGrid

dgrd

dgrdTitles

DataList

dlst

dlstTitles

DropDownList

drop

dropCountries

HyperLink

lnk

lnkDetails

Image

img

imgAuntBetty

ImageButton

ibtn

ibtnSubmit

Label

lbl

lblResults

LinkButton

lbtn

lbtnSubmit

ListBox

lst

lstCountries

Panel

pnl

pnlForm2

PlaceHolder

plh

plhFormContents

RadioButton

rad

radFemale

RadioButtonList

radl

radlGender

RangeValidator

valg

valgAge

RegularExpression

vale

valeEmail_Validator

Repeater

rpt

rptQueryResults

RequiredFieldValidator

valr

valrFirstName

Table

tbl

tblCountryCodes

TableCell

tblc

tblcGermany

TableRow

tblr

tblrCountry

TextBox

txt

txtFirstName

ValidationSummary

vals

valsFormErrors

XML

xmlc

xmlcTransformResults

變數
變數的作用域及字首

字首

說明

舉例

P

全域性變數

pstrName

St

靜態變數

ststrName

M

模組或者窗體的區域性變數

MstrName

A

陣列

AintCount[]

變數資料型別的字首

C#資料型別

類庫資料型別

標準命名舉例

Sbyte

System.sbyte

sbte

Short

System.Int16

sht

Int

System.Int32

int

Long

System.Int64

lng

Byte

System.Byte

bte

Ushot

System.Uint16

usht

Uint

System.Uint32

uint

Ulong

System.Uint64

ulng

Float

System.Single

flt

Double

System.Double

dbl

Decimal

System.Decimal

dcl

Bool

System.Boolean

bol

Char

System.Char

chr

Object

System.Object

obj

String

System.String

str

 

System.DateTime

dte

IntPtr

System.Intpre

intptr



常量定義
常量=作用域+ c+資料型別+變數名

類物件定義
類例項=作用域+cls+變數名
類物件=C+名稱

結構物件定義
結構物件例項=作用域+struc+變數名
結構物件=S+名稱

名稱空間定義
以層為字首進行命名

介面定義
以大寫I為字首

窗體的命名規則
窗體名=frm+窗體名(名詞+動詞)
注意:儲存的檔案明和窗體名相同。

列舉定義規則
以Enum為字首

事件命名規則
事件控制器要帶有EventHandler字尾
使用sender和e命名兩個引數
事件引數類要帶有EventArgs字尾
考慮使用動詞命名事件
對於有"之前"或"之後"概念的事件,要使用現在時或過去時命名