我一直自認為,自己在編程功力還算說的過去,昨天一個老師看了我以前寫的代碼,說功力還需加強(當時我很鬱悶,其實我知道的可能還比他多)。很多時候我們都太注重高水平、尖端的技術,其實很多公司叫你寫一段簡單的程式,可能就會決定要不要你。他們是從代碼中看出了你的閱曆,你的水平。這些水平不是體現你的尖端技術(況且很多新技術都是可以學的),而是你的風格,或習慣,而這些恰恰是經過很長的閱曆積累起來的。
下面是從網上收集的c#編程風格參考,希望對讀者有用。
【參考】《.NET設計規範》Krzysztof Cwalina,Brad Abrams著
C#編程世界中存在許多不同的編程風格約定,每一種都有自己的曆史和哲學。本文描述的約定著眼於以下這些目標:
1、必須是實際開發人員使用的約定。為了實現這個目標,我們審查了由.NET架構的開發人員編寫的代碼。有些約定並未在架構中普遍應用,對此我們不予採納。
2、約定應該儘可能的合理、簡潔。我們認為只要不犧牲代碼的可讀性,在更少的行數內編寫更多的代碼通常是有協助的,因為可以儘可能地減少代碼的分屏和拆行,儘可能地增加代碼的密度(沒有空行)。
3、約定要簡單。我們認為編程約定沒有必要對每一種格式的每一個細節都錙銖必較。過於複雜的約定會難以遵循,而且與一小組核心約定相比,它們不會再增添太多的價值。
一、通用約定風格
1、花括弧的使用
- 要把左花括弧放在前一條語句的末尾。
if (someExpression){
DoSomething();
}
- 要使右花括弧與左花括弧所在的行的行首對齊,除非花括弧內只有一條語句。
if (someExpression){
DoSomething();
}
- 要把右花括弧放在新的一行的開始處。
if (someExpression){
DoSomething();
}
- 考慮把只有一條語句的代碼塊和左右花括弧寫在同一行。屬性的存取方法經常使用這種風格。
public int Foo{
get{ return foo; }
set{ foo = value; }
}
- 考慮把只有一個存取方法的屬性的所有花括弧寫在同一行中。
public int Foo{ get{ return foo; } }
- 要使右花括弧單獨佔一行,除非它後面是else、else if或while。
if (someExpression){
do{
DoSomething();
} while(someOtherCondition);
}
- 避免省略花括弧,即使程式設計語言允許這樣做。
不應該認為花括弧是可以省略的。即使對只有一條語句的代碼塊,仍應該使用花括弧。這樣可以增強代碼的可讀性和可維護性。
for (int i=0; i<100; i++){ DoSomething(i); }
只有在極少數情況下才可以省略花括弧,比如在原來僅有的一條語句後再添加新的語句是不可能的或是非常罕見的。例如,在throw語句後面再添加任何語句都是沒有意義的:
if (someExpression) throw new ArgumentOutOfRangeException(...);
本條約定的另一個例外是case語句。由於case和break語句已經表示了代碼塊的起始和結束,因此這些花括弧可以被省略。
2、空格的使用
- 要在左花括弧之後和右花括弧之前加一個空格。
public int Foo{ get{ return foo; } }
- 避免在左花括弧之前加空格。
最好如此:if (someExpression){
可以接受:if (someExpression) {
- 要在形式參數之間的逗號後加一個空格。
正確:public void Foo(char bar, int x, int y)
錯誤:public void Foo(char bar,int x,int y)
- 避免在實際參數之前加空格。
最好如此:Foo(mychar,0,1)
可以接受:Foo(mychar, 0, 1)
- 避免在左圓括弧之後或右圓括弧之前加空格。
最好如此:Foo(mychar,0,1)
可以接受:Foo( mychar, 0, 1 )
- 不要在成員的名字和左圓括弧之間加空格。
正確:Foo()
錯誤:Foo ()
- 不要在左方括弧之後和右方括弧之前加空格。
正確:x = dataArray[index];
錯誤:x = dataArray[ index ];
- 不要在控制流程語句之前加空格。
正確:while(x==y)
錯誤:while (x==y)
- 避免在二元操作符之前和之後加空格。
最好如此:if(x==y){ ... }
可以接受:if(x == y){ ... }
- 不要在一元操作符之前或之後加空格。
正確:if(!y){ ... }
錯誤:if(! y){ ... }
3、縮排的使用
- 要用4個連續的空格符來進行縮排。
- 不要用製表位(tab)來進行縮排。
- 要對代碼塊中的內容進行縮排。
if (someExpression){
DoSomething();
}
- 要對case代碼塊進行縮排,儘管沒有使用花括弧。
switch(someExpression){
case 0:
DoSomething();
break;
...
}
二、命名規範
- 要在命名標示符時遵循《架構設計準則》中的命名規範,除非是內部欄位和私人欄位。
- 要在命名空間、類型及成員時採用PascalCasing大小寫風格,除非是內部欄位和私人欄位。
- 要用camelCasing大小寫風格來命名內部欄位和私人欄位。
- 要用camelCasing大小寫風格來命名局部變數。
- 要用camelCasing大小寫風格來命名方法的形式參數。
- 不要使用匈牙利命名法(也就是說,不要在變數名中包含變數的類型)。
- 避免給局部變數加首碼。
- 要使用C#語言中對應的別名,不要使用.NET架構中的類型名。
例如,要使用int而不是Int32,要使用object而不是Object。
三、注釋
- 不要用注釋來描述一些對任何人都顯而易見的事。
- 避免使用塊注釋文法(/*...*/)。即使注釋會有多行,也最好是使用單行注釋文法(//...)。
//This is a very long content.
//This is a very long content.
//This is a very long content.
public class List<T> : IList<T>, IList{
...
}
- 不要把注釋放在行尾,除非注釋非常短。
//Avoid
public class ArrayList{
private int count; //-1 indicates uninitialized array
}
四、檔案的組織
- 不要在一個源檔案中包含一個以上的公用類型,除非有嵌套類,或各類型之間的不同之處僅在於泛型參數的數量。
一個檔案中有多個內部類型是允許的。
- 要用相同的名字來命名源檔案及其包含的公用類型。
例如,String類應該在String.cs檔案中,而List<T>類則應該在List.cs檔案中。
- 要用相同的階層來組織檔案目錄和名字空間。
例如,應該把System.Collections.Generic.List<T>的源檔案放在System\Collections\Generic目錄中。
- 考慮根據下面給出的順序和組別來對成員進行分組:
1.所有欄位。
2.所有建構函式。
3.公有屬性及其受保護的屬性。
4.方法。
5.事件。
6.所有顯式實現的介面成員。
7.內部成員。
8.私人成員。
9.所有巢狀型別。
- 要把不能公開訪問的成員和顯式實現的介面成員分別放在自己的#region塊中。
#region internal members
...
#endregion
#region private members
...
#endregion
- 考慮在每個組別內根據字母順序來組織成員。
- 考慮根據由簡單到複雜的順序來組織重載成員。
- 要把using指令放在名字空間的聲明之外。
using System;
namespace System.Collections{
...
}