.NET编程规范

时间:2024-07-26 18:34:44

.NET开发编程规范

第1章 程序的版式

版式虽然不会影响程序的功能,但会影响可读性。程序的版式追求清晰、美观,是程序风格的重要构成因素。

可以把程序的版式比喻为"书法"。好的"书法"可让人对程序一目了然,看得兴致勃勃。差的程序"书法"如螃蟹爬行,让人看得索然无味,更令维护者烦恼有加。

1.1 版本和版权声明

版本和版权的声明写在文件的开头,包含内容如下:

1、 版权信息

2、 摘要

3、 当前版本

4、 作者

5、 修改作者

6、 完成日期

7、 版本历史信息

例:

///<copyright> Copyright (c) 2006,有限公司</copyright>

///<copyright> All rights reserved.</copyright>

///<abstract>描述文件的内容,实现的功能和算法等内容</abstract>

///<current_version>当前版本</current_version>

///<author>作者</author>

///<finish_date>完成日期</finish_date>

///<replace_version>取代版本</replace_version>

///<modify>修改</modify>

///<modify_author>修改作者</modify_author>

///<modify_date>修改日期</modify_date>

版本版权声明示例

在C#中代码注释这样写的好处是Visual Stuidio能够在编译的时候自动生成xml格式的注释文档。

1.2空行

空行起着分隔程序段落的作用。空行得体(不过多也不过少)将使程序的布局更加清晰。空行不会浪费内存,虽然打印含有空行的程序是会多消耗一些纸张,但是值得。所以不要舍不得用空行。

在每个类声明之后、每个函数定义结束之后都要加空行。参见示例1-2(a)在一个函数体内,逻揖上密切相关的语句之间不加空行,其它地方应加空行分隔。参见示例1-2(b )

// 空行

void Function1(…)

{

}

// 空行

void Function2(…)

{

}

// 空行

void Function3(…)

{

}

// 空行

while (condition)

{

statement1;

// 空行

if (condition)

{

statement2;

}

else

{

statement3;

}

// 空行

statement4;

}

示例1-2(a) 函数之间的空行                  示例1-2(b) 函数内部的空行

1.3 代码行

(1)一行代码只做一件事情,如只定义一个变量,或只写一条语句。这样的代码容易阅读,并且方便于写注释。

(2)if、for、while、do等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加{}。这样可以防止书写失误。

示例1-3(a)为风格良好的代码行,示例1-3(b)为风格不良的代码行。

int width; // 宽度

int height; // 高度

int depth; // 深度

int width, height, depth;

// 宽度高度深度

x = a + b;

y = c + d;

z = e + f;

X = a + b;   y = c + d; z = e + f;

if (width < height)

{

dosomething();

}

if (width < height) dosomething();

for (initialization; condition; update)

{

dosomething();

}

// 空行

other();

for (initialization; condition; update)

dosomething();

other();

示例1-3(a) 风格良好的代码行                示例1-3(b) 风格不良的代码行

【建议】尽可能在定义变量的同时初始化该变量(就近原则)

如果变量的引用处和其定义处相隔比较远,变量的初始化很容易被忘记。如果引用了未被初始化的变量,可能会导致程序错误。本建议可以减少隐患。例如

int width = 10;     // 定义并初绐化width

int height = 10;    // 定义并初绐化height

int depth = 10;     // 定义并初绐化depth

1.4 代码行内的空格

(1)关键字之后要留空格。象const、case 等关键字之后至少要留一个空格,否则无法辨析关键字。象if、for、while等关键字之后应留一个空格再跟左括号'(',以突出关键字。

(2)函数名之后不要留空格,紧跟左括号'(',以与关键字区别。

(3)'('向后紧跟,')'、','、';'向前紧跟,紧跟处不留空格。

(4)','之后要留空格,如Function(x, y, z)。如果';'不是一行的结束符号,其后要留空格,如for (initialization; condition; update)。

(5)赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如"="、"+=" ">="、"<="、"+"、"*"、"%"、"&&"、"||"、"<<","^"等二元操作符的前后应当加空格。

(6)一元操作符如"!"、"~"、"++"、"--"、"&"(地址运算符)等前后不加空格。

(7)象"[]"、"."、"->"这类操作符前后不加空格。

(8)对于表达式比较长的for语句和if语句,为了紧凑起见可以适当地去掉一些空格,如for (i=0; i<10; i++)和if ((a<=b) && (c<=d))

示例1-4 代码行内的空格

void Func1(int x, int y, int z)

void Func1 (int x,int y,int z)

if (year >= 2000)

if(year>=2000)

if ((a>=b) && (c<=d))

if(a>=b&&c<=d)

for (i=0; i<10; i++)

for(i=0;i<10;i++)

x = a < b ? a : b;

x=a<b?a:b;

示例1-4(a) 风格良好的代码行                示例1-4(b) 风格不良的代码行

1.5 对齐

