C#代碼規範-編程秘笈

來源:互聯網
上載者:User

標籤:namespace   項目   new   逗號   不同   list   索引   檢查   prope   

原文地址:https://www.cnblogs.com/zzp0320/p/6949973.html

1、引言

本文是一套面向C# programmer和C# developer進行開發所應遵循的開發規範

按照此規範來開發C#程式可帶來以下益處:

代碼的編寫保持一致性,提高代碼的可讀性和可維護性,在團隊開發一個項目的情況下,程式員之間可代碼共用,易於代碼的回顧

本規範是初版,只適用於一般情況的通用規範,並不能覆蓋所有的情況

2、檔案組織

2.1C#源檔案

類名或檔案名稱要簡短,不要超過2000LOC,將代碼分割開,使結構清晰。將每個類放在一個單獨的檔案中,使用類名來命名檔案名稱(當然副檔名是.cs),這種約定會使大家工作更簡單

2.2目錄設計

為每一個命名空間建立一個目錄。(用MyProject/TestSuite/TestTier作為MyProject.TestSuite.TestTier的路徑,而不用帶點的命名空間名做路徑)這樣可以更容易地將命名空間映射到目錄

 層次劃分。

3、縮排

3.1換行

當一個運算式超過一行時,根據這些通用原則進行處理:

在逗號後換行,在操作符後換行,在高層換行而不要在低層處換行,折行後對齊上一行語句同一層的運算式起始位置。

方法調用換行樣本:

longMethodCall(expr1,expr2,expr3,expr4,expr5);

算術運算式換行樣本:

推薦:

var = a * b / (c - g + f) +

      4 * z;

不好的格式——應避免:

var = a * b / (c - g +

      f) + 4 * z;

推薦使用第一種方法,因為是在括號運算式之外折行(高層次折行原則)。注意要用定位字元到縮排的位置,然後用用空格到折行的位置。在我們的例子中是:

> var = a * b / (c - g + f) +

> ......4 * z;

‘>‘表示是定位字元,‘.‘表示是空格符。(定位字元後是空白是用定位字元縮排)。一個好的編碼習慣就是在所用的編輯器中顯示定位字元和空格符。

3.2 空白

利用空格進行縮排從未有過統一的標準。一些人喜歡用兩個空格,一些人喜歡用四個空格而還有一些人喜歡用八個空格,甚至有的人喜歡用更多的空格。好的做法是用定位字元。定位字元有一些優點:

·         每個人都可以設定他們自己喜歡的縮排層級。

·         它僅僅是1個字元而不是2,4,8等等,因此它將減少輸入(甚至因為自動縮排,有時你不得不手工設定縮排或取消設定,等等諸如此類的操作)。

·         如果你想增加或減少縮排,可以標記一塊,使用Tab增加縮排層級而用Shift-Tab減少縮排層級。這幾乎對於任何文字編輯器都是適用的。

這裡,我們定義定位字元為標準縮排符。

不要用空格縮排—用定位字元!

4、注釋

4.1塊注釋

塊注釋通常應該是被避免的 。推薦使用///注釋作為C#的標準聲明。如果希望用塊注釋時你應該用以下風格:

/*Line1

*Line2

*Line3

*/

因為這樣可以為讀者將註解區塊與代碼塊區分開。雖然並不提倡使用C風格的單行注釋,但你仍然可以使用。一旦用這種方式,那麼在注釋行後應有斷行,因為很難看清在同一行中前面有注釋的代碼

/*blah blah blah */

塊注釋在極少情況下是有用的。通常塊注釋用於注釋掉大的程式碼片段

4.2單行注釋

你應該用//注釋風格"注釋掉”代碼(快速鍵,Alt+/),它也可以被用於代碼的注釋部分

單行注釋被用於代碼說明時必須縮排到相應的編進層級。注釋掉的代碼應該放在第一行被注釋掉以使注釋掉的代碼更容易看清

