基礎記錄--.NET開發規範

 1.有關簡潔:web

     使用#region標記代碼區域,便於摺疊算法

2.有關命名:編程

  • 使用有意義的名稱,如 IsDepartmentReadyToOfferJob
  • 使用完整單詞,帕斯卡(Pascal)和駱駝(Camel)寫法
NumberOfArgumentsIn
nargin

    根據含義而非類型命名設計模式

ParcelName
strParcelName

      不要用大小寫區分名稱數組

  • 像普通詞同樣書寫縮略詞:XmlReader; System.Linq
  • 用複數形式書寫集合名稱
  • 習慣性後綴(前綴):
抽象基類
-Base
接口
I-
異常
-Exception
事件參數
-EventArgs
事件委託
-EventHandler
特性
-Attribute
泛型類型參數
T-

 

  • 給實現一種設計模式的類加上模式名稱,例如:工廠模式 - xxxFactory
  • 泛型參數的命名:使用單個大寫字母,如T, U等。須要時,寫成TKey, TValue等
  • 枚舉的命名:普通枚舉用單數名詞,位域枚舉用複數名詞。
  • 接口的命名:使用I-加名詞爲聲明服務的接口命名,使用I-加形容詞爲描述能力的接口命名。(例:IEnumerable和IEnumerator)
  • 用能體現布爾值特徵的名稱給布爾類型命名:IsXxx,HasXxx,CanXxx
  • 方法的命名:用動[賓]結構、帕斯卡寫法
  • 變量和方法參數命名:用名詞性結構、駱駝寫法
  • 成組的私有字段、公共屬性和構造函數形參:_item, Item, item。見4.6節代碼示例
  • 習慣中容許使用的標準「一次性」變量名(只限這幾個):
i, j, k
循環變量(類型:System.Int32)
o
System.Object
s
System.String
e
事件實參(基類:System.EventArgs)
ex
異常(基類:System.Exception)
g
System.Drawing.Graphics
x, y, z
Lambda表達式的形參

 

  •  命名空間的命名:公司名.產品名.技術/模塊名。將相互依賴的類型放在同一命名空間下。不要污染框架命名空間(例如在System命名空間中添加類型)。

3.有關字面量app

 

  • 避免使用數值字面量。使用常量表示一個值,使用枚舉明確指示一個狀態。
  • 使用枚舉代替布爾值。
  • 使用標準形式書寫浮點字面量。沒必要寫f,d(通常只用double),但要對整數寫上小數點。用科學計數法時注意小數點前只能有一位數,且不能是0。
  • 字符串字面量應該老是賦給變量使用。用string.Empty代替空串字面量。

 

4 最佳實踐

 

4.1 使用屬性

 

  • 屬性是函數成員,沒有存儲空間。例:屬性不能作ref/out參數。
  • 將成員字段所有私有,使用屬性來獲取,不需修改就不設set。
  • 屬性應簡單、低成本、無反作用、與調用順序無關。
  • 屬性返回集合應該老是隻讀。(用戶代碼能夠清空集合、再添加元素,但不容許使對象引用改變)
  • 屬性返回其餘引用類型也應該儘可能考慮只讀,用戶代碼依然能夠修改爲員。
  • 特殊的屬性:索引器

 

[思考題2]框架

 

複製代碼
string s = "abcdeeg";
s[5] = 'f';
複製代碼

 

以上代碼在C++和C#中是否都合法?是否都有效?函數式編程

 

4.2 使用不可變值類型

 

  • 爲「值」語義使用struct。所謂值語義就是一種狀態、屬性,例如點(座標)、顏色(份量)等,多具備短小數據量的特色。
  • 爲struct的字段添加readonly修飾符,成爲不可變(Immutable)類型。成員函數返回新實例,而不是修改this實例。
  • 值類型的成員字段只應使用基本CTS類型。

 

4.3 轉換

 

  • 用as和is運算符代替顯式引用轉換
  • 基本類型的轉換要使用System.Convert類
  • 避免裝箱和拆箱

 

4.4 字符串

 

[思考題3]檢測一個字符串str是否以"abc"開頭,有兩種方法(不使用StartsWith):函數

 

複製代碼
str.SubString(0, 3) == "abc";
str.IndexOf("abc") == 0;
複製代碼

 

請問哪一種方法好,爲何? ui

 

CLR中的字符串是不可變類型,字符串分配是一項昂貴的操做。所以咱們有如下最佳作法:

 

  • 用string.Empty代替空串字面量。
  • 用str.Length == 0或string.IsNullOrEmpty(str)檢測空串,後者還兼容空引用。
  • 反覆使用的字符串應當建立變量屢次引用而不是每次都使用字面量(每出現一次字面量就要從新分配一次字符串)。
  • 不分大小寫的比較應當用string.Compare(str1, str2, true)而不是str1.ToUpper() == str2.ToUpper()。
  • 考慮使用string.Format()方法而不是字符串拼接來輸出結果。
  • 大量拼接字符串要使用StringBuilder類。

 

4.5 使用查詢表達式代替循環

 