(1)程序的分界符'{'和'}'应独占一行并且位于同一列,同时与引用它们的语句左对齐。

(2){ }之内的代码块在'{'右边数格处左对齐。

void Function(int x)

{

… // program code

}

void Function(int x){

… // program code

}

if (condition)

{

… // program code

}

else

{

… // program code

}

if (condition){

… // program code

}

else {

… // program code

}

for (initialization; condition; update)

{

… // program code

}

for (initialization; condition; update){

… // program code

}

While (condition)

{

… // program code

}

while (condition){

… // program code

}

如果出现嵌套的{},则使用缩进对齐,如:

{

{

}

}

示例1-5(a) 风格良好的对齐                      示例1-5(b) 风格不良的对齐

1.6长行拆分

代码行最大长度宜控制在70至80个字符以内。代码行不要过长,否则眼睛看不过来,也不便于打印。

长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要进行适当的缩进,使排版整齐,语句可读。

if ((very_longer_variable1 >= very_longer_variable12)

&& (very_longer_variable3 <= very_longer_variable14)

&& (very_longer_variable5 <= very_longer_variable16))

{

dosomething();

}

for (very_longer_initialization;

very_longer_condition;

very_longer_update)

{

dosomething();

}

示例1-6 长行的拆分

1.7 注释

C#语言中,程序块的注释常采用"/*…*/",行注释一般采用"//…"。注释通常用于:

(1)版本、版权声明;

(2)函数接口说明;

(3)重要的代码行或段落提示。

(4) 虽然注释有助于理解代码,但注意不可过多地使用注释。

(5)注释是对代码的"提示",而不是文档。程序中的注释不可喧宾夺主,注释太多了会让人眼花缭乱。注释的花样要少。

(6)如果代码本来就是清楚的,则不必加注释。否则多此一举,令人厌烦。例如

i++;  // i 加 1,多余的注释

(7)边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。不再有用的注释要删除。

(8)注释应当准确、易懂,防止注释有二义性。错误的注释不但无益反而有害。

(9)尽量避免在注释中使用缩写,特别是不常用缩写。

(10)注释的位置应与被描述的代码相邻,可以放在代码的上方或右方,不可放在下方。

(11)当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注释,便于阅读。

/*

* 函数介绍:

* 输入参数:

* 输出参数:

* 返回值 :

*/

void Function(float x, float y, float z)

{

}

if (…)

{

while (…)

{

} // end of while

} // end of if

示例1-7 程序的注释

第2章 命名规则

所有标识符的命名必须遵循如下三种大小写规范进行命名:

风格

说明

样例

Pascal 大小写

首字母大写,且后续单词的首字母都必须大写;

本规则一般用于 三个或更多字母的标识 的情况

BackColor

Camel 大小写

首字母小写且后续单词的首字母都必须大写

本规则仅用于 函数参数和保护实例成员的命名 中

backColor

大写格

所有字母都必须大写

本规则仅用于 标识只有两个或更少字母 的情况

System.IO

System.Web.UI

2.1   大小写规则

大写标识符中的所有字母都大写。仅对于由两个或者更少字母组成的标识符使用该约定。例如:

System.IO

System.Web.UI

下表汇总了大写规则,并提供了不同类型的标识符的示例。

标识符

大小写

示例

Pascal

AppDomain

枚举类型

Pascal

ErrorLevel

枚举值

Pascal

FatalError

事件

Pascal

ValueChange

异常类

Pascal

WebException

注意 总是以 Exception 后缀结尾。

只读的静态字段

Pascal

RedValue

接口

Pascal

IDisposable

注意 总是以 I 前缀开始。

方法

Pascal

ToString

命名空间

Pascal

System.Drawing

属性

Pascal

BackColor

公共实例字段

Pascal

RedValue

注意 很少使用。属性优于使用公共实例字段。

受保护的实例字段

Camel

redValue

注意 很少使用。属性优于使用受保护的实例字段。

私有的实例字段

Camel

redValue

参数

Camel

typeName

方法内的变量

Camel

backColor

2.2缩写

为了避免混淆和保证跨语言交互操作,请遵循有关区缩写的使用的下列规则:

(1) 不要将缩写或缩略形式用作标识符名称的组成部分。例如,使用 GetWindow,而不要使用 GetWin。

(2) 不要使用计算机领域中未被普遍接受的缩写。

(3) 在适当的时候,使用众所周知的缩写替换冗长的词组名称。例如,用 UI 作为 User Interface 缩写,用OLAP 作为 On-line Analytical Processing 的缩写。

(4) 在使用缩写时,对于超过两个字符长度的缩写请使用 Pascal 大小写或 Camel 大写。例如,使用 HtmlButton 或 HTMLButton。但是,应当大写仅有两个字符的缩写,如,System.IO,而不是 System.Io。

(5) 不要在标识符或参数名称中使用缩写。如果必须使用缩写,对于由多于两个字符所组成的缩写请使用Camel 大小写,虽然这和单词的标准缩写相冲突。

