C#代码规范

1. 引言

本文是一套面向C# programmer 和C# developer 进行开发所应遵循的开发规范。

按照此规范来开发C#程序可带来以下益处:

·         代码的编写保持一致性,

·         提高代码的可读性和可维护性,

·         在团队开发一个项目的情况下,程序员之间可代码共享

·         易于代码的回顾,

本规范是初版,只适用于一般情况的通用规范,并不能覆盖所有的情况。

2. 文件组织

2.1 C# 源文件

类名或文件名要简短,不要超过2000LOC,将代码分割开,使结构清晰。将每个类放在一个单独的文件中,使用类名来命名文件名(当然扩展名是.cs)。这种约定会使大家工作更简单。

2.2 目录设计

为每一个命名空间创建一个目录。(用MyProject/TestSuite/TestTier作为MyProject.TestSuite.TestTier的路径,而不用带点的命名空间名做路径)这样可以更容易地将命名空间映射到目录层次划分。

3. 缩进

3.1 换行

当一个表达式超过一行时,根据这些通用原则进行处理:

·         在逗号后换行。

·         在操作符后换行。

·         在高层换行而不要在低层处换行。

·         折行后对齐上一行语句同一层的表达式起始位置。

方法调用换行示例:
longMethodCall(expr1, expr2,
               expr3, expr4, expr5);

算术表达式换行示例:

推荐:
var = a * b / (c - g + f) +
      4 * z;

不好的格式——应避免:

var = a * b / (c - g +
      f) + 4 * z;

推荐使用第一种方法,因为是在括号表达式之外折行(高层次折行原则)。注意要用制表符到缩进的位置,然后用用空格到折行的位置。在我们的例子中是:

> var = a * b / (c - g + f) +
> ......4 * z;

'>'
表示是制表符,'.'表示是空格符。(制表符后是空白是用制表符缩进)。一个好的编码习惯就是在所用的编辑器中显示制表符和空格符。
3.2 空白

利用空格进行缩进从未有过统一的标准。一些人喜欢用两个空格,一些人喜欢用四个空格而还有一些人喜欢用八个空格,甚至有的人喜欢用更多的空格。好的做法是用制表符。制表符有一些优点:

·         每个人都可以设置他们自己喜欢的缩进层级。

·         它仅仅是1个字符而不是248等等,因此它将减少输入(甚至因为自动缩进,有时你不得不手工设置缩进或取消设置,等等诸如此类的操作)。

·         如果你想增加或减少缩进,可以标记一块,使用Tab增加缩进层级而用Shift-Tab减少缩进层级。这几乎对于任何文本编辑器都是适用的。

这里,我们定义制表符为标准缩进符。

不要用空格缩进—用制表符!
4. 注释

4.1 块注释

块注释通常应该是被避免的。推荐使用///注释作为C#的标准声明。如果希望用块注释时你应该用以下风格:
/* Line 1
* Line 2
* Line 3
*/

因为样可以为读者将注释块与代码块区分开。虽然并不提倡使用C风格的单行注释,但你仍然可以使用。一旦用这种方式,那么在注释行后应有断行,因为很难看清在同一行中前面有注释的代码:
/* blah blah blah */

块注释在极少情况下是有用的。通常块注释用于注释掉大的代码段。

4.2 单行注释

你应该用//注释风格“注释掉”代码(快捷键,Alt+/)。它也可以被用于代码的注释部分。

单行注释被用于代码说明时必须缩进到相应的编进层级。注释掉的代码应该放在第一行被注释掉以使注释掉的代码更容易看清。

一条经验,注释的长度不应该超过被解释代码的长度太长,因为这表示代码过于复杂,有潜在的bug
4.3 文件注释

.net 框架,Microsoft 已经介绍了一个基于XML 注释的文件。这些文件是包括XML 标签的正规的单行的C#注释。他们遵循单行注释的模式:

/// <summary>
/// This class...
/// </summary>

多行XML 注释遵循这种模式:

/// <exception cref=
BogusException>
/// This exception gets thrown as soon as a
/// Bogus flag gets set.
/// </exception>

为了被认作是XML注释行,所有的行都必须用三个反斜线开始。标签有以下两类:

·         文件说明项

·         格式/参考

第一类包括像<summary>, <param> or <exception>的标签。描述一个程序的API元素的这些文档说明项必须写清楚以方便其他程序员。如上面的多行注释示例所示,这些标签通常带有名称或cref属性。编译器会检查这些属性,所以它们必须是有效、正确的。第二类用诸如<code>, <list> or <para>标签,用于控制备注说明的布局。