一條經驗,注釋的長度不應該超過被解釋代碼的長度太長,因為這表示代碼過於複雜,有潛在的bug

4.3檔案注釋

在.net架構,Microsoft已經介紹了一個基於XML注釋的檔案。這些檔案是包括XML標籤的正規的單行的C#注釋。他們遵循單行注釋的模式:

 ///<summary>

///This class

///</summary>

多行XML注釋遵循這種模式:

///<exception cref="BogusException">

 ///This exception gets thrown as soon as a

///</exception>

為了被認作是XML注釋行,所有的行都必須用三個反斜線開始。標籤有以下兩類:

檔案說明項   格式/參考

第一類包括像<summary><param>or<exception> 的標籤。描述一個程式的API元素的這些文檔說明項必須寫清楚以方便其他程式員。如上面的多行注釋樣本所示,這些標籤通常帶有名

 稱或cref屬性。編譯器會檢查這些屬性,所以它們必須是有效正確的。第二類用諸如<code>,<list>or<para>標籤,用於控製備注說明的布局。檔案可以用‘檔案’菜單中的“建立”菜單產生。檔案

以html格式產生:

5、聲明

5.1每行的聲明數

推薦每行只有一個聲明,因為它可以方便注釋

int level;//indentation level

int size;//size of table

當聲明變數時,不要把多個變數或不同類型的變數放在同一行,例如:

int a, b; //What is ‘a‘? What does ‘b‘ stand for?

上面的例子也顯示了變數名不明顯的缺陷。當命名變數時要清晰。

5.2 初始化

局部變數一旦被聲明就要初始化。例如:

string name = myObject.Name;

int val = time.Hours;

注意:如果你初始化一個dialog,設計使用using語句:

using (OpenFileDialog openFileDialog = new OpenFileDialog()) {

...

}

5.3 類和介面聲明

當編寫C#類和介面時,應遵循以下格式化規則:

