苏起 - 云代码空间
—— 干一件你感兴趣的事,永远不觉得累!
规范开发人员在开发过程中养成良好的编码规范,对程序集、文件等进行更好的版本控制,增加代码的友好性和阅读性。
本文档适用于开发过程中的项目架构师、设计师、编码人员等,主要是针对开发人员;
名词 |
定 义 |
骆驼式(Camel)命名 |
如它的名称所表示的那样,是指混合使用大小写字母来构成变量和函数的名字。首字母小写,组合词组的第二个及之后的单词首字母大写,其它均为小写字母。如employeeNo、departmentType、myData等 |
帕斯卡(Pascal)命名 |
与骆驼命名法类似。只不过骆驼命名法是首字母小写,而帕斯卡命名法是首字母大写。如UserName、DepartmentInfo、MyData等 |
匈牙利命名 |
标识符的名字以一个或者多个小写字母开头作为前缀;前缀之后的是首字母大写的一个单词或多个单词组合,该单词要指明变量的用途。前缀可标识出变量的作用域、类型等,可以多个同时使用,顺序是先m_(成员变量)+指针+数据类型+对象描述;如frmSwitchboard、txtUserName、iCount、iMyData等 |
本文档主要从以下几个方面对C#开发过程中的文件和类进行命名和编码的约束:程序集规范、文件规范、编码规范;
程序集的约束主要对程序集的名称、公司信息、版本、等信息进行约束;
文件的约束主要是对文件创建信息、修改信息、文件名的命名规则、编码格式等进行相关约束;
编码规范描述了类、结构、接口、委托等的命名、注释说明,以及方法、属性的命名和注释说明;
程序集的名称依据程序集实现的主体对象名称而定,必须是名词或名称词组,采取帕斯卡命名规则。
程序集的默认命名空间由一个或多个命名组成,每个命名由是一个或最多两个名词组成,命名采取帕斯卡命名规则,多个命名间用“.”进行连接。默认命名空间都以EBusiness首部分,加上其它的一个或多个命名。如EBusiness.Framework.Cache;
程序集生成的Dll文件规则遵循如下原则:命名空间(去掉最后一个命名)+程序集名称。如程序集名称为Logger,程序集的默认命名空间为EBusiness.Framework.Log,而程序集生成的Dll则命名为EBusiness.Framework.Logger;
程序集属性设置中的标题、产品为程序集本身的名称,公司为“XXX公司”,版权为“版权所有 (c) 公司网址”,产品版本和文件版本则根据实际开发过程中的版本来递增;
程序集生成的同时,也须对注释生成相关的XML文档;
文件的命名保持与文件中的类名、接口名、结构类一致,采取帕斯卡命名规则;
一个文件应该只有一个命名空间,避免将多个命名空间放在同一个文件里面,只有一个类或接口或结构存在,避免将多个类放在一个文件里面。
一个文件最好不要超过500行代码(IDE 产生的代码除外),如果一个类的代码超过500行时,建议可使用partial修饰符对类进行片断性的分隔(在编译时,编译器会将它们构造为一个类);原则上,尽量不要手工的修改IDE生成的代码,如确实需修改IDE生成的代码时,编码格式和风格必须符合IDE编码标准。
每个文件必须在文件头中加上文件的创建信息、修改信息等,用于更方便管理和追踪文件版本更改;文件抬头的通用格式如上:
/*
* Version: 1.0
* Create Date: yyyy-MM-dd
* Author: 作者
* Description: 对该文件中主要实现的类或接口进行说明
* Modify Date: yyyy-MM-dd
* Modifier: 修改者
* Description: 修改说明
*/
文件的创建信息有且只能有一组,文件存在多次修改时,则会有多组修改信息,以追加方式对文件修改信息进行描述;
文件编码格式的保存,采取UTF-8,通过.Net开发工具中的【文件】菜单中的<高级保存选项>中选择第二项“”进行设置。
当使用partial类并将其分配给每个文件一部分时,对每个文件命名使用后缀P并附带一个额外的数字,如下所示:
//In MyClassP1.cs
public partial class MyClass
{..}
// In MyClassP2.cs
public partial class MyClass
{..}
文件中每行代码的长度不要超过100个字符,超过时须换行。
当表达式超出或即将超出规定的行宽,首先考虑在在逗号“,”后换行,其次考虑在操作符前换行。要求在换行时,结尾处能非常清晰的知道此行未结束,严禁以“)”进行换行。编码人员应根据此规则进行灵活的应用。
缩进应该是每行一个Tab(4个空格),不要在代码中使用Tab字符,应通过工具中的选项来设置缩进,Visual Studio.Net设置:工具->选项->文本编辑器->C#->制表符->插入空格;
空行是为了将逻辑上相关联的代码分块,以便提高代码的可阅读性。
在以下情况中必须使用一个空行来进行分隔:
1) 方法与方法、属性与属性、方法与属性、属性与字段、方法与字段之间;
2) 方法中变量声明与语句之间;
3) 同一方法中不同逻辑块之间;
4) 方法中的返回语句与其他的语句之间;
在以下情况中要使用到空格:
1) 关键字和左括符 “(” 应该用空格隔开,方法名与左括符“(”除外。如
private string GetUserInfo(string username, int company)
{
….
while (true)
……
}
2) 不管是在方法的定义或方法的调用过程中,多个参数间用逗号隔开,且每个逗号后都应加一个空格。
3) 除了 . 之外,所有的二元操作符都应用空格与它们的操作数隔开。一元操作符、++及--与操作数间不需要空格。如
a += c + d;
a = (a + b) / (c * d);
while (d++ = s++)
{
n++;
}
PrintSize(“size is “ + size + “\n”);
4) 语句中的表达式之间用空格隔开。如
for (expr1; expr2; expr3)
括号“()”必须是成对出现;当右括号恰好超过了当前行定义的最大行宽时,右括号不要进行单独的换行。
左括号“(”与关键字之间应有一空格,但左括号“(”与方法定义和调用时中间不要添加任何空格。
花括号“{}”必须是成对出现,花括号除了在属性中的应用外,一般是不能在同一行中使用。不同行时,要求左花括号“{”与右花括号“}”必须进行对齐;花括号的使用遵循如下规则:
1) 左花括号 “{” 放于关键字或方法名的下一行并与之对齐。如
public int Add(int x, int y)
{
if (x>y)
{
x += y;
}
}
2) 通常情况下左花括号 “{”单独成行,不与任何语句并列一行,除属性定义外,如:
public interface IEmployee
{
string UserName{get;}
int UserId{get;}
}
示例二:
public class Employee : IEmployee
{
public string UserName
{
get{return this._userName;};
}
public int UserId
{
get {return this._userId;};
}
}
3) if、while、do语句后常规情况下都须使用“{}”,但如果语句体中只有一句语句时,可以省略掉“{}”,如:
if (someValue == 1)
{
someValue = 2;
}
示例二:
if (someValue == 1)
someValue = 2;
4) 在多层花括号的嵌套中,建议右花括号 “}” 后加一个注释以便找到与之相应的“{”,如:
while (dtrEmployee.Read())
{
if (!string.IsNullorEmpty(dtrEmployee[“EmployeeName”]))
{
…..
} // if valid
else
{
……
} // not valid
} // end for drtEmployee Read
编码中的注释应遵循如下原则:
1) 注释的格式应该统一,避免采取多种不同方式的注释,注释本身要求简单性和完整性,避免复杂和不完整的注释,反而会带反效果;
2) 避免杂乱的注释,如一整行星号。而是应该使用空白将注释同代码分开;
3) 避免在块注释的周围加上印刷框。这样看起来可能很漂亮,但是难于维护;
4) 避免多余的或无用的注释,要求代码应该可以自解释,好的代码本身就应具体良好的可读性;如果字段、内部方法本身的定义能够良好的解释自己,则该部分的注释可以省略掉;
5) 在编写代码时就应注释,而不是在Coding完成后来补充注释,这是极不好的编程习惯;
6) 每个项目启动开发之前,应提供标准的注释样本以规范编码过程;
7) 行尾注释的使用:在变量声明时,可使用行尾注释,要求将所有行尾注释在同一公共制表位处对齐。在方法体语句尽量不使用行尾注释,因为行尾注释不但增长了行宽,破坏编码外观,且没有结构性,使代码更难阅读;
8) 对由循环和逻辑分支组成的代码使用注释,有利于源代码的阅读;
9) 如需发现须要相当复杂的注释来解释代码节,请考虑此代码是否须重构,来减少方法的复杂性;
10) 在修改某此重要编码或容易反复出错的方法块时,必须加上修改标识的注释,以使让团队开发成员能够清晰的明白现有逻辑或纠正错误;修改标识主要包括修改人、修改时间、修改原因、修改内容等,并能体现出修改代码块的开始位置和结束位置;
11) 当对方法、属性等进行修改时,应保存注释的最新性;
12) 在生成Release版本或项目部署发布前,应移除所有无关注释或因废代码产生的注释,避免给日后维护工作中产生混乱;
该类注释采用.Net已定义好的Xml标签来标记,在声明接口、类、方法、属性、字段都应该使用该类注释,以便代码完成后直接生成代码文档,让别人更好的了解代码的实现和接口,同时在程序集生成的属性中,应勾选生成相关的Xml注释。Xml标签注释如下:
/// <summary>
/// 已重写,获取页面加载方法体的内容
/// </summary>
/// <param name="writer">HTML输出流</param>
/// <returns>返回页面加载方法体字符串</returns>
public override string GetPageLoadFunctionBody(System.Web.UI.HtmlTextWriter writer)
{
….
}
文档型注释的标签:
标签 |
该类注释用于对代码进行大规模的修改时,或者暂时屏蔽某些代码时。格式如下:
/*
* Modify Date: yyyy-MM-dd
* Modifier: 修改人
* Modify Reason: 修改原因
* Modify Content: 修改内容
*/
…….修改的代码
//End Modify
单行注释适用于字段声明、方法内的代码注释、方法内的变量声明、方法体内的循环、分支、条件等的注释,如:
private int userId; //用户Id
private string departmentName; //部门名称
示例二:
switch (dayOfWeek)
{
case 1:
……
break;
case 2:
……
break;
}//End switch
示例三:
if ( true) // always true
{
ExecuteCalcSalary();
} // always true
1) 一行只建议作一个声明,并按字母顺序排列,并可对声明的变量进行初始化。如:
int level; //推荐
int size; //推荐
int x, y; //不推荐
DataTable dtUser = new DataTable(); //用户信息的DT
2) 类的变量的定义建议不使用pulbic和protected修饰符,而是通过get和set属性访问器来实现对私有字段的读写;
3) 变量的声明建议是放在类的开始处或方法的开始处,而不是在使用它们时才做声明,如下所示:
示例一:不推荐的做法
/// <summary>
/// User类的构造函数
/// </summary>
/// <param name=" userName ">用户名</param>
/// <param name=" userName ">家庭地址</param>
public User(string userName, string Address)
{
….
}
private string _userName;
public string UserName
{
get{return this._userName;}
}
示例一:推荐的做法
private string _userName;
/// <summary>
/// User类的构造函数
/// </summary>
/// <param name=" userName ">用户名</param>
/// <param name=" userName ">家庭地址</param>
public User(string userName, string Address)
{
….
}
public string UserName
{
get{return this._userName;}
}
示例二
void MyMethod()
{
int int1 = 0; // beginning of method block
if (condition)
{
int int2 = 5; // beginning of "if" block
int1 = int1*int2;
...
}
}
4) 变量的声明时应避免不同层次间的变量重名,如下所示:
避免以下声明,不推荐
int count;
...
void ClearCustomer()
{
int count = 1; //避免
string strValidator;
if (condition)
{
string strValidator = “error”; // 避免
...
}
...
}
类和接口中方法名与其后的左括号间没有任何空格,左花括号 “{” 出现在声明的下行并与之对齐,单独成行,方法间用一个空行隔开;
名称应该说明“什么”而不是“如何”。通过避免使用公开基础实现(它们会发生改变)的名称,可以保留简化复杂性的抽象层。例如,可以使用 GetNextStudent(),而不是 GetNextArrayElement()。 命名时遵行一个简单的原则:唯一名称在编程上仅用于将各项区分开,表现力强的名称让人第一眼看到时就能知道该命名的目的性和意义。在命名时常会使名称足够长以便有一定的意义,但须避免冗长和符合语言的规则和标准。以下几点是推荐的命名方法:
1) 避免容易被主观解释的难懂的名称,如方法名 AnalyzeThis(),或者属性名 xxK8。这样的名称会导致多义性;
2) 在类属性的名称中包含类名是多余的,如 Book.BookTitle,而是应该使用 Book.Title;
3) 只要合适,在变量名的末尾或开头加计算限定符(Avg、Sum、Min、Max、Index);
4) 在变量名中使用互补对,如 min/max、begin/end 和 open/close;
5) 布尔变量名应该包含 Is,这意味着 Yes/No 或 True/False 值,如 fileIsFound;
6) 在命名状态变量时,避免使用诸如 Flag 的术语。状态变量不同于布尔变量的地方是它可以具有两个以上的可能值。不是使用 documentFlag,而是使用更具描述性的名称,如 documentFormatType;
7) 即使对于可能仅出现在几个代码行中的生存期很短的变量,仍然使用有意义的名称。仅对于短循环索引使用单字母变量名,如 i 或 j。 可能的情况下,尽量不要使用原义数字或原义字符串。如(for i = 1 To 7),而是使用命名常数,如 (for i = 1 To DAYS_IN_WEEK) 以便于维护和理解;
8) 避免使用与常用的 .NET 框架命名空间重复的类名称。例如,不要将以下任何名称用作类名称:System、Collections、Forms 或 UI。有关 .NET 框架命名空间的列表,请参阅类库。另外,避免使用和以下关键字冲突的标识符:
AddHandler |
对由首字母缩写组合成的命名空间、变量、对象,要求所有字母都须大写。如:
System.IO
System.Web.UI
HTMLButton
下表制定了不同类型的标识符的大小写规则:
标识符 |
为了避免混淆和保证跨语言交互操作,请遵循有关区缩写的使用的下列规则:
1) 不要将缩写或缩略形式用作标识符名称的组成部分。例如,使用 GetWindow,而不要使用 GetWin;
2) 不要使用计算机领域中未被普遍接受的缩写;
3) 在适当的时候,使用众所周知的缩写替换冗长的词组名称。例如,用 UI 作为 User Interface 缩写,用 OLAP 作为 On-line Analytical Processing 的缩写;
4) 在使用缩写时,对于超过两个字符长度的缩写请使用 Pascal 大小写或 Camel 大小写。例如,使用 HtmlButton 或 HTMLButton。但是,应当大写仅有两个字符的缩写,如,System.IO,而不是 System.Io;
5) 不要在标识符或参数名称中使用缩写。如果必须使用缩写,对于由多于两个字符所组成的缩写请使用Camel 大小写,虽然这和单词的标准缩写相冲突。
命名命名空间时的一般性规则是使用公司名称,后跟技术名称和可选的功能与设计, CompanyName.TechnologyName[.Feature][.Design],例如:
IInternational.Bussniess
IInternational. Bussniess.OrderModel
命名空间使用Pascal大小写,用逗号分隔开,命名空间和类不能使用同样的名字。例如,有一个类被命名为Debug后,就不要再使用Debug作为一个名称空间名。
类的命名遵循如下规则:用名词或名词短语命名类,不能名包括类型前缀(如不须加上cls或者c前缀)或特殊字符(如不包括下划线“_”等),使用全称避免缩写(除非缩写已是一种公认的约定,如URL、HTML),大小写使用 Pascal规则。
有时候需要提供以字母 I 开始的类名称,虽然该类不是接口。只要 I 是作为类名称组成部分的整个单词的第一个字母,这便是适当的。例如,类名称 IdentityStore 是适当的。在适当的地方,使用复合单词命名派生的类。派生类名称的第二个部分应当是基类的名称。例如,ApplicationException 对于从名为 Exception 的类派生的类是适当的名称,原因ApplicationException 是一种Exception。或ObsoleteAttribute是属性Attribute类的派生类。类名命名在应用该规则特殊情况下,还须进行合理的判断。例如,Button 对于从 Control 派生的类是适当的名称。尽管按钮是一种控件,但是将 Control 作为类名称的一部分将使名称不必要地加长。
接口的命名遵循如下规则:用名词或名词短语,或者描述行为的形容词命名接口(例如IComponent 使用描述性名词,ICustomAttributeProvider 使用名词短语,IPersistable 使用形容词),不包括特殊字符(如下划线“_”等),加上字母I作为前缀(I大写),尽量少用缩写(除非缩写已是一种公认的约定,如URL、HTML),大小写使用 Pascal规则。
当类是接口的标准执行时,定义这一对类/接口组合就要使用相似的名称。两个名称的不同之处只是接口名前有一个I前缀,如ICustomAttributeProvider和CustomAttributeProvider。
枚举 (Enum) 值类型从 Enum 类继承。遵行如下规则:枚举类型和值名称都采用Pascal规则,不使用前缀或后缀,尽量不使用缩写,对大多数 Enum 类型使用单数名称,但是对作为位域的 Enum 类型使用复数名称,总是将 FlagsAttribute 添加到位域 Enum 类型。在枚举的定义时,还须避免对枚举提供明确的值,以及避免为枚举指定特定的类型。
//推荐的做法
public enum color
{
red,green,blue
}
//不推荐的做法
public enum color
{
red = 1,green = 2,blue = 3
}
//不推荐的做法
public enum color : long
{
red,green,blue
}
参数的命名遵循如下规则:
1) 使用描述性参数名称。参数名称应当具有足够的描述性,以便参数的名称及其类型可用于在大多数情况下确定它的含义;
2) 对参数名称使用 Camel 大小写;
3) 使用描述参数的含义的名称,而不要使用描述参数的类型的名称。开发工具将提供有关参数的类型的有意义的信息;
4) 不要使用保留的参数。保留的参数是专用参数,如果需要,可以在未来的版本中公开它们。相反,如果在类库的未来版本中需要更多的数据,请为方法添加新的重载;
5) 不要给参数名称加匈牙利语类型表示法的前缀;
以下规则概述字段的命名指南:
1) private、protected 使用 Camel 大小写,public 使用 Pascal 大小写;
2) 使用全称避免缩写(除非缩写已是一种公认的约定,如URL、HTML) ,不要对字段名使用匈牙利语表示法,也不需加上前缀。好的名称应描述语义,而非类型。
3) 对预定义对象实例使用公共静态只读字段。如:public static readonly Color Red = new Color(0x0000FF);
常量的命名规则比较特别,要求所有单词都大写,多个单词间用“_”分隔,如: public const string PAGE_TITLE = "Welcome";
集合是一组组合在一起的类似的类型化对象,如哈希表、查询、堆栈、字典和列表,集合的命名使用复数。
参数的命名遵循如下规则: 使用动词或动词短语命名方法、使用 Pascal 大小写,同一方法有保留参数时,尽量通过重载来实现;
参数的命名遵循如下规则: 使用名词或名词短语命名属性,不使用匈牙利命名规则,采用Pascal命名规则,可考虑与属性类型相同的对象名称来创建属性,如下所示:
public enum Color
{
// Insert code for Enum here.
}
public class Control
{
public Color Color
{
get{……}
set{……}
}
}
参数的命名遵循如下规则:
1) 事件处理程序名常考虑使用动词或动词词组,采取Pascal命名规则,使用 EventHandler 后缀,但不使用前缀(如不使用OnClose的命名);
2) 指定两个名为 sender 和 e 的参数。sender 参数表示引发事件的对象。sender 参数始终是object 类型的,即使在可以使用更为特定的类型时也如此。与事件相关联的状态封装在名为 e 的事件类的实例中;
3) 使用动名词(动词的“ing”形式)创建表示事件前的概念的事件名称,用过去式表示事件后。例如,可以取消的 Close 事件应当具有 Closing 事件和 Closed 事件。而不是使用BeforeXxx/AfterXxx 命名模式;
4) 通常情况下,对于可以在派生类中重写的事件,应在类型上提供一个受保护的方法(称为 OnXxx)。此方法只应具有事件参数 e,因为发送方总是类型的实例。
以下示例阐释正确命名的事件参数EventArgs和事件处理程序:
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;
}
}
}
public delegate void MouseEventHandler(object sender, MouseEventArgs e);
控件的命名采取匈牙利命名规则,参见附录中的控件命名规范;
每行最多包含一个语句。如:
a++; //推荐
b--; //推荐
a++; b--; //不推荐
复合语句是指包含"父语句{子语句;子语句;}"的语句,使用复合语句应遵循以下几点:子语句要缩进,左花括号“{” 在复合语句父语句的下一行并与之对齐,即使只有一条子语句要不要省略花括号“ {}”。 如:
for (int i=0; i<count; i++)
{
n++;
}
return语句中不使用括号,除非它能使返回值更加清晰。如:
return;
return myDisk.size();
return (size ? size : defaultSize);
在使用if语句时,避免在布尔条件语句中调用函数。赋值到局部变量并检查它们的值。如下所示:
//避免以下用法
if(iseverythingok())
{...}
//推荐以下用法
bool ok = iseverythingok();
if(ok)
{...}
if、if-else、if else-if 语句使用格式如下:
if (condition)
{
statements;
}
if (condition)
{
statements;
}
else
{
statements;
}
if (condition)
{
statements;
}
else if (condition)
{
statements;
}
else
{
statements;
}
在使用for语句时应注意:在循环过程中不要修改循环计数器,避免产生空循环体(所谓空循环体是指:所有的操作都在initialization、condition 或 update中实现,而没有实质性的循环过程);for 语句使用格式如下:
for (initialization; condition; update)
{
statements;
}
在使用foreach 语句时,同样须避免产生空循环体,使用格式如下:
foreach (object obj in array)
{
statements;
}
while 语句使用格式如下:
while (condition)
{
statements;
}
do - while 语句使用格式如下:
do
{
statements;
} while (condition);
使用switch分支语句时,请注意:所有的非空 case 语句必须用 break或return语句来结束分支,语句switch中的每个case各占一行,语句switch中的case按归顺一定的顺序排列(如按字母升序序或数字大小升序排列),为所有switch语句提供default分支。switch - case语句使用格式如下:
switch (condition)
{
case 1:
statements;
break;
case 2:
statements;
break;
default:
statements;
break;
}
语句使用格式如下:
try
{
statements;
}
catch (ExceptionClass e)
{
statements;
}
finally
{
statements;
}
using 块语句使用格式如下:
using (object)
{
statements;
}
避免在同一方法体中使用多个goto语句,使用多个goto语句时让方法的可读性和维护性变得十分糟糕。goto 语句使用格式如下:
goto Label1;
statements;
Lable1:
statements;
1) 编码中只抛出显示处理后的异常,在捕获 (catch) 语句的抛出异常子句中 (throw) ,总是抛出原始异常,用以维护原始错误的堆栈分配,如:
catch(Exception exception)
{
MessageBox.Show(exception.Message);
throw ; // 和 throw exception 一样。
}
2) 在循环操作中,不推荐直接return操作,而是以break来进行替代。如下所示:
for(int i=0;i<10;i++) {
If (i==1)
{
break;
}
……….实现的for循环代码块
}
3) 不要声明public的event,而应使用事件访问器,如下:
public class Source
{
private EventHandler _NumberChangeEvent;
public event EventHandler NumberChangeEvent
{
add
{
_NumberChangeEvent += value;
}
remove
{
_NumberChangeEvent -= value;
}
}
}
4) 尽量避免强制类型转换,而是采取as来进行转换,如果不得不做类型转换,尽量用显式方式,如下所示:
Animal animal = new Dog();
Dog dog = animal as Dog;
if (dog != null)
{
…….实现的代码块
}
5) 生成和构建一个长的字符串时,一定要使用StringBuilder,而不用string;
6) 尽量不用使用this引用,除非是要调用类中的另一个Constructor;
public class Person
{
private string _strName;
public Person(string name)
{
_strName=name;
}
public Person() : this("Jim")
{
}
}
7) 除非为了解决调用基类构造函数时成员名的冲突,否则不要使用base访问基类的成员;
public class dog
{
public dog(string name)
{}
public virtual void bark(int howlong)
{}
}
public class germanshepherd : dog
{
public germanshepherd(string name): base(name)
{}
public override void bark(int howlong)
{
base.bark(howlong);
}
}
8) 对于泛型,类型使用大写字母,当处理.NET格式Type时使用Type后缀;
//推荐的做法
public class LinkedList<K, T>
{..}
//不推荐的做法
public class LinkedList<KeyType,DataType>
{..}
9) 对于匿名方法参照有规律的代码规划,其缩进应与匿名委托声明对齐;
delegate void SomeDelegate (string someString);
//推荐的做法
public void InvokeMethod()
{
SomeDelegate someDelegate=delegate (string name)
{
MessageBox.Show(name);
};
someDelegate ("Juval");
}
//不推荐的做法
public void InvokeMethod()
{
SomeDelegate someDelegate=delegate (string name)
{MessageBox.Show(name);};
someDelegate(”Juval");
}
10) 对非密封类总是将public和protected方法标记为virtual,有助于派生类的重写;
11) 永远不要假设一种类型支持某个接口,而应做防护性地检查是否支持该接口;
public interface IDemoInterface
{…..}
public class DemoClass : IDemoInterface
{……}
//推荐的使用方法
DemoClass obj = new DemoClass();
IDemoInterface obj2 = obj as IDemoInterface;
if (null != obj2)
{
obj2.method1();
}
else
{
…….
}
12) 泛型接口不要定义限制。接口层的限制通常能用强类型代替。
public class customer
{...}
//避免
public interface ilist where t : customer
{...}
//正确
public interface icustomerlist : ilist
{...}
无。
匈牙利命名法是一名匈牙利程序员发明的,而且他在微软工作了多年。此命名法就是通过微软的各种产品和文档传出来的。多数有经验的程序员,不管他们用的是哪门儿语言,都或多或少在使用它。
这种命名法的基本原则是:
变量名=属性+类型+对象描述
即一个变量名是由三部分信息组成,这样,程序员很容易理解变量的类型、用途,而且便于记忆。
下边是一些推荐使用的规则例子,你可以挑选使用,也可以根据个人喜好作些修改再用之。
⑴属性部分:
全局变量: g_
常量 : c_
类成员变量: m_
⑵类型部分:
指针: p
句柄: h
布尔型: b
浮点型: f
无符号: u
⑶描述部分:
初始化: Init
临时变量: Tmp
目的对象: Dst
源对象: Src
窗口: Wnd
下边举例说明:
hwnd: h表示句柄,wnd表示窗口,合起来为“窗口句柄”。
m_bFlag: m表示成员变量,b表示布尔,合起来为:“某个类的成员变量,布尔型,是一个状态标志”。
变量命名规则
类型 |
前缀 |
示例 |
Array |
arr |
arrShoppingList |
Boolean |
bln |
blnIsPostBack |
Byte |
byt |
bytPixelValue |
Char |
chr |
chrDelimiter |
DateTime |
dtm |
dtmStartDate |
Decimal |
dec |
decAverageHeight |
Double |
dbl |
dblSizeofUniverse |
Integer |
int |
intRowCounter |
Long |
lng |
lngBillGatesIncome |
Object |
obj |
objReturnValue |
Short |
sht |
shtAverage |
Single |
sng |
sngMaximum |
String |
str |
strFirstName |
控件命名规范
类型 |
前缀 |
示例 |
AdRotator |
adrt |
adrtTopAd |
Button |
btn |
btnSubmit |
Calendar |
cld |
cldMettingDates |
CheckBox |
chk |
chkBlue |
CheckBoxList |
chkl |
chklFavColors |
CompareValidator |
cv |
cvValidAge |
CustomValidator |
xv |
xvDBCheck |
DataGrid |
dg |
dgTitles |
DataList |
dl |
dlTitles |
DropDownList |
ddl |
ddlCountries |
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 |
rdo |
rdoFemale |
RadioButtonList |
rdol |
rdolGender |
RangeValidator |
rv |
rvAge |
RegularExpression |
re |
reEmail_Validator |
Repeater |
rpt |
rptQueryResults |
RequiredFieldValidator |
rfv |
rfvFirstName |
Table |
tbl |
tblCountryCodes |
TableCell |
tc |
tcGermany |
TableRow |
tr |
trCountry |
TextBox |
txt |
txtFirstName |
ValidationSummary |
vs |
vsFormErrors |
XML |
xml |
xmlTransformResults |
GroupBox |
grp |
grpDepartments |
PictureBox |
pic |
picUserPhoto |
ComboBox |
cbo |
cboCity |
TreeView |
tvw |
trwProductType |
ListView |
lvw |
lvwDepartement |
TabControl |
tab |
tabEmployees |
DateTimePicker |
dtp |
dtpBirthday |
Timer |
tmr |
tmrClock |
Splitter |
spl |
splTopBottom |
ProgressBar |
pbar |
pbarProcess |
RichTextBox |
rtb |
rbtAddress |
ImageList |
imgl |
imglSources |
ToolBar |
tlb |
tlbNavigator |
MenuItem |
mnu |
mnuFile |
Crystal Report |
rpt |
rptEmployeeMonthSalary |
ADO.NET变量命名规范
类型 |
前缀 |
示例 |
Connection |
conn |
connNorthwind |
Command |
cmd |
cmdReturnProducts |
Parameter |
parm |
parmProductID |
DataAdapter |
da |
daProducts |
DataReader |
dtr |
dtrProducts |
DataSet |
ds |
dsNorthWind |
DataTable |
dt |
dtProduct |
DataRow |
dr |
drRow98 |
DataColumn |
dc |
dcProductID |
DataRelation |
drel |
drelMasterDetail |
DataView |
dvw |
dvwFilteredProducts |