2.3命名空间

(1) 命名命名空间时的一般性规则是使用公司名称,后跟技术名称和可选的功能与设计,如下所示。

CompanyName.TechnologyName[.Feature][.Design]

例如:

namespace Langchao.Procurement

namespace Langchao.Procurement.DataRules

(2) 命名空间使用Pascal大小写,用逗号分隔开。

(3) TechnologyName 指的是该项目的英文缩写,或软件名。
(4) 命名空间和类不能使用同样的名字。例如,有一个类被命名为Debug后,就不要再

使用Debug作为一个名称空间名。

2.4类

(1) 使用 Pascal 大小写。

(2) 用名词或名词短语命名类。

(3) 使用全称避免缩写,除非缩写已是一种公认的约定,如URL、HTML

(4)  不要使用类型前缀。例如,使用类名称 FileStream

(5) 不要使用下划线字符 (_)。

(6) 有时候需要提供以字母 I 开始的类名称,虽然该类不是接口。只要 I 是作为类名称组成部分的整个单词的第一个字母,这便是适当的。例如,类名称 IdentityStore 是适当的。在适当的地方,使用复合单词命名派生的类。派生类名称的第二个部分应当是基类的名称。例如,ApplicationException 对于从名为 Exception 的类派生的类是适当的名称,原因ApplicationException 是一种Exception。请在应用该规则时进行合理的判断。例如,Button 对于从 Control 派生的类是适当的名称。尽管按钮是一种控件,但是将 Control 作为类名称的一部分将使名称不必要地加长。

public class FileStream

public class Button

public class String

2.5接口

以下规则概述接口的命名指南:

(1) 用名词或名词短语,或者描述行为的形容词命名接口。例如,接口名称 IComponent 使用描述性名词。接口名称 ICustomAttributeProvider 使用名词短语。名称 IPersistable 使用形容词。

(2) 使用 Pascal 大小写。

(3) 少用缩写。

(4) 给接口名称加上字母 I 前缀,以指示该类型为接口。在定义类/接口对(其中类是接口的标准实现)时使用相似的名称。两个名称的区别应该只是接口名称上有字母 I 前缀。

(5) 不要使用下划线字符 (_)。

(6) 当类是接口的标准执行时,定义这一对类/接口组合就要使用相似的名称。两个名称的不同之处只是接口名前有一个I前缀。

以下是正确命名的接口的示例。

public interface IServiceProvider

public interface IFormatable

以下代码示例阐释如何定义 IComponent 接口及其标准实现 Component 类。

public interface IComponent

{

// Implementation code goes here.

}

public class Component: IComponent

{

// Implementation code goes here.

}

2.6属性 (Attribute)

应该总是将后缀 Attribute 添加到自定义属性类。以下是正确命名的属性类的示例。

public class ObsoleteAttribute

{

}

2.7枚举 (Enum)

枚举 (Enum) 值类型从 Enum 类继承。以下规则概述枚举的命名指南:

(1) 对于 Enum 类型和值名称使用 Pascal 大小写。

(2) 少用缩写。

(3) 不要在 Enum 类型名称上使用 Enum 后缀。

(4) 对大多数 Enum 类型使用单数名称,但是对作为位域的 Enum 类型使用复数名称。

(5) 总是将 FlagsAttribute 添加到位域 Enum 类型。

2.8参数

以下规则概述参数的命名指南:

(1) 使用描述性参数名称。参数名称应当具有足够的描述性,以便参数的名称及其类型

可用于在大多数情况下确定它的含义。

(2) 对参数名称使用 Camel 大小写。

(3) 使用描述参数的含义的名称,而不要使用描述参数的类型的名称。开发工具将提

供有关参数的类型的有意义的信息。因此, 通过描述意义,可以更好地使用参

数的名称。少用基于类型的参数名称,仅在适合使用它们的地方使用它们。

(4) 不要使用保留的参数。保留的参数是专用参数,如果需要,可以在未来的版本中公

开它们。相反,如果在类库的未来版本中需要更多的数据,请为方法添加新的重载。

(5) 不要给参数名称加匈牙利语类型表示法的前缀。

以下是正确命名的参数的示例。

Type GetType(string typeName)

string Format(string format, args() As object)

2.9方法

以下规则概述方法的命名指南:

(1) 使用动词或动词短语命名方法。

(2) 使用 Pascal 大小写。

(3) 以下是正确命名的方法的实例。

RemoveAll()

GetCharArray()

Invoke()

2.10 属性 (property)

以下规则概述属性的命名指南:

(1) 使用名词或名词短语命名属性。

(2) 使用 Pascal 大小写。

(3) 不要使用匈牙利语表示法。

(4) 考虑用与属性的基础类型相同的名称创建属性。例如,如果声明名为 Color 的属性,则属性的类型同样应该是 Color。请参阅本主题中后面的示例。