函數式編程爲C#帶來了高可讀性的聲明式語法。循環是一種命令式語法,在聲明式語法中相應的是對集合的mapping操做。

 

如下代碼生成前100個徹底平方數:

 

複製代碼
var squares = Enumerable.Range(1, 100).Select(x => x * x);
複製代碼

 

返回int數組:squares.ToArray();

 

返回List<int>集合:squares.ToList();

 

如下代碼對集合foos中每一個元素執行DoSomething()成員方法:

 

複製代碼
foos.ForEach(x => x.DoSomthing());
複製代碼

 

如下代碼選出foos中大於100的元素:

 

複製代碼
var q = foos.Where(x => x > 100);
複製代碼

 

points中點按到原點距離排序:

 

複製代碼
var q = points.OrderBy(x => x.DistTo(new Point(0, 0)));
複製代碼

 

foos中平方最小的數:

 

複製代碼
double minSq = foos.Min(x => x * x);
double min = foos.Distinct().Single(x => x * x == minSq);
複製代碼

 

foos中的數是否有大於100的(是否都大於100)

 

複製代碼
foos.Any(x => x > 100);
foos.All(x => x > 100);
複製代碼

 

4.6 返回多個值

 

  • 在Matlab中能夠用矩陣返回多個值,這就是元組(Tuple)的概念。當函數須要返回多個值時,應當使用元組而不是使用輸出參數。.NET 4.0中提供了Tuple泛型類,位於System命名空間。在3.5如下版本能夠考慮本身實現。

 

複製代碼
public class Tuple<T1, T2>
{
    private T1 _item1;
    private T2 _item2; 

    public T1 Item1 { get { return _item1; } }
    public T2 Item2 { get { return _item2; } } 

    public Tuple(T1 item1, T2 item2)
    {
        _item1 = item1;
        _item2 = item2;
    }
} 

public class TupleList<T1, T2> : List<Tuple<T1, T2>>
{
    public void Add(T1 item1, T2 item2)
    {
        base.Add(new Tuple<T1, T2>(item1, item2));
    }
}
複製代碼

 

  • 在任什麼時候候都應避免使用ref/out傳遞參數,尤爲對引用類型(禁止引用的引用)。嘗試改進你的設計。

 

4.7 對象初始化

 

複製代碼
Button btn = new Button { Text = "Click me!", BackColor = Color.FromArgb(255, 255, 255) };
btn.Click += (sender, e) => MessageBox.Show("Hello!");
複製代碼

 

4.8 小函數

 

  • 將大函數分拆成小函數。這樣作的好處有:
    • 合併重複代碼,便於維護
    • 增長函數層級,便於調試
  • 方法參數也不宜過多,不然也應考慮拆分。

 

4.9 using塊和finally

 

如下代碼編譯成相同IL:

 

複製代碼
// 1. Example Using clause:
using (myConnection = new SqlConnection(connString))
{
myConnection.Open();
} 

// 2. Example Try / Catch block:
try
{
myConnection = new SqlConnection(connString);
myConnection.Open();
}
finally
{
myConnection.Dispose();
}
複製代碼

 

4.10 使用泛型集合

 

  • 不要使用非泛型的ArrayList,這會帶來沒必要要的裝箱和拆箱。使用System.Collections.Generic命名空間中的容器類型。
  • 代替數組的首選:List<T>。如被用戶代碼獲取應該以只讀屬性形式提供。若是要真的使集合不可修改,可用ReadOnlyCollection<T>(System.Collections.ObjectModel)
  • 集合作參數禁止ref/out傳遞(形成引用的引用)。值傳遞便可達到修改集合元素的目的。
  • 在多個函數間返回、傳遞的集合考慮用接口類型IEnumerable<T>和yield關鍵字。連續的LINQ語句考慮不急於調用ToList或ToArray。
  • 其餘經常使用集合:Dictionary<TKey, TValue>; SortedSet<T>(.NET 4) 

 

4.11 充分利用BCL

 

  • BCL中提供了不少經常使用算法,而且還在不斷擴充。例如,.NET 4增長了System.Numerics命名空間,目前包括BigIntegar和Complex類,而在bcl.codeplex.com上已經放出了BigRational類的候選版和源代碼。
  • 儘量只依賴BCL,減小第三方依賴。
  • 對字符串的操做都有簡單的方法能夠調用。用這些方法不只能更方便省時、穩定高效,並且能使你的代碼趨向於可讀性強的聲明式風格。
  • 儘量只用系統定義的委託,而不是本身定義委託類型。系統定義的委託包括:各類泛型參數數目的Func, Action; 一個Predicate<T>;各類EventHandler。如下是一個高階函數的應用實例:

 

複製代碼
Func<Color, EventHandler> changeControlColor =
x => (sender, e) => (sender as Control).BackColor = x;
button1.Click += changeControlColor(Colors.Red);
複製代碼

 

4.12其餘

 

  • 使用虛函數和多態而不是頻繁使用引用轉換
  • 建立枚舉0值表示未初始化、無效、未指定或默認
  • 老是在派生類構造函數的初始化列表中列出全部基構造函數
  • 老是重寫ToString()方法
相關文章
相關標籤/搜索