·         在方法名和圓括弧“(”開始它的參數列表之間不要使用空格。

·         在聲明語句的下一行以大括弧"{"標誌開始。

·         以"}"結束,通過它自身的縮排與相應的開始標誌匹配。

例如:

Class MySample : MyClass, IMyInterface

{

        int myInt;

        public MySample(int myInt)

        {

        this.myInt = myInt ;

        }

        void Inc()

        {

                ++myInt;

        }

        void EmptyMethod()

        {

        }

}

對於一個大括弧的位置參考10.1部分。

6. 語句

6.1 簡單語句

每行都應該只包含一條語句。

6.2 返回語句

一個返回語句不要用最外圍圓括弧。不用:

return (n * (n + 1) / 2);

用: return n * (n + 1) / 2;

6.3 If, if-else, if else-if else 語句

if, if-else and if else-if else 語句看起來應該像這樣:

if (condition) {

DoSomething();

...

}

if (condition) {

DoSomething();

...

} else {

DoSomethingOther();

...

}

if (condition) {

DoSomething();

...

} else if (condition) {

DoSomethingOther();

...

} else {

DoSomethingOtherAgain();

...

}

6.4 for / foreach 語句

一個for語句應該如下形式:

for (int i = 0; i < 5; ++i) {

...

}

或者放置一行(考慮用一個while語句代替)

for (initialization; condition; update) ;

foreach語句應該像下面所示 :

foreach (int i in IntList) {

...

}

注意:在一個迴圈中,即使只有一個語句通常也用括弧括起來。

6.5 While/do-while 語句

一個while語句應該寫成如下形式:

while (condition) {

...

}

一個空while語句應該是以下格式:

while (condition) ;

一個do-while語句應該是如下格式:

do

{

...

} while (condition);

6.6 Switch 語句

一個switch語句應該如下格式:

switch (condition) {

case A:

...

break;

case B:

...

break;

default:

...

break;

}

6.7 Try-catch 語句

一個try-catch statement語句應該遵循以下格式:

try {

...

} catch (Exception) {}

or

try {

...

} catch (Exception e) {

...

}

or

try {

...

} catch (Exception e) {

...

} finally {

...

}

7. 空白

7.1 空行

空行提高可讀性。它們分開那些邏輯上自身相關聯的代碼塊。兩行空格行應該用於以下之間:

·         一個源檔案的邏輯段。

·         類和介面定義(每個檔案只定義一個類或介面以避免這種情況)。

一個空格行應該總是被用於以下之間:

·         方法

·         屬性

·         一個方法中的局部變數和它的第一條語句

·         一個方法中的邏輯段為了提高可讀性。注意空白行必須被縮排因為它們包括一條語句這使得插入這些行更容易。

7.2 內部空格

在一個逗號或一個分號之後應該由一個空格,例如:

TestMethod(a, b, c); 不要用: TestMethod(a,b,c)

TestMethod( a, b, c );

單個空格包圍操作符(除了像加的一元操作符和邏輯非),例:

a = b; // don‘t use a=b;

for (int i = 0; i < 10; ++i) // don‘t use for (int i=0; i<10; ++i)

// or

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

7.3 表格格式化

行的一個邏輯塊應該作為一個表格被格式化:

string name = "Mr. Ed";

int myValue = 5;

Test aTest = Test.TestYou;

對於表格的格式化用空格而不用定位字元因為在某些定位字元縮排設定會使表格格式化看起來是很奇怪。

8. 命名習慣

8.1 大寫格式

8.1.1 Pascal Casing

習慣大寫每個單詞的第一個字母(就像在TestCounter)。

8.1.2 Camel Casing

習慣除了第一個單詞外大寫每個單詞的第一個字母例如testCounter。

8.1.3 全大寫情況

對於只有一兩個字元縮寫組成的標識符才用全大寫的情況。有三個或更多個字元組成的標識符應該用Pascal情況代替。例如:

public class Math

{

public const PI = ...

public const E = ...

public const feigenBaumNumber = ...

}

8.2. 命名指導方針

通常根據指導方針在名字和命名內用低線字元對Hungarian 符號來說被認為是壞習慣。

Hungarian 符號是一組應用於命名來映射變數類型的首碼和尾碼。這種命名風格在早期的Windows程式中被廣泛應用,但現在被取消了至少不提倡了。如果你遵循這個指南用Hungarian 符號是不允許的。

但要記住一個好的變數名描述了語義而不失類型。

對於這個規則有個例外就是GUI編碼。包括像按鈕(buttton)的GUI元素,所有領域和變數名都應該帶有它們類型名的尾碼不是縮寫。例如:

System.Windows.Forms.Button cancelButton;

System.Windows.Forms.TextBox nameTextBox;

8.2.1 類命名指導方針

·         類命名必須是名詞或名詞短語。

·         UsePascal 情況參考8.1.1

·         不要用任何類首碼

8.2.2 介面命名指導方針Guidelines

·         用可以描述行為的名詞或名詞短語或形容詞命名介面。(例如IComponent 或 IEnumberable)

·         用Pascal情況(參考8.1.1)

·         用I作為名字的首碼,它應該緊跟一個大寫字母(介面名的第一個字母)

8.2.3 枚舉命名指導方針

·         用Pascal情況命名枚舉值名字和類型名字

·         枚舉類型和枚舉值不要首碼

·         對於枚舉用單一名字

·         對於位領域用複數名字

8.2.4 唯讀和常量命名

·         用名詞,名詞短語或名詞的縮寫命名靜態領域

·         使用Pascal 情況(參考8.1.1)

8.2.5 參數/非常量領域命名

·         一定要用描述性名字,應該能夠足夠表現變數的意義和它的類型。但一個好的名字應該基於參數的意義。

·         使用Camel情況(參考8.1.2)

8.2.6 變數命名

·         計數變數當用在瑣碎的計數迴圈式更適宜叫i, j, k, l, m, n。(參考10.2例如對全域計數的更智能命名等等)—

·         使用Camel情況(參考8.1.2)

8.2.7 方法命名

·         用動詞或動詞短語命名方法。

·         使用Pascal(參考8.1.2)

8.2.8 屬性命名

·         用名詞或名詞短語命名屬性

·         使用Pascal 情況(參考8.1.2)

·         考慮用與其類型相同的名字命名一個屬性

8.2.9 事件命名

·         用事件處理器尾碼命名事件處理器

·         用sender 和 e命名兩個參數

·         使用Pascal情況(參考8.1.1)

·         用EventArgs 尾碼命名事件參數

·         用現在和過去時態命名有首碼和複製概念的事件名字。

·         考慮用一個動詞命名事件。

8.2.10 大寫總結

 

Type

 

Case

 

Notes

 

Class / Struct

 

Pascal Casing

 

 

 

Interface

 

Pascal Casing

 

Starts with I

 

Enum values

 

Pascal Casing

 

 

 

Enum type

 

Pascal Casing

 

 

 

Events

 

Pascal Casing

 

 

 

Exception class

 

Pascal Casing

 

End with Exception

 

public Fields

 

Pascal Casing

 

 

 

Methods

 

Pascal Casing

 

 

 

Namespace

 

Pascal Casing

 

 

 

Property

 

Pascal Casing

 

 

 

Protected/private Fields

 

Camel Casing

 

 

 

Parameters

 

Camel Casing

 

 

 

9. 編程習慣

9.1 可見度

不要任何公用執行個體或類變數,讓它們為私人的。對於私人成員最好不用“private”作修飾語什麼都不寫。私人是預設情況,每個C#程式員都應該知道這一點。

用屬性代替。你可以用公用靜態(或常量)對於這個規則是以例外,帶它不應該是規則。

9.2 沒有“幻”數

不要用幻數,也就是在原始碼中直接用常數值。替代這些後者以防變化(比方說,你的應用程式可以處理3540使用者代替427你的代碼在50行中通過分散25000LOC)是錯誤和沒有收益的。聲明一個帶有數的常量來代替:

public class MyMath

{

public const double PI = 3.14159...

}

10. 編碼舉例

10.1 Brace placement example

namespace ShowMeTheBracket

{

public enum Test {

TestMe,

TestYou

}

public class TestMeClass

{

Test test;

public Test Test {

get {

return test;

}

set {

test = value;

}

}

void DoSomething()

{

if (test == Test.TestMe) {

//...stuff gets done

} else {

//...other stuff gets done

}

}

}

}

括弧應該在以下情況之後以新行開始:

·         命名空間聲明(注意這在0.3版本中是新添的與0.2版本不同)

·         類/介面/結構聲明

·         方法聲明

10.2 變數命名舉例

代替:

for (int i = 1; i < num; ++i) {

meetsCriteria[i] = true;

}

for (int i = 2; i < num / 2; ++i) {

int j = i + i;

while (j <= num) {

meetsCriteria[j] = false;

j += i;

}

}

for (int i = 0; i < num; ++i) {

if (meetsCriteria[i]) {

Console.WriteLine(i + " meets criteria");

}

}

try intelligent naming :

for (int primeCandidate = 1; primeCandidate < num; ++primeCandidate)

{

isPrime[primeCandidate] = true;

}

for (int factor = 2; factor < num / 2; ++factor) {

int factorableNumber = factor + factor;

while (factorableNumber <= num) {

isPrime[factorableNumber] = false;

factorableNumber += factor;

}

}

for (int primeCandidate = 0; primeCandidate < num; ++primeCandidate)

{

if (isPrime[primeCandidate]) {

Console.WriteLine(primeCandidate + " is prime.");

}

}

注意:索引變數通常叫i, j, k 等等。但Note: Indexer variables generally should be called i, j, k etc. But 萬一像這樣,使得重新考慮這個原則更有意義。一般來說,當同一個計數器或索引器被重用,給它們有意義的名字。

C#代碼規範-編程秘笈

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.