以下代码示例阐释正确的属性命名。

public class SampleClass

{

public Color BackColor

{

// Code for Get and Set accessors goes here.

}

}

以下代码示例阐释提供其名称与类型相同的属性。

public enum Color

{

// Insert code for Enum here.

}

public class Control

{

public Color Color

{

get

{

// Insert code here.

}

set

{

// Insert code here.

}

}

}

以下代码示例不正确,原因是 Color 属性是 Integer 类型的。

public enum Color

{

// Insert code for Enum here.

}

public class Control

{

public int Color

{

// Insert code here

}

}

在不正确的示例中,不可能引用 Color 枚举的成员。Color.Xxx 将被解释为访问一个成员,

该成员首先获取 Color 属性( C# 中为 int 类型)的值,然后再访问该值的某个成员(该成

员必须是 System.Int32 的实例成员)。

2.11事件

以下规则概述事件的命名指南:

(1) 对事件处理程序名称使用 EventHandler 后缀。

(2) 指定两个名为 sender 和 e 的参数。sender 参数表示引发事件的对象。sender 参数始终是object 类型的,即使在可以使用更为特定的类型时也如此。与事件相关联的状态封装在名为 e 的事件类的实例中。对 e 参数类型使用适当而特定的事件类。

(3) 用 EventArgs 后缀命名事件参数类。

(4) 考虑用动词命名事件。

(5) 使用动名词(动词的"ing"形式)创建表示事件前的概念的事件名称,用过去式表示事件后。例如,可以取消的 Close 事件应当具有 Closing 事件和 Closed 事件。不要使用BeforeXxx/AfterXxx 命名模式。

(6) 不要在类型的事件声明上使用前缀或者后缀。例如,使用 Close,而不要使用 OnClose。

(7) 通常情况下,对于可以在派生类中重写的事件,应在类型上提供一个受保护的方法(称为OnXxx)。此方法只应具有事件参数 e,因为发送方总是类型的实例。

以下示例阐释具有适当名称和参数的事件处理程序。

public delegate void MouseEventHandler(object sender, MouseEventArgs e);

以下示例阐释正确命名的事件参数类。

public class MouseEventArgs : EventArgs

{

int x;

int y;

public MouseEventArgs(int x, int y)

{

this.x = x;

this.y = y;

}

public int X

{

get

{

return x;

}

}

public int Y

{

get

{

return y;

}

}

}

2.12 常量 (const)

以下规则概述常量的命名指南:

所有单词大写,多个单词之间用 "_" 隔开。 如

public const string PAGE_TITLE = "Welcome";

2.13 字段

以下规则概述字段的命名指南:

(1) private、protected 使用 Camel 大小写。

(2) public 使用 Pascal 大小写。

(3) 拼写出字段名称中使用的所有单词。仅在开发人员一般都能理解时使用缩写。字段名称不要使用大写字母。下面是正确命名的字段的示例。

class SampleClass

{

string url;

string destinationUrl;

}

(4) 不要对字段名使用匈牙利语表示法。好的名称描述语义,而非类型。

(5) 不要对字段名或静态字段名应用前缀。具体说来,不要对字段名称应用前缀来区分静态和非静态字段。例如,应用 g_ 或 s_ 前缀是不正确的。

(6)对预定义对象实例使用公共静态只读字段。如果存在对象的预定义实例,则将它们声明为对象本身的公共静态只读字段。使用 Pascal 大小写,原因是字段是公共的。下面的代码示例阐释公共静态只读字段的正确使用。

public struct Color

{

public static readonly Color Red = new Color(0x0000FF);

public Color(int rgb)

{

// Insert code here.}

public Color(byte r, byte g, byte b)

{

// Insert code here.

}

public byte RedValue

{

get

{

return Color;

}

}

}

2.14 静态字段

以下规则概述静态字段的命名指南:

(1) 使用名词、名词短语或者名词的缩写命名静态字段。

(2) 使用 Pascal 大小写。

(3) 对静态字段名称使用匈牙利语表示法前缀。

(4) 建议尽可能使用静态属性而不是公共静态字段。

2.15 集合

集合是一组组合在一起的类似的类型化对象,如哈希表、查询、堆栈、字典和列表,集合的命名

建议用复数。

第3章 表达式和基本语句

3.1 运算符的优先级

C#语言的运算符有数十个,运算符的优先级与结合律如表3-1所示。注意一元运算符 + - * 的优先级高于对应的二元运算符。

优先级

运算符

结合律

( ) [ ] -> .

从左至右

! ~ ++ -- (类型) sizeof

+ - * &

从右至左

 

* / %

从左至右

+ -

从左至右

<< >>

从左至右

<   <=   > >=

从左至右

== !=

从左至右

&

从左至右

^

从左至右

|

从左至右

&&

从左至右

||

从右至左

?:

从右至左

= += -= *= /= %= &= ^=

|= <<= >>=

从左至右

表3-1 运算符的优先级与结合律

如果代码行中的运算符比较多,用括号确定表达式的操作顺序,避免使用默认的优先级。

为了防止产生歧义并提高可读性,应当用括号确定表达式的操作顺序。例如:

word = (high << 8) | low

if ((a | b) && (a & c))

3.2 复合表达式

如 a = b = c = 0这样的表达式称为复合表达式。允许复合表达式存在的理由是:(1)书写简洁;(2)可以提高编译效率。但要防止滥用复合表达式。

(1)不要编写太复杂的复合表达式。

例如:

i = a >= b && c < d && c + f <= g + h ; // 复合表达式过于复杂

(2)不要有多用途的复合表达式。

例如:

d = (a = b + c) + r ;

该表达式既求a值又求d值。应该拆分为两个独立的语句:

a = b + c;

d = a + r;

(3)不要把程序中的复合表达式与"真正的数学表达式"混淆。

例如:

if (a < b < c)          // a < b < c是数学表达式而不是程序表达式

并不表示

if ((a<b) && (b<c))

而是成了令人费解的

if ( (a<b)<c )

3.3 if 语句

if语句是c# 语言中最简单、最常用的语句,然而很多程序员用隐含错误的方式写if语句。本节以"与零值比较"为例,展开讨论。

3.3.1 布尔变量与零值比较

