代碼是軟件開發過程的產物,代碼的作用是通過編譯器編譯后運行,達到預期的效果(功能、穩定性、安全性等等),而另外一個重要作用是給人閱讀。對於機器來說只要代碼正確就能夠正確的運行程序,但是人不同,如果代碼編寫混亂就會對代碼閱讀造成障礙,導致代碼無法維護,甚至會導致代碼重構等高成本活動,所以規范代碼勢在必行。
本文從以下幾個方面介紹代碼規范以及相關工具。
.Net代碼規范簡介
文章開始提到過代碼是給人看的,代碼規范的目的在於創建一個統一的規范來保持代碼的整潔,這樣有利於提高代碼的可維護性,但除此之外還可以將一些代碼的最佳實踐也作為規范的一部分,這樣還可以提高代碼的性能和安全性。
一般來說.Net的代碼規范主要有:代碼格式規范、代碼使用規范,前者保證代碼可讀性后者保證代碼執行效率和安全性。
代碼格式規范
代碼格式規范主要的目的是統一代碼編寫格式,避免開發人員獨特的代碼編寫方式,以便於項目的所有開發人員能快速的閱讀其他人員開發的代碼,代碼格式規范主要有以下幾個方面:
注:除以下規范外,對於一個工程來說應該還有工程結構規范(也可以理解為代碼目錄結構規范),工程結構規范可能因項目不同而不同,但是統一規范可以提高代碼查找效率和開發效率(團隊新成員不會再疑惑代碼應該放哪里)。
命名規范
命名規范主要涉及命名空間、類型、接口、屬性、方法、變量等相關命名,其主要規范有:
- 使用Pascal(單詞首字母大寫)命名方式對命名空間、類型、枚舉類型、枚舉值、事件、屬性、方法、常量進行命名。
例:public class PersonManager {}
- 使用Camel()命名方式對參數、變量、字段進行命名。
例:private string userName;
禁止使用縮寫,除URL、IO等能達成共識的縮寫除外,使用縮寫可全大寫。
例:System.IO;
- 接口以I做為前綴進行命名。
例:public interface IConvertor {}
- 抽象類以Abstract為前綴或者以Base為后綴進行命名。
例:public abstract class PersonBase {}
- 異常類型以Exception為后綴。
例:public class CustomException {}
- 在對任何東西命名時需要使用有意義的名稱,並且保證單詞拼寫正確以及語法正確,避免使用拼音(地名等通用拼音除外)。
例: public string Name {get; set;}
反例: public string N {get; set;}
布局規范
布局規范的目的是使代碼變得整潔,提高代碼可讀性,其主要規范有:
- 代碼縮進為4個空格。
左右花括號必須獨自一行,括號內容為空時除外:
例:public void WriteLog(string log)
{
Console.WriteLine(log);
}
public void EmptyMethod(string log) {}
- 括號的使用:
- if/for/while/do等關鍵字后面與左括號直接需要加空格:
if (x == 1)
-
- 運算符左右需要加空格:
a = c + b;
- 單行代碼限制120個字符,超長處理方式:
- 第二行相對第一行縮進4個空格,從第三行開始無需縮進。
- 運算符及方法調用的“.”需要跟隨換行,但逗號不需要。
例:WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
App.Method(a
+ b,
c);
注釋規范
注釋用來對編寫的代碼進行說明,包括功能說明以及實現說明,這樣可以大大的提高程序的可讀性,另外規范的注釋還可以通過工具來生成相應的API文檔,C#的注釋規范有以下幾種:
- 類注釋
例:/// <summary>
/// This is a Entity Class for Post.
/// </summary>
public class Post
- 屬性及方法注釋:
/// <summary>
/// Get post with id
/// </summary>
/// <param name="id">post's identity</param>
/// <returns>post instance</returns>
public Post GetPostById(int id)
- 代碼單行注釋:
//this is a single line comment
- 代碼多行注釋:
/*
this is comment1
this is comment2
*/
代碼使用規范
代碼的使用規范,或者說是代碼編寫的最佳“實踐”(當然優良的格式規范也是一種最佳實踐),它們是根據代碼的實現/運行原理以及特定的應用場景進行實踐的最佳方案,這些方案的使用除了可以提高代碼的可讀行外,還可以減少程序Bug、提高程序性能及安全性,如以下幾個方面:
- 使用語言特性
this:使用this區分類型中的屬性與變量、靜態成員,可以提高程序可讀性。
var:適當的使用var可以提高開發效率且不影響程序可讀性,如在不知道返回值具體類型或者不需要知道類型的時候。
反例:
本例來自:https://weblogs.asp.net/dixin/csharp-coding-guidelines-4-types
- 字符串內插(string interpolation):字符串內插是C#6.0的特性,使用字符串內插可以提高程序可讀性:
例:
- 異常
- 當程序出現與預期不符時應該拋出異常讓程序上游處理。
- 盡可能使用C#中內置的異常類型。
- 捕獲異常必須處理。
- 獲取指定異常而非統一使用Exception。
- 安全准則
參考:https://docs.microsoft.com/zh-cn/dotnet/standard/security/secure-coding-guidelines
更多規范可參考:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions
代碼使用規范是一個廣泛的話題,除了以上一些通用的規范之外,還可以對OOP以及開發框架等方面根據實際情況制定規則,使用統一的規范進行開發可以讓代碼變得更加容易管理。
常用的代碼規范工具
- Visual Studio
VS是非常強大的IDE,在眾多功能中當然不會缺少對代碼規范的支持。
- StyleCop
StyleCop是一個代碼分析工具,StyleCop有兩個版本StyleCop和StyleCop Analyzers,前者適用於VS2010-VS2017所有版本,它的原理是在編譯時對代碼進行分析,而StyleCop Analyzers僅支持VS2015+,它基於.Net的roslyn編譯框架實現的,它支持開發時對代碼進行實時分析(不再需要等編譯)。
StyleCop:https://github.com/StyleCop/StyleCop
StyleCop Analyzers:https://github.com/DotNetAnalyzers/StyleCopAnalyzers
- Resharper
Resharper是jetbrains公司開發的一個VS收費插件,它不僅包含了代碼分析,還具備了代碼生成、編譯、測試、調試等功能。
VS2017與Resharper的功能比較https://www.jetbrains.com/resharper/documentation/comparisonMatrix_R2018_1_vs2017.html
- EditConfig
EditConfig是一個跨編輯器/IDE的代碼風格一致性維護工具(協議/插件),現在VS2017已經支持EditConfig
- DocFx
DocFx是一個API文檔生成工具,使用DocFx可以快速的搭建一個程序使用、及API文檔,樣式可參考:
DocFx教程:http://dotnet.github.io/docfx/tutorial/docfx_getting_started.html
API文檔:http://dotnet.github.io/docfx/api/Microsoft.DocAsCode.html
小結
本文主要介紹了C#中的編程規范,並將規范分為了兩個類型,分別是格式規范和使用規范,前者主要目的是讓代碼格式達到一致性,后者則是規定了代碼的使用方法,最大化的減少不同經驗開發人員編寫代碼的質量,提高程序的可讀性、性能、穩定性及安全性。
在開發過程中編程規范是一項非常重要的工作,它關系着代碼是否能夠被維護,提高可維護性可以減少團隊成員增減、功能新增、代碼變更等帶來的高成本。
編程規范的制定並不簡單,不同的人對編程規范也有不同的理解,特別是代碼的使用規范,它要求制定者必須要有豐富的代碼開發以及代碼優化經驗。為了確保規范能夠順利的制定,個人認為需要以先制定后修改的方式進行,先制定是為了不耽誤開發工作,在開發工作開始之前制定好規范即可按規范開發,后修改,其一是在開發過程中發現不合理的地方進行修改(口說無憑,實踐出真理),另外是隨着團隊能力的提高,可以總結更多的代碼使用最佳實踐。
文章的最后介紹了一些常用的規范工具,下篇文章將詳細的介紹.Net平台下的規范工具以其使用。
參考:
https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions
https://docs.microsoft.com/zh-cn/dotnet/standard/security/secure-coding-guidelines#application-code-that-is-not-a-reusable-component
https://orcharddojo.net/orchard-resources/Library/DevelopmentGuidelines/BestPractices/CSharp
https://www.codeproject.com/articles/118853/some-best-practices-for-c-application-development
https://weblogs.asp.net/dixin/csharp-coding-guidelines-1-fundamentals
https://github.com/dotnet/docfx
https://github.com/alibaba/p3c/blob/master/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4Java%E5%BC%80%E5%8F%91%E6%89%8B%E5%86%8C%EF%BC%88%E8%AF%A6%E5%B0%BD%E7%89%88%EF%BC%89.pdf