读 《CSharp Coding Guidelines》有感
C# 編程指南
前不久在 Github 上看見了一位大牛創(chuàng)建一個(gè)倉庫:CSharpCodingGuidelines,打開之后看了一下?readme.md?相關(guān)描述,感覺應(yīng)該很不錯(cuò),于是就?clone?到本地拜讀一下,這里列一些自己的筆記,方便日后回顧。
基本原則
Astonishment 原則:你的代碼應(yīng)該盡量做到讓每一個(gè)人都能理解。任何人都有寫出讓機(jī)器認(rèn)識的代碼,但是并不是每個(gè)人都能寫出讓人認(rèn)識的代碼;
Kiss 原則:類似 Python 之禪 里面說的那樣,簡單勝于復(fù)雜;
YAGNI 原則:代碼盡量能做到可擴(kuò)展,但請不要過度重構(gòu),因?yàn)槟悴荒茴A(yù)知未來;
DRY 原則:不要重復(fù)造輪子,除非你有時(shí)間或者你造的輪子會比別人的優(yōu)秀;
面向?qū)ο缶幊淘瓌t:繼承、封裝、多態(tài)、抽象;
類設(shè)計(jì)指南
一個(gè)類/接口應(yīng)該只有一個(gè)用途,要符?合單一職責(zé)?原則;
只創(chuàng)建返回有用對象的構(gòu)造函數(shù),當(dāng)構(gòu)造函數(shù)的參數(shù)超過 3 的話,你就應(yīng)該考慮你的類設(shè)計(jì)是否過于臃腫;
接口應(yīng)該短小精悍,其定義要明確清晰地傳達(dá)出其具有的行為;
如果一種行為有多種實(shí)現(xiàn),請考慮使用接口而不是基類;
盡量使用接口將類進(jìn)行彼此解耦;
避免使用靜態(tài)類;
不要使用?new?關(guān)鍵字來禁止編譯器顯示相關(guān)警告;
在上述代碼段中,我們創(chuàng)建一個(gè)基類?book,并定義了一個(gè)?Print()?方法,接著我們創(chuàng)建一個(gè)子類?PocketBook,并通過?new?關(guān)鍵字來重寫基類方法。在項(xiàng)目復(fù)雜的情況下,使用這種方式將導(dǎo)致我們不能準(zhǔn)確預(yù)測是子類調(diào)用還是父類調(diào)用,使代碼復(fù)雜度提升。
應(yīng)該可以將派生類當(dāng)作基類對象來處理;
不要引用基類的派生類;
避免暴露一個(gè)對象依賴的其它對象;
避免雙向依賴;
類應(yīng)該有狀態(tài)和行為;
類應(yīng)該保護(hù)其內(nèi)部狀態(tài)的一致性;
屬性成員設(shè)計(jì)指南
允許按任意順序設(shè)置屬性;
使用方法而不是屬性;
不要使用相互排斥的屬性;
屬性、方法或者本地方法只應(yīng)該做一件事情;
不要通過靜態(tài)成員公開有狀態(tài)的對象;
用 IEnumerable
?或者 ICollection?來代替具體的集合對象作為返回值;如果屬性、參數(shù)和返回值是字符串或者集合類型的話,則永遠(yuǎn)不應(yīng)該為空;
盡可能地定義具體的參數(shù);
考慮使用特定域的值類型而不是基元;
其他設(shè)計(jì)指南
拋出異常而不是返回某種類型的狀態(tài)值;
提供完整而有意義的異常信息;
拋出適當(dāng)?shù)淖罹唧w的異常;
不要通過 try - catch 方式隱藏異常;
正確處理異步代碼中的異常;
調(diào)用事件委托前先判斷是否為空;
protected virtual void OnNotify(string args){Notify?.Invoke(this, args); }
使用受保護(hù)的虛方法來觸發(fā)每個(gè)事件;
考慮添加屬性變化事件;
當(dāng)觸發(fā)事件時(shí)要確保 sender != nulll;
如果合適的話,請考慮使用泛型約束;
在返回 LINQ 表達(dá)式之前計(jì)算它的結(jié)果;
如果不是必須,不要使用?this?和?base?關(guān)鍵字;
可維護(hù)性指南
方法內(nèi)部的代碼段盡量不要超過 7 行;
確保所有成員私有,類的類型默認(rèn)為為?internal sealed
避免雙重條件;
在其包含的命名空間內(nèi)命名程序集;
將源文件命名為它所包含的類型;
將源文件的內(nèi)容限制為一種類型;
將不同的邏輯函數(shù)放到同一個(gè)部分類中;
在使用一個(gè)類型時(shí),使用?using?關(guān)鍵字導(dǎo)入需要的命名空間,而不是類型的完整空間標(biāo)識;
不要使用魔法數(shù);
只有當(dāng)類型顯而易見時(shí)才使用?var?關(guān)鍵字;
定義變量時(shí)盡可能地初始化;
在相互獨(dú)立的代碼段中定義臨時(shí)變量;
若對象有集合需要初始化的話在進(jìn)行對象初始化的同時(shí)進(jìn)行集合初始化;
不要顯式進(jìn)行?bool?值的比較;
避免嵌套循環(huán);
在使用?if、else、do、while、for、foreach、case?的同時(shí)使用?{}?;
在?switch case?代碼段中添加?default?邏輯;
在所有的?if?、else if?后再添加?else;
避免使用多個(gè)返回值;
考慮使用簡單的條件語句代替?if else;
封裝屬性、方法或局部函數(shù)中的復(fù)雜表達(dá)式;
再合適的情況下嘗試重載方法;
使用可選參數(shù)來代替重載;
避免使用命名參數(shù);
避免定義超過3個(gè)參數(shù)的簽名;
避免函數(shù)簽名為布爾類型;
不要將參數(shù)作為臨時(shí)變量使用;
將模式作為操作;
不要注釋代碼;
命名指南
不要在變量、參數(shù)和類型成員中包含數(shù)字;
不要在字段添加前綴;
不要使用縮寫;
成員、參數(shù)和變量定義要根據(jù)它們代表的意義;
使用名詞、名詞短語或者形容詞來定義類型;
使用描述性名稱命名泛型參數(shù);
在類成員中不要重復(fù)定義和類相同的名稱;
成員定義可參考 .Net Framework 的定義方式;
避免使用可能被誤解的段名稱或字段;
正確定義屬性;
在命名方法或局部函數(shù)時(shí)使用謂詞或謂詞對象;
使用名稱、層、謂詞和功能申明命名空間;
使用動詞或動詞前綴來定義事件;
使用?ing?和?end?后綴來表達(dá)事件預(yù)處理和發(fā)送事件;
使用?on?前綴來定義事件處理程序;
使用?Async?或者?TaskAsync?來標(biāo)識異步方法;
性能指南
使用?Any()?判斷?IEnumerable?是否為空 ;
僅對低密集型活動使用異步;
對于 CPU密集型使用?Task.Run;
避免同時(shí)將?async/await?和?Task.Wait?混合使用;
避免?async/await?在單線程環(huán)境下出現(xiàn)死鎖;
框架指南
使用 C# 類型 別名而不是系量進(jìn)行顯式調(diào)用;
不要硬編碼;統(tǒng)命名空間中的類型;
盡
使用最高警告級別編譯代碼;
對于簡單的表達(dá)式避免使用?LINQ;
使用 lambda 表達(dá)式來代替匿名函數(shù);
只用在使用動態(tài)對象時(shí)才使用?dynamic?關(guān)鍵字;
支持異步/等待任務(wù)延續(xù);
文檔指南
使用美式英語來編寫相關(guān)文檔;
文檔中的代碼部分要保證完整性;
與其他開發(fā)人員一起編寫 xml 文檔;
編寫 MSDN 風(fēng)格的技術(shù)文檔;
避免內(nèi)聯(lián)注釋;
注釋值應(yīng)該用來解釋復(fù)雜的算法或討論;
不要使用注釋來跟蹤要在以后完成的工作;
布局指南
使用常規(guī)布局;
根據(jù)公式要求進(jìn)行命名空間的約束;
將成員置于定義良好的順序中;
謹(jǐn)慎使用?#region;
適當(dāng)使用表現(xiàn)健全的成員;
相關(guān)鏈接
Code Complete: A Praccal Handbook of Soware Construcon (Steve McConnel)
The Art of Agile Development (James Shore)
Applying Domain-Driven Design and Paerns: With Examples in C# and .NET (Jimmy Nilsson)
Jeremy D. Miller's Blog
LINQ Framework Design Guidelines
Best Pracces for c# async/await
原文地址:https://www.cnblogs.com/hippieZhou/p/9410623.html
.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com?
總結(jié)
以上是生活随笔為你收集整理的读 《CSharp Coding Guidelines》有感的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软把UWP定位成业务线应用程序开发平台
- 下一篇: 微软Windows Community