文件可以用‘文件’菜单中的‘创建’菜单产生。文件以HTML格式产生。

5. 声明

5.1 每行的声明数

推荐每行只有一个声明,因为它可以方便注释。

int level; // indentation level
int size; // size of table

当声明变量时,不要把多个变量或不同类型的变量放在同一行,例如:

int a, b; //What is 'a'? What does 'b' stand for?

上面的例子也显示了变量名不明显的缺陷。当命名变量时要清晰。
5.2 初始化

局部变量一旦被声明就要初始化。例如:

string name = myObject.Name;



int val = time.Hours;

注意:如果你初始化一个dialog,设计使用using语句:

using (OpenFileDialog openFileDialog = new OpenFileDialog()) {
...
}

5.3 类和接口声明

当编写C#类和接口时,应遵循以下格式化规则:

·         在方法名和圆括号“(”开始它的参数列表之间不要使用空格。

·         在声明语句的下一行以大括号"{"标志开始。

·         "}"结束,通过它自身的缩进与相应的开始标志匹配。

例如:

Class MySample : MyClass, IMyInterface
{
        int myInt;
        public MySample(int myInt)
        {
        this.myInt = myInt ;
        }
        void Inc()
        {
                ++myInt;
        }
        void EmptyMethod()
        {
        }
}

对于一个大括号的位置参考10.1部分。

6. 语句

6.1 简单语句

每行都应该只包含一条语句。

6.2 返回语句

一个返回语句不要用最外围圆括号。不用:

return (n * (n + 1) / 2);
用: return n * (n + 1) / 2;

6.3 If, if-else, if else-if else 语句

if, if-else and if else-if else 语句看起来应该像这样:

if (condition) {
     DoSomething();
     ...
}
if (condition) {
     DoSomething();
     ...
} else {
     DoSomethingOther();
     ...
}
if (condition) {
     DoSomething();
     ...
} else if (condition) {
     DoSomethingOther();
     ...
} else {
     DoSomethingOtherAgain();
     ....
}

6.4 for / foreach 语句

一个for语句应该如下形式:

for (int i = 0; i < 5; ++i) {
     ...
}

或者放置一行(考虑用一个while语句代替)

for (initialization; condition; update) ;
foreach
语句应该像下面所示 :
     foreach (int i in IntList) {
     ...
}

注意:在一个循环中,即使只有一个语句通常也用括弧括起来。

6.5 While/do-while 语句

一个while语句应该写成如下形式:

while (condition) {
     ...
}

一个空while语句应该是以下格式:

while (condition) ;

一个do-while语句应该是如下格式:

do
{
     ...
} while (condition);

6.6 Switch 语句

一个switch语句应该如下格式:

switch (condition) {
case A:
     ...
     break;
case B:
     ...
     break;
default:
     ...
     break;
}

6.7 Try-catch 语句

一个try-catch statement语句应该遵循以下格式:

try {
     ...
} catch (Exception) {}
or
try {
     ...
} catch (Exception e) {
     ...
}
or
try {
     ...
} catch (Exception e) {
     ...
} finally {
     ...
}

7. 空白

7.1 空行

空行提高可读性。它们分开那些逻辑上自身相关联的代码块。两行空格行应该用于以下之间:

·         一个源文件的逻辑段。

·         类和接口定义(每个文件只定义一个类或接口以避免这种情况)。

一个空格行应该总是被用于以下之间:

·         方法

·         属性

·         一个方法中的局部变量和它的第一条语句

·         一个方法中的逻辑段为了提高可读性。注意空白行必须被缩进因为它们包括一条语句这使得插入这些行更容易。

7.2 内部空格

在一个逗号或一个分号之后应该由一个空格,例如:

TestMethod(a, b, c);
不要用: TestMethod(a,b,c)



TestMethod( a, b, c );

单个空格包围操作符(除了像加的一元操作符和逻辑非),例:
a = b; // don't use a=b;
for (int i = 0; i < 10; ++i) // don't use for (int i=0; i<10; ++i)

// or
// for(int i=0;i<10;++i)

7.3 表格格式化

行的一个逻辑块应该作为一个表格被格式化:

string name = "Mr. Ed";
int myValue = 5;
Test aTest = Test.TestYou;

对于表格的格式化用空格而不用制表符因为在某些制表符缩进设置会使表格格式化看起来是很奇怪。

8. 命名习惯

8.1 大写格式

8.1.1 Pascal Casing

习惯大写每个单词的第一个字母(就像在TestCounter)。

8.1.2 Camel Casing

习惯除了第一个单词外大写每个单词的第一个字母例如testCounter

8.1.3 全大写情况

对于只有一两个字符缩写组成的标识符才用全大写的情况。有三个或更多个字符组成的标识符应该用Pascal情况代替。例如:

public class Math
{
     public const PI = ...
     public const E = ...
     public const feigenBaumNumber = ...
}

8.2. 命名指导方针

通常根据指导方针在名字和命名内用低线字符对Hungarian 符号来说被认为是坏习惯。

Hungarian 符号是一组应用于命名来映射变量类型的前缀和后缀。这种命名风格在早期的Windows程序中被广泛应用,但现在被取消了至少不提倡了。如果你遵循这个指南用Hungarian 符号是不允许的。

但要记住一个好的变量名描述了语义而不失类型。

对于这个规则有个例外就是GUI编码。包括像按钮(buttton)的GUI元素,所有领域和变量名都应该带有它们类型名的后缀不是缩写。例如:


System.Windows.Forms.Button cancelButton;
System.Windows.Forms.TextBox nameTextBox;

8.2.1 类命名指导方针

·         类命名必须是名词或名词短语。

·         UsePascal 情况参考8.1.1

·         不要用任何类前缀

8.2.2 接口命名指导方针Guidelines

·         用可以描述行为的名词或名词短语或形容词命名接口。(例如IComponent IEnumberable

·         Pascal情况(参考8.1.1

·         I作为名字的前缀,它应该紧跟一个大写字母(接口名的第一个字母)

8.2.3 枚举命名指导方针

·         Pascal情况命名枚举值名字和类型名字

·         枚举类型和枚举值不要前缀

·         对于枚举用单一名字

·         对于位领域用复数名字

8.2.4 只读和常量命名

·         用名词,名词短语或名词的缩写命名静态领域

·         使用Pascal 情况(参考8.1.1

8.2.5 参数/非常量领域命名

·         一定要用描述性名字,应该能够足够表现变量的意义和它的类型。但一个好的名字应该基于参数的意义。

·         使用Camel情况(参考8.1.2

8.2.6 变量命名

·         计数变量当用在琐碎的计数循环式更适宜叫i, j, k, l, m, n。(参考10.2例如对全局计数的更智能命名等等)—

·         使用Camel情况(参考8.1.2

8.2.7 方法命名

·         用动词或动词短语命名方法。

·         使用Pascal(参考8.1.2

8.2.8 属性命名

·         用名词或名词短语命名属性

·         使用Pascal 情况(参考8.1.2

·         考虑用与其类型相同的名字命名一个属性

8.2.9 事件命名

·         用事件处理器后缀命名事件处理器

·         sender e命名两个参数

·         使用Pascal情况(参考8.1.1

·         EventArgs 后缀命名事件参数

·         用现在和过去时态命名有前缀和复制概念的事件名字。

·         考虑用一个动词命名事件。

8.2.10 大写总结

Type

Case

Notes

Class / Struct

Pascal Casing

 

Interface

Pascal Casing

Starts with I

Enum values

Pascal Casing

 

Enum type

Pascal Casing

 

Events

Pascal Casing

 

Exception class

Pascal Casing

End with Exception

public Fields

Pascal Casing

 

Methods

Pascal Casing

 

Namespace

Pascal Casing

 

Property

Pascal Casing

 

Protected/private Fields

Camel Casing

 

Parameters

Camel Casing

 

9. 编程习惯

9.1 可见性

不要任何公共实例或类变量,让它们为私有的。对于私有成员最好不用“private”作修饰语什么都不写。私有是默认情况,每个C#程序员都应该知道这一点。

用属性代替。你可以用公共静态(或常量)对于这个规则是以例外,带它不应该是规则。

9.2 没有“幻”数

不要用幻数,也就是在源代码中直接用常数值。替代这些后者以防变化(比方说,你的应用程序可以处理3540用户代替427你的代码在50行中通过分散25000LOC)是错误和没有收益的。声明一个带有数的常量来代替:


public class MyMath
{
     public const double PI = 3.14159...
}

10. 编码举例

10.1 Brace placement example


namespace ShowMeTheBracket
{
     public enum Test {
     TestMe,
     TestYou
}
public class TestMeClass
{
     Test test;
     public Test Test {
     get {
     return test;
     }
     set {
     test = value;
     }
}
     void DoSomething()
     {
          if (test == Test.TestMe) {
               //...stuff gets done
          } else {
               //...other stuff gets done
          }
     }
}
}

括弧应该在以下情况之后以新行开始:

·         命名空间声明(注意这在0.3版本中是新添的与0.2版本不同)

·         /接口/结构声明

·         方法声明

10.2 变量命名举例

代替:

for (int i = 1; i < num; ++i) {
meetsCriteria[i] = true;
}
for (int i = 2; i < num / 2; ++i) {
int j = i + i;
while (j <= num) {
meetsCriteria[j] = false;
j += i;
}
}
for (int i = 0; i < num; ++i) {
if (meetsCriteria[i]) {
Console.WriteLine(i + " meets criteria");
}
}
try intelligent naming :
for (int primeCandidate = 1; primeCandidate < num; ++primeCandidate)
{
isPrime[primeCandidate] = true;
}
for (int factor = 2; factor < num / 2; ++factor) {
int factorableNumber = factor + factor;
while (factorableNumber <= num) {
isPrime[factorableNumber] = false;
factorableNumber += factor;
}
}
for (int primeCandidate = 0; primeCandidate < num; ++primeCandidate)
{
if (isPrime[primeCandidate]) {
Console.WriteLine(primeCandidate + " is prime.");
}
}

注意:索引变量通常i, j, k 等等。但Note: Indexer variables generally should be called i, j, k etc. But 万一像这样,使得重新考虑这个原则更有意义。一般来说,当同一个计数器或索引器被重用,给它们有意义的名字。

 

   转自http://www.cnblogs.com/shenzhenzsw/articles/1285638.html

转载于:https://www.cnblogs.com/LeeYongze/archive/2009/11/05/1596891.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/349718.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌guava_使用Google Guava进行馆藏创建和不变性

谷歌guava因此&#xff0c;我想看看番石榴提供的一些集合创建模式&#xff0c;以及它提供的某些不可变集合类型。 如果您没有看过我以前的文章&#xff0c;则可能要从这里开始&#xff1a; 番石榴第1部分– MultiMaps 番石榴第2部分– BiMaps 番石榴第3部分–多组 Guava的…

问题 1051: [编程入门]结构体之成绩统计2

题目描述有N个学生&#xff0c;每个学生的数据包括学号、姓名、3门课的成绩&#xff0c;从键盘输入N个学生的数据&#xff0c;要求打印出3门课的总平均成绩&#xff0c;以及最高分的学生的数据&#xff08;包括学号、姓名、3门课成绩&#xff09;输入学生数量N占一行每个学生的…

socket-02

# -- coding: utf-8 --_author__ "HuaQiang Yan" import socketdef handle_request(client):buf client.recv(1024) # 接收请求client.send(bytes("HTTP/1.1 200 OK\r\n\r\n", encodingutf-8))client.send(bytes("Hello World&#xff01;", …

jenkins复制作业_Jenkins分层作业和作业状态汇总

jenkins复制作业您可能知道&#xff0c;Jenkins是高度可配置的CI服务器。 我们可以设置不同的自定义构建过程。 我将分享一些我用来设置詹金斯工作层次的方法。 这是用例&#xff1a; 我们有一个主要的入口工作被调用以启动整个构建过程。 这项工作可以有一个到多个子工作。 …

xaml语言建立首个win8 Metro应用,rss阅读器

本实例是来源msdn的Metro开发文档&#xff0c;按着解说一步步来理解的&#xff0c;修改了一点点&#xff0c;拿了博客园本人的博客作为RSS阅读&#xff0c;本实例用来学习还是可以的 参考文档http://msdn.microsoft.com/zh-cn/library/windows/apps/br211380.aspx#Y909 先看允…

在扩展Spock时输出给定值

Spock是一个Java测试框架&#xff0c;由GradleWare的软件工程师Peter Niederwieser于2008年创建&#xff0c;它可以促进BDD的发展。 利用这个 例如 &#xff0c;一个故事可以定义为&#xff1a; Story: Returns go to stockAs a store owner In order to keep track of stock…

wsgi

wsgi&#xff0c;通用网关接口。相当于在app与web服务&#xff08;socket服务端&#xff09;之间建立统一连接的规范。 真实开发中的python web程序来说&#xff0c;一般会分为两部分&#xff1a;服务器程序和应用程序。服务器程序负责对socket服务器进行封装&#xff0c;并在请…

Java与Python:哪一种最适合您? [信息图]

通过从应用程序中学习企业APM产品&#xff0c;发现更快&#xff0c;更高效的性能监控。 参加AppDynamics APM导览&#xff01; 在软件开发中&#xff0c;很少有问题比选择编程语言更具分裂性或部落性。 软件开发人员经常以自己选择的工具来强烈地认同自己&#xff0c;将客观事…

零基础学习java------day11------常用API

API概述 API(application Programming Interface, 应用程序编程接口)&#xff0c;是一些预先定义的函数。目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力&#xff0c;而又无需访问源码&#xff0c;或理解内部工作机制的细节 比如我需要在一个程序里面嵌入…

.net 下的集合

集合的操作在编码的时候很常见。但是由于经常使用几种集合。而忽略了一些不常用的集合。在这里我整理下。 首先先了解下接口&#xff1a; 1、IEnumerable&#xff0c;返回一个循环访问集合的枚举器。 2、IEnumerable<T>&#xff0c;返回一个循环访问指定集合T的枚举器。 …

aspects_具有Aspects的Java中的Mixin –用于Scala特性示例

aspectsScala特征允许将新行为混合到一个类中。 考虑两个特征&#xff0c;可以向JPA实体添加审核和与版本相关的字段&#xff1a; package mvcsample.domainimport javax.persistence.Version import scala.reflect.BeanProperty import java.util.Datetrait Versionable {Ver…

TCP服务端实现并发

socket 在 tcp 协议下通信 客户端 import socket ​ # 创建客户端TCP协议通信 c socket.socket() # 与指定服务端握手 c.connect((127.0.0.1, 8080)) ​ # 通信循环 while True:# 向服务端发送信息msg input(>>>)if len(msg) 0:continuec.send(msg.encode(utf-8))#…

问题 1052: [编程入门]链表合并

题目描述已有a、b两个链表&#xff0c;每个链表中的结点包括学号、成绩。要求把两个链表合并&#xff0c;按学号升序排列。 输入第一行&#xff0c;a、b两个链表元素的数量N、M,用空格隔开。 接下来N行是a的数据 然后M行是b的数据 每行数据由学号和成绩两部分组成 输出按照学号…

ssh 看apache_使用Apache KeyedObjectPool的ssh连接池

ssh 看apache我发现org.apache.commons.pool非常有用且健壮&#xff0c;但没有充分记录。 因此&#xff0c;我将在这里帮助您解释如何使用Apache KeyedObjectPool 。 什么是KeyedObjectPool &#xff1f; 它是一个映射&#xff0c;其中包含多种类型的实例池。 可以使用任意键访…

问题 1066: 2004年秋浙江省计算机等级考试二级C 编程题(2)

题目描述输入一个正数x和一个正整数n&#xff0c;求下列算式的值。要求定义两个调用函数&#xff1a;fact(n)计算n的阶乘&#xff1b;mypow(x,n)计算x的n次幂&#xff08;即xn&#xff09;&#xff0c;两个函数的返回值类型是double。 x - x2/2! x3/3! ... (-1)n-1xn/n! 输出…

Ubuntu16.04下安装多版本cuda和cudnn

Ubuntu16.04下安装多版本cuda和cudnn 原文 https://blog.csdn.net/tunhuzhuang1836/article/details/79545625 前言因为之前针对Pytorch&#xff0c;caffe&#xff0c;torch等&#xff0c;装了cuda8.0和对应cudnn5.1&#xff0c;但是最近在装MxNet的时候&#xff0c;发现官网上…

什么是javax.ws.rs.core.context? [ 第1部分 ]

如何使用Context批注 JAX-RS API提供了一种非常方便的机制&#xff0c;可以将各种有用的资源&#xff08;例如HTTP标头&#xff09;注入到端点中。 Context注释是一个通用注释&#xff0c;它注入以下对象的实例&#xff1a; HttpHeaders- > HTTP标头参数和值 UriInfo- >…

spring的事件

理论 异步的实现方式可以使用事件&#xff0c;或者异步执行&#xff1b; spring中自带了事件的支持&#xff0c;核心是ApplicationEventPublisher; 事件包括三个要点&#xff1a; 事件的定义&#xff1b;事件监听的定义&#xff1b;发布事件&#xff1b;实战 代码路径&#xff…

[多项式算法]多项式求逆 学习笔记

多项式求逆 和整数的乘法逆元定义类似&#xff0c;对于多项式\(A(x)B(x)1\)&#xff0c;则称\(A(x),B(x)\)互为乘法逆元。 \(A(x)\)存在乘法逆元的充要条件是\([x^0]A(x)\)存在乘法逆元。 现在思考如何用\(O(n\log n)\)的时间计算\(A(x)\)的乘法逆元&#xff1a; 考虑倍增&…

java jax-rs_在Java EE 6中将Bean验证与JAX-RS集成

java jax-rsJavaBeans验证&#xff08;Bean验证&#xff09;是Java EE 6平台的一部分提供的新验证模型。 约束通过以JavaBeans组件&#xff08;例如托管Bean&#xff09;的字段&#xff0c;方法或类上的注释形式的约束来支持Bean验证模型。 javax.validation.constraints包中提…