鼎鼎知识库
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

2020.10.25代码规范.md 13KB

vor 4 Jahren
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. > 本篇代码规范中的C#部分源自苏州盛派网络科技有限公司创始人Jeffrey Su的《C#编码规范》,本篇是在Markdown下的复述和实践,并且加入前端和手机端的代码规范。
  2. # 1、概述
  3. > 1.1 为什么需要代码规范
  4. - 便于团队协作和维护
  5. - 方便阅读
  6. - 美观
  7. > 1.2 类型
  8. - Pascal: BackColor
  9. - Camel: backColor
  10. 建议后端使用Pascal规范,前端使用Camel规范。
  11. # 2、代码外观
  12. > 2.1 每行字符数
  13. 不超过110个字符。
  14. > 2.2 换行
  15. 当每行即将超出110个字符时,优先在逗号后换行,其次在操作符前换行。
  16. > 2.3 缩进
  17. 4个空格。
  18. Viusal Studio可在文本编辑器中设置。
  19. > 2.4 空行
  20. 以下情况空两行
  21. ```
  22. --接口和类的定义之间
  23. --枚举和类的定义之间
  24. --类与类的定义之间
  25. ```
  26. 以下情况空一行
  27. ```
  28. --方法与方法之间
  29. --属性与属性之间
  30. --方法中变量声明与语句之间
  31. --方法的不同逻辑块之间
  32. --方法的返回语句与其它语句之间
  33. --属性与方法之间
  34. --属性与字段之间
  35. --方法与字段之间
  36. --注释与其它语句间
  37. ```
  38. > 2.5 空格
  39. 关键字和左括号之间用空格
  40. ```
  41. while (true)
  42. ```
  43. 方法名和左括号之间不使用空格
  44. ```
  45. SayHello(string name)
  46. ```
  47. 方法中的多个参数用逗号隔开,每个逗号后加一个空格
  48. ```
  49. ShowMessage(string name, int age)
  50. ```
  51. 二元操作符需要用空格和其后面的操作数隔开
  52. ```
  53. a += c + d;
  54. a = (a + b) / (c * d);
  55. ```
  56. 一元操作符、++、--与操作数之间不需要空格
  57. ```
  58. n++
  59. ```
  60. 语句中的表达式之间用空格隔开
  61. ```
  62. foreach(Person p in People)
  63. ```
  64. > 2.6 括号
  65. 左括号不要紧靠关键字,中间用一个空格隔开
  66. ```
  67. if (a > 0)
  68. ```
  69. 方法名之后的左括号不需要空格
  70. ```
  71. void SayHello(string name)
  72. ```
  73. > 2.7 花括号
  74. 左括号`{`放在关键字或方法名的下一行并与之对齐
  75. ```
  76. if (true)
  77. {
  78. }
  79. public int Add(int x, int y)
  80. {
  81. }
  82. ```
  83. 左括号与右括号对齐。
  84. 左括号单独成行,不与任何语句并列一行。
  85. 右括号建议加一个注释,方便找到与之对应的左括号。
  86. ```
  87. while (true)
  88. {
  89. if (isValid == true)
  90. {
  91. }//ifvalid
  92. else
  93. {
  94. }//not valid
  95. }//end forever
  96. ```
  97. # 3、注释
  98. - 修改代码的同时,也需要修改注释
  99. - 注释内容:有关用途、假设、限制、为什么存在等
  100. - 注释不应该产生多义:阐明代码就足够,不如注释中不该出现幽默
  101. - 注释中的印刷框:不推荐
  102. - 无关注释:在发布之前去掉
  103. - 对代码段的注释过于复杂:建议重构代码段
  104. - 对错误的修复和解决方法:建议使用注释
  105. > 3.1 文档型注释
  106. 在接口、类、方法、属性、字段中使用注释,方便阅读和生成代码文档。
  107. ```
  108. ///<summary>
  109. ///<para>
  110. ///this is description
  111. ///</para>
  112. ///</summary>
  113. ```
  114. > 3.2 不再使用或者临时屏蔽的代码。
  115. ```
  116. /*
  117. [修改标识]
  118. [修改原因]
  119. */
  120. ```
  121. > 3.3 单行注释
  122. ```
  123. //this is comment
  124. private int number;
  125. if(a=='')//always true
  126. {
  127. }//always true
  128. ```
  129. > 3.4 C#中的注释标签
  130. - 将说明中的文本标记为代码.
  131. ```
  132. <c>contentt</c>
  133. ```
  134. - <remarks>或<returns>等标记内的<para>
  135. ```
  136. <para>content</para>
  137. ```
  138. - 描述方法参数
  139. ```
  140. <param name='name'>description</param>
  141. ```
  142. - paramref
  143. ```
  144. <paramref name="name" />
  145. ```
  146. - see
  147. ```
  148. <see cref="memeber" />
  149. ```
  150. - seealso
  151. ```
  152. <seealso cref="member" />
  153. ```
  154. - example
  155. ```
  156. <example>description</example>
  157. ```
  158. - code
  159. ```
  160. <code>content</code>
  161. ```
  162. - summary
  163. ```
  164. <summary>description</summary>
  165. ```
  166. - exception
  167. ```
  168. <exception cref="member">description</exception>
  169. ```
  170. - include
  171. - list
  172. - permission
  173. - remarks
  174. - returns
  175. - value
  176. # 4、申明
  177. > 4.1 每行声明一个变量,并按字母顺序排列
  178. ```
  179. int level;//remark
  180. int size;//remark
  181. ```
  182. > 4.2 变量声明时初始化
  183. ```
  184. int a = 0;
  185. ```
  186. > 4.3 变量放在代码块的开始处
  187. ```
  188. void MyMethod()
  189. {
  190. int a = 0;
  191. ...
  192. }
  193. ```
  194. # 5、命名规范
  195. - 避免多义: AnalyzeThis()不推荐
  196. - 属性名称不需要包含类名:Book.BookTitle,不推荐
  197. - 在变量名称末尾或开头加计算限定符:MyAvg
  198. - 在变量名中使用互补配对:min/max, begin/end, open/close
  199. - bool类型变量名加is: isEnabled
  200. - 状态变量,具有多个可能的状态:documentType
  201. - 在循环中带上语义
  202. ```
  203. int NUM_DAYS_IN_WEEK = 10;
  204. for (int i = 0; i <=NUM_DAYS_IN_WEEK; i++)
  205. {
  206. }
  207. ```
  208. > 5.1 大小写规则
  209. - 类:AppDomain
  210. - 枚举类型:ErrorLevel
  211. - 枚举值:FatalError
  212. - 事件:ValueChanged
  213. - 异常类:WebException
  214. - 只读静态字段:RedValue
  215. - 接口:IDisposable
  216. - 方法:ToString
  217. - 命名空间:System.Drawing
  218. - 属性:BackColor
  219. - 公共实例字段:RedValue
  220. - 受保护的实例字段:redValue
  221. - 私有的实例字段:redValue
  222. - 参数:typeName
  223. - 方法内的变量:backColor
  224. > 5.2 缩写
  225. - 计算机领域未被普遍接受的缩写:不推荐用
  226. - 计算机领域众所周知的缩写:推荐用。比如UI作为User Interface的缩写
  227. - 仅有两个字符的缩写:两个字符都大写。比如System.IO
  228. - 超出两个字符的缩写:使用Pascal或Camel。比如HtmlButton
  229. - 参数名称中可以缩写吗:不推荐
  230. > 5.3 命名空间
  231. - 格式:CompanyName.TechnologyName或ProjectName.[.Feature][.Design]
  232. - 命名空间和类不能使用同样的名字
  233. > 5.4 类
  234. - 使用Pascal:MyClass
  235. - 使用名称或名词短语
  236. - 避免缩写,除非缩写是大众周知的
  237. - 不使用类型前缀,推荐使用`FileStream`,不推荐使用`CFileStream`
  238. - 不推荐使用下划线
  239. - 有时可以以I开头:IdentityStore
  240. - 派生类的第二部分是基类名称:`ApplicationException`
  241. > 5.5 接口
  242. - 使用描述性名词:`IComponent`
  243. - 使用名词短语:`ICustomAttributeProvider`
  244. - 使用形容词:`IPersistable`
  245. - 使用Pascal:
  246. - 少用缩写
  247. - I前缀
  248. - 不要使用下划线
  249. > 5.6 特性
  250. ```
  251. public class ObsoleteAttribute
  252. {}
  253. ```
  254. > 5.7 枚举
  255. - 使用Pascal
  256. - 少用缩写
  257. - 不要在Enum类型名称上使用Enum后缀
  258. - 对大多数Enume类型使用单数名称
  259. > 5.8 参数
  260. - 具有描述性
  261. - 使用Camel
  262. - 不要使用保留参数
  263. > 5.9 方法
  264. - 使用动词或动词短语
  265. - 使用Pascal
  266. > 5.10 属性
  267. - 使用名词或名词短语
  268. - 使用Pascal
  269. > 5.11 事件
  270. - 事件处理程序名称使用EvengHandler后缀
  271. - 使用`sender`和`e`两个参数,`sender`表示引发事件的对象,`sender`的参数类型始终是`object`类型,即使在可以使用特定类型时也如此。与事件相关的状态封装在名为`e`的参数中,对`e`参数类型使用适当而特定的事件类。
  272. - 用`EventArgs`后缀命名事件参数类
  273. - 使用动词命名事件
  274. - 使用进行时:`Closing`
  275. - 使用过去式:`Closed`
  276. - 不要使用BeforeXxx/AfterXxx命名模式
  277. - 不要在类型的事件申明上使用前缀或后缀。比如,使用`Close`,不使用`OnClose`
  278. - 在派生类中可以重写的事件,应在类型上提供一个受保护的方法,比如`OnXxx`
  279. 定义事件处理程序:
  280. ```
  281. public delegate void MouseEventHandler(object sender, MouseEventArgs e);
  282. public class MouseEventArgs : EventArgs
  283. {
  284. int x;
  285. int y;
  286. public MouseEventArgs(int x, int y)
  287. {
  288. this.x = x;
  289. this.y = y;
  290. }
  291. public int X
  292. {
  293. get{
  294. return x;
  295. }
  296. }
  297. public int Y
  298. {
  299. get
  300. {
  301. return y;
  302. }
  303. }
  304. }
  305. ```
  306. > 5.12 常量
  307. 所有单词大写,多个单词之间用`_`分隔。
  308. ```
  309. public const string Page_Title = "Welcome";
  310. ```
  311. > 5.13 字段
  312. - private, protected类型的字段使用Camel
  313. - public类型的字段使用Pascal
  314. - 不轻易使用缩写,除非是众所周知的缩写
  315. - 字段名称前不加前缀。比如,`g_`或`s_`
  316. - 公共静态只读字段
  317. ```
  318. public struct Color
  319. {
  320. public static readonly Color Red = new Color();
  321. public Color(int rgb)
  322. {
  323. public Color(byte r, byte g, byte, b)
  324. {
  325. }
  326. }
  327. }
  328. ```
  329. > 5.14 静态字段
  330. - 使用名词、名词短语或者名词缩写
  331. - 使用Pascal
  332. > 5.15 集合
  333. 建议使用复数。
  334. > 5.16 措词
  335. 不要将以下名称作为类名称:
  336. ```
  337. AddHandler AddressOf Alias And Ansi
  338. As Assembly Auto Base Boolean
  339. ByRef Byte ByVal Call Case
  340. Catch CBool CByte Cchar CDate
  341. CDec CDbl Char Cint Class
  342. CLng CObj Const Cshort CSng
  343. CStr CType Date Decimal Declare
  344. Default Delegate Dim Do Double
  345. Each Else ElseIf End Enum
  346. Erase Error Event Exit ExternalSource
  347. False Finalize Finally Float For
  348. Friend Function Get GetType Goto
  349. Handles If Implements Imports In
  350. Inherits Integer Interface Is Let
  351. Lib Like Long Loop Me
  352. Mod Module MustInherit MustOverride MyBase
  353. MyClass Namespace New Next Not
  354. Nothing NotInheritable NotOverridable Object On
  355. Option Optional Or Overloads Overridable
  356. Overrides ParamArray Preserve Private Property
  357. Protected Public RaiseEvent ReadOnly ReDim
  358. Region REM RemoveHandler Resume Return
  359. Select Set Shadows Shared Short
  360. Single Static Step Stop String
  361. Structure Sub SyncLock Then Throw
  362. To True Try TypeOf Unicode
  363. Until volatile When While With
  364. WithEvents WriteOnly Xor Eval extends
  365. instanceof package var
  366. ```
  367. # 6、语句
  368. > 6.1 每行一个语句
  369. > 6.2 复合语句
  370. - 子语句要缩进
  371. - 左花括号在父语句的下一行并与之对齐,单独成行
  372. - 即使只有一条子语句也不要省略花括号
  373. ```
  374. while (d += s++)
  375. {
  376. n++;
  377. }
  378. ```
  379. > 6.3 return语句
  380. return语句不使用括号,除非能使返回值更加清晰。
  381. > 6.4 if, if-else, if else-if
  382. ```
  383. if (condition)
  384. {
  385. }
  386. if (condition)
  387. {
  388. }
  389. else
  390. {
  391. }
  392. if (condition)
  393. {
  394. }
  395. else if (condition)
  396. {
  397. }
  398. else
  399. {
  400. }
  401. ```
  402. > 6.5 for, foreach语句
  403. ```
  404. for (initialization; condition; update)
  405. {
  406. }
  407. foreach (object obj in array)
  408. {
  409. }
  410. ```
  411. > 6.6 while
  412. ```
  413. while (condition)
  414. {
  415. }
  416. while (condition);
  417. ```
  418. > 6.7 do-while
  419. ```
  420. do
  421. {
  422. } while (condition);
  423. ```
  424. > 6.8 switch-case
  425. ```
  426. switch (condition)
  427. {
  428. case 1:
  429. statements;
  430. break;
  431. case 2:
  432. statements;
  433. break;
  434. default:
  435. statements;
  436. break;
  437. }
  438. ```
  439. > 6.9 try-catch
  440. ```
  441. try
  442. {
  443. }
  444. catch (ExceptionClass ex)
  445. {
  446. }
  447. finally
  448. {
  449. }
  450. ```
  451. > 6.10 using
  452. ```
  453. using (object)
  454. {
  455. }
  456. ```
  457. > 6.11 got
  458. ```
  459. goto Label1:
  460. statements;
  461. Label:
  462. statements;
  463. ```
  464. # 7、其它
  465. > 7.1 文件头标注
  466. 文件头顶格(没有空行或空格),放置协议或关键说明
  467. ```
  468. #region Apache License Version 2.0
  469. /*----------------------------------------------------------------
  470. Copyright 2017 Jeffrey Su & Suzhou Senparc Network Technology Co.,Ltd.
  471. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
  472. except in compliance with the License. You may obtain a copy of the License at
  473. http://www.apache.org/licenses/LICENSE-2.0
  474. Unless required by applicable law or agreed to in writing, software distributed under the
  475. License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  476. either express or implied. See the License for the specific language governing permissions
  477. and limitations under the License.
  478. Detail: https://github.com/JeffreySu/WeiXinMPSDK/blob/master/license.md
  479. ----------------------------------------------------------------*/
  480. #endregion Apache License Version 2.0
  481. ```
  482. 紧跟协议或关键说明,为文件说明及版本更新内容
  483. 如:
  484. ```
  485. /*----------------------------------------------------------------
  486. Copyright (C) 2017 Senparc
  487. 文件名:ModifyDomainApi.cs
  488. 文件功能描述:修改域名接口
  489. 创建标识:Senparc - 20170601
  490. 修改标识:Senparc - 20171201
  491. 修改描述:v1.7.3 修复ModifyDomainApi.ModifyDomain()方法判断问题
  492. 修改标识:Senparc - 20171231
  493. 修改描述:v1.7.4 更新API地址
  494. ----------------------------------------------------------------*/
  495. ```
  496. 创建
  497. ```
  498. 其中“文件名”“文件功能描述”及“创建标识”必须在文件创建时时填写。
  499. “创建标识”上下各空 2 行。
  500. ```
  501. 修改
  502. ```
  503. 每次更新文件必须填写“修改标识”及对应的“修改描述”。“修改标识”下,需要填写“修改人”和“时间”,使用“ - ”分隔。
  504. 每次修改填写的一组“修改标识”和“修改描述”中间不空行,每组修改信息上下各空 1 行(第一次修改是,上方空 2 行,配合“创建标识”标准)。
  505. ```
  506. > 7.2 异步方法标记
  507. 严格按照以下换行格式:
  508. ```
  509. #if !NET35 && !NET40
  510. #region 异步方法
  511. /// <summary>
  512. /// 【异步方法】修改服务器地址 接口
  513. /// </summary>
  514. public static async Task<ModifyDomainResultJson> ModifyDomainAsync()
  515. {
  516. //...
  517. }
  518. #endregion
  519. #endif
  520. ```
  521. > 重点注意:<br>
  522. > 1、`#if` 和 `#region 异步方法` 中间没有空行,结束标签也是如此。<br>
  523. > 2、方法名称备注的 summary 信息必须以 `【异步方法】` 开头。<br>
  524. > 3、 #region 的下一行、#endregion 的上一行,应该为空行。