 不可将布尔变量直接与TRUE、FALSE或者1、0进行比较。

根据布尔类型的语义,零值为"假"(记为FALSE),任何非零值都是"真"(记为TRUE)。TRUE的值究竟是什么并没有统一的标准。例如 c# 将TRUE定义为1,而Visual Basic.net则将TRUE定义为-1。

假设布尔变量名字为flag,它与零值比较的标准if语句如下:

if (flag)   // 表示flag为真

if (!flag) // 表示flag为假

其它的用法都属于不良风格,例如:

if (flag == TRUE)

if (flag == 1 )

if (flag == FALSE)

if (flag == 0)

3.3.2 整型变量与零值比较

应当将整型变量用"=="或"!="直接与0比较。

假设整型变量的名字为value,它与零值比较的标准if语句如下:

if (value == 0)

if (value != 0)

不可模仿布尔变量的风格而写成

if (value)      // 会让人误解 value是布尔变量

if (!value)

3.3.3 浮点变量与零值比较

不可将浮点变量用"=="或"!="与任何数字比较。

千万要留意,无论是float还是double类型的变量,都有精度限制。所以一定要避免将浮点变量用"=="或"!="与数字比较,应该设法转化成">="或"<="形式。

假设浮点变量的名字为x,应当将

if (x == 0.0)    // 隐含错误的比较

转化为

if ((x>=-EPSINON) && (x<=EPSINON))

其中EPSINON是允许的误差(即精度)。

3.4 循环语句的效率

C# 循环语句中,for语句使用频率最高,while语句其次,do语句很少用。提高循环体效率的基本办法是降低循环体的复杂性。

(1)在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数。例如示例3-4(b)的效率比示例3-4(a)的高。

for (row=0; row<100; row++)

{

for ( col=0; col<5; col++ )

{

sum = sum + a[row][col];

}

}

for (col=0; col<5; col++ )

{

for (row=0; row<100; row++)

{

sum = sum + a[row][col];

}

}

示例3-4(a) 低效率:长循环在最外层           示例3-4(b) 高效率:长循环在最内层

(2) 如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。示例3-4(c)的程序比示例3-4(d)多执行了N-1次逻辑判断。并且由于前者老要进行逻辑判断,打断了循环"流水线"作业,使得编译器不能对循环进行优化处理,降低了效率。如果N非常大,最好采用示例3-4(d)的写法,可以提高效率。如果N非常小,两者效率差别并不明显,采用示例3-4(c)的写法比较好,因为程序更加简洁。

for (i=0; i<N; i++)

{

if (condition)

DoSomething();

else

DoOtherthing();

}

if (condition)

{

for (i=0; i<N; i++)

DoSomething();

}

else

{

for (i=0; i<N; i++)

DoOtherthing();

}

表3-4(c) 效率低但程序简洁                表3-4(d) 效率高但程序不简洁

3.5 for 语句的循环控制变量

(1)不可在for 循环体内修改循环变量,防止for 循环失去控制。

(2)建议for语句的循环控制变量的取值采用"半开半闭区间"写法。

示例3-5(a)中的x值属于半开半闭区间"0 =< x < N",起点到终点的间隔为N,循环次数为N。

示例3-5(b)中的x值属于闭区间"0 =< x <= N-1",起点到终点的间隔为N-1,循环次数为N。

相比之下,示例3-5(a)的写法更加直观,尽管两者的功能是相同的。

for (int x=0; x<N; x++)

{

}

for (int x=0; x<=N-1; x++)

{

}

示例3-5(a) 循环变量属于半开半闭区间           示例3-5(b) 循环变量属于闭区间

3.6 switch语句

switch是多分支选择语句,而if语句只有两个分支可供选择。虽然可以用嵌套的if语句来实现多分支选择,但那样的程序冗长难读。这是switch语句存在的理由。

switch语句的基本格式是:

switch (variable)

{

case value1 :  …

break;

case value2 :  …

break;

default : …

break;

}

(1)每个case语句的结尾不要忘了加break,否则将导致多个分支重叠(除非有意使多个分支重叠)。

(2)不要忘记最后那个default分支。即使程序真的不需要default处理,也应该保留语句 default : break; 这样做并非多此一举,而是为了防止别人误以为你忘了default处理。

第4章 Asp.net设计规范

本界面设计规范适用于Asp.net开发的所有页面。

5.1 页眉、页脚和样式表

在主窗口中显示的所有页面应该包含相同的页眉文件、页脚文件和样式表

在单独窗口中显示的页面应该包含和主窗口页面一致的样式表

页面元素的样式应该在单独的样式表中定义,而非直接在页面中定义各种属性

5.2页面标题

在单独窗体中呈现的页面应该定义<title>元素,title必须能够表达界面的功能

5.3 窗口大小和位置

弹出的新窗口应在屏幕上处于居中位置,如top=200,left=300

页面元素的宽度应尽量使用百分比而避免直接使用像素值,应当保证页面在800x600满屏的窗口中显示时不用横向移动滚动条

5.4超链接

链接到系统内部页面的超链接使用相对路径

5.5按钮

含义相同的按钮名称应保持一致,如"确定"、"取消"、"重置"、 "搜索"、"高级搜索"、"新建"、"删除"、"更改"等

多于一个的按钮并排摆放时顺序(左右/上下)应保持一致,如"确定"应该在"取消"的左边

5.6处理结果

每次处理都应该有相应的处理结果页面或提示信息,不管该处理是成功还是失败

相同处理结果的用语应保持一致,如避免同时使用"失败"和"没有成功"这样意义相同的词语

5.7 操作确认

当用户在进行一些诸如删除,查封,导入,导出等会对系统造成影响的操作的时候,系统必须用确认框或者确认页面来提醒用户,并且让用户进行确认。

任何一个操作页面,都必须提供给用户取消操作,并且返回的功能。

5.8 数据验证

各个功能页面,系统都必须进行严格的数据验证,包括长度,类型,是否合法等等

在asp.net中所有的数据验证都使用validator控件在客户端实现。

5.9控件使用

在asp.net中,dot net framework提供了WebControls和HtmlControls两种控件,但是两种控件有本质的区别,WebControls是服务器端的控件,服务器在执行的时候需要保留相应控件的状态等信息,HtmlControls是和Html相关的控件,使用原则如下

所有需要服务器端进行事件响应的使用WebControl

无需服务器端相响应的比如超连接,图片等等尽量使用HtmlControls这样可以提高效率,减少服务器的负担,减少网络传输的数据量。

5.10 视图状态

Asp.net中每个页面对象在输出html结束之后,页面对象将会被垃圾回收线程给回收掉,为了保存页面中各个WebControls的状态,系统会自动将各个WebControl里面的数据,状态等信息保存在ViewState中,这样就极大地加大了文件的大小,为了减少页面下载的量,试图状态的使用原则如下:

在页面中判断Page.IsPostBack属性,将少对象初始化的量。

将一些无需保留数据WebControls的EnableViewState改为false

5.11 异常处理

在各个模块的类库中,如果有异常出现则首先将异常写到日志文件中,同时将异常抛出

在页面上尽可能的将所有从封装的类中抛出来的异常抓起来,并且给用户比较友好的提示

当出现非常严重的异常时将页面重定向到errorpage中。

5.12 HTML页面中需要注意的地方

去掉页面中所有的<font>标签,因为在html标准4.0的时候这个tag就已经不建议使用了。

为页面添加正确的DOCTYPE,DOCTYPE是document type的简写。主要用来说明你用的XHTML或者HTML是什么版本。

设定一个命名空间,一个namespace是收集元素类型和属性名字的一个详细的DTD,namespace声明允许你通过一个在线地址指向来识别你的namespace。

声明编码语言(<meta http-equiv="Content-Type" content="text/html; charset=GB2312" />)。

用小写字母写所有的标签。

为图片添加alt属性。

给所有的属性添加引号

关闭所有的标签,及时是<br>也应该写成<br />。

所有和显示显示相关的控制用css来控制。

给每一个表格或者表单赋予一个唯一的ID。

5.13 数据库访问

在页面文件中不要出现任何访问数据库的代码

访问数据库的方式,推荐方式2

方式1,通过字符串拼接来生成一个完整的SQL语句,如下

SqlConnection objDbConn = new SqlConnection("链接字符串");

String strSql = "select * from TUSER_USERINFO where UserID=" + strUserID;

SqlCommand objCommand = new Command(strSql,objDbConn);

SqlDataReader objReader = objCommand.ExecuteReader();

缺陷:SQL Injection漏洞

方式2,通过参数来实现

SqlConnection objDbConn = new SqlConnection("链接字符串");

String strSql = "select * from TUSER_USERINFO where UserID=@UserID";

SqlCommand objCommand = new Command(strSql,objDbConn);

objCommand.Paramters.Add("@UserID",strUserID);

SqlDataReader objReader = objCommand.ExecuteReader();

系统将调用Ms SQLServer2000中的sp_executesql存储过程来实现,能够避免漏洞

第5章 javascript编写规范

6.1 在什么地方插入 JavaScript

一种方法,JavaScript 出现在 HTML 的head 部分,使用标记<script>…</script>。

另外一种插入 JavaScript 的方法,是把 JavaScript 代码写到另一个文件当中(此文件通常应该用".js"作扩展名),然后用格式为"<script src="javascript.js"></script>"的标记把它嵌入到文档中。注意,一定要用"</script>"标记。

6.2 JavaScript 中的变量

变量的命名有以下要求:只包含字母、数字和/或下划线;要以字母开头;不能太长不能与 JavaScript 保留字(Key Words,Reserved Words,数量繁多,不能一一列出;凡是可以用来做 JavaScript 命令的字都是保留字)重复。 而且,变量是区分大小写的,例如,variable 和 Variable 是两个不同的变量。不仅如此,大部分命令和"对象"(请参阅"对象化编程"章)都是区分大小写的。

提示 给变量命名,最好避免用单个字母"a""b""c"等,而改用能清楚表达该变量在程序中的作用的词语。这样,不仅别人能更容易的了解你的程序,而且你在以后要修改程序的时候,也很快会记得该变量的作用。变量名一般用小写,如果是由多个单词组成的,那么第一个单词用小写,其他单词的第一个字母用大写。例如:myVariable 和 myAnotherVariable。这样做仅仅是为了美观和易读,因为 JavaScript 一些命令(以后将用更具体的方法阐述"命令"一词)都是用这种方法命名的:indexOf;charAt 等等。

变量的赋值 一个变量声明后,可以在任何时候对其赋值。赋值的语法是:

<变量> = <表达式>;

其中"="叫"赋值符",它的作用是把右边的值赋给左边的变量。下一节将讨论到表达式。

JavaScript常数 有下列几个:

null 一个特殊的空值。当变量未定义,或者定义之后没有对其进行任何赋值操作,它的值就是"null"。企图返回一个不存在的对象时也会出现null值。
NaN "Not a Number"。出现这个数值比较少见,以至于我们可以不理它。当运算无法返回正确的数值时,就会返回"NaN"值。NaN 值非常特殊,因为它"不是数字",所以任何数跟它都不相等,甚至 NaN 本身也不等于 NaN 。
true 布尔值"真"。用通俗的说法,"对"。
false 布尔值"假"。用通俗的说法,"错"。

6.3语句

6.3.1 注释

JavaScript 注释有两种:单行注释和多行注释。单行注释用双反斜杠"//"表示。当一行代码有"//",那么,"//"后面的部分将被忽略。而多行注释是用"/*"和"*/"括起来的一行到多行文字。程序执行到"/*"处,将忽略以后的所有文字,直到出现"*/"为止

6.3.2 if 语句

if ( <条件> ) <语句1> [ else <语句2> ];本语句有点象条件表达式"?:":当<条件>为真时执行<语句1>,否则,如果else 部分存在的话,就执行<语句2>。与"?:"不同的是,if 只是一条语句,不会返回数值。<条件>是布尔值,必须用小括号括起来;<语句1>和<语句2>都只能是一个语句,欲使用多条语句,请用语句块。

if (a == 1)
  if (b == 0) alert(a+b);
else
  alert(a-b);

if (a == 1)

{
  if (b == 0) alert(a+b);
} else {
  alert(a-b);
}

示例 风格不良的对齐                      示例 风格良好的对齐

6.3.3 循环体

for (<变量>=<初始值>; <循环条件>; <变量累加方法>)<语句>;

提示 适当的使用 for 循环,能使 HTML 文档中大量的有规律重复的部分简化,也就是用 for 循环重复写一些 HTML 代码,达到提高网页下载速度的目的。不过请在 Netscape 中重复进行严格测试,保证通过了才好把网页传上去。作者曾试过多次因为用 for 循环向文档重复写 HTML 代码而导致 Netscape"猝死"。IE 中绝对没有这种事情发生,如果你的网也是只给 IE 看的,用多多的 for 也没问题。

6.3.4 switch 语句

如果要把某些数据分类,例如,要把学生的成绩按优、良、中、差分类。我们可能会用 if 语句,但使用太多的 if 语句的话,程序看起来有点乱。switch 语句就是解决这种问题的最好方法。

switch (e)

{
  case r1: (注意:冒号)
    ...
    [break;]
  case r2:
    ...
    [break;]
  ...
  [default:
    ...]
}

ADO.NET命名规范

数据类型

数据类型简写

标准命名举例

Connection

con

conNorthwind

Command

cmd

cmdReturnProducts

Parameter

parm

parmProductID

DataAdapter

dad

dadProducts

DataReader

dtr

dtrProducts

DataSet

dst

dstNorthWind

DataTable

dtbl

dtblProduct

DataRow

drow

drowRow98

DataColumn

dcol

dcolProductID

DataRelation

drel

drelMasterDetail

DataView

dvw

dvwFilteredProducts

WinForm Control 命名规范

数据类型

数据类型简写

标准命名举例

Label

lbl

lblMessage

LinkLabel

llbl

llblToday

Button

btn

btnSave

TextBox

txt

txtName

MainMenu

mmnu

mmnuFile

CheckBox

chk

chkStock

RadioButton

rbtn

rbtnSelected

GroupBox

gbx

gbxMain

PictureBox

pic

picImage

Panel

pnl

pnlBody

DataGrid

dgrd

dgrdView

ListBox

lst

lstProducts

CheckedListBox

clst

clstChecked

ComboBox

cbo

cboMenu

ListView

lvw

lvwBrowser

TreeView

tvw

tvwType

TabControl

tctl

tctlSelected

DateTimePicker

dtp

dtpStartDate

HscrollBar

hsb

hsbImage

VscrollBar

vsb

vsbImage

Timer

tmr

tmrCount

ImageList

ilst

ilstImage

ToolBar

tlb

tlbManage

StatusBar

stb

stbFootPrint

OpenFileDialog

odlg

odlgFile

SaveFileDialog

sdlg

sdlgSave

FoldBrowserDialog

fbdlg

fgdlgBrowser

FontDialog

fdlg

fdlgFoot

ColorDialog

cdlg

cdlgColor

PrintDialog

pdlg

pdlgPrint

WebControl 命名规范

数据类型

数据类型简写

标准命名举例

AdRotator

adrt

Example

Button

btn

btnSubmit

Calendar

cal

calMettingDates

CheckBox

chk

chkBlue

CheckBoxList

chkl

chklFavColors

CompareValidator

valc

valcValidAge

CustomValidator

valx

valxDBCheck

DataGrid

dgrd

dgrdTitles

DataList

dlst

dlstTitles

DropDownList

drop

dropCountries

HyperLink

lnk

lnkDetails

Image

img

imgAuntBetty

ImageButton

ibtn

ibtnSubmit

Label

lbl

lblResults

LinkButton

lbtn

lbtnSubmit

ListBox

lst

lstCountries

Panel

pnl

pnlForm2

PlaceHolder

plh

plhFormContents

RadioButton

rad

radFemale

RadioButtonList

radl

radlGender

RangeValidator

valg

valgAge

RegularExpression

vale

valeEmail_Validator

Repeater

rpt

rptQueryResults

RequiredFieldValidator

valr

valrFirstName

Table

tbl

tblCountryCodes

TableCell

tblc

tblcGermany

TableRow

tblr

tblrCountry

TextBox

txt

txtFirstName

ValidationSummary

vals

valsFormErrors

XML

xmlc

xmlcTransformResults

变量
变量的作用域及前缀

前缀

说明

举例

P

全局变量

pstrName

St

静态变量

ststrName

M

模块或者窗体的局部变量

MstrName

A

数组

AintCount[]

变量数据类型的前缀

C#数据类型

类库数据类型

标准命名举例

Sbyte

System.sbyte

sbte

Short

System.Int16

sht

Int

System.Int32

int

Long

System.Int64

lng

Byte

System.Byte

bte

Ushot

System.Uint16

usht

Uint

System.Uint32

uint

Ulong

System.Uint64

ulng

Float

System.Single

flt

Double

System.Double

dbl

Decimal

System.Decimal

dcl

Bool

System.Boolean

bol

Char

System.Char

chr

Object

System.Object

obj

String

System.String

str

 

System.DateTime

dte

IntPtr

System.Intpre

intptr



常量定义
常量=作用域+ c+数据类型+变量名

类对象定义 
类实例=作用域+cls+变量名 
类对象=C+名称

结构对象定义 
结构对象实例=作用域+struc+变量名 
结构对象=S+名称

命名空间定义 
以层为前缀进行命名

接口定义 
以大写I为前缀

窗体的命名规则 
窗体名=frm+窗体名(名词+动词)
注意:保存的文件明和窗体名相同。

枚举定义规则 
以Enum为前缀

事件命名规则 
事件控制器要带有EventHandler后缀 
使用sender和e命名两个参数 
事件参数类要带有EventArgs后缀 
考虑使用动词命名事件 
对于有"之前"或"之后"概念的事件,要使用现在时或过去时命名

分类: 资源