1 文件组织
1.1 C#源文件
把每个类都放在单独的文件中,文件名字和类名一致(用.CS作为扩展名)。类文件不要太长,不要超过2000LOC。必要时,分割代码,使结构更清晰。
1.2 目录安排
为每个命名空间创建一个目录(如,对于MyProject.TestSuite.TestTier使用MyProject/TestSuite/TestTier作为路径,不要使用带“.”的命名空间)。这样更易于映射命名空间到目录。
2 缩进
2.1 分行
如果表达式不适合单行显示,应根据下面通常的原则分行:
l 在一个逗号后换行
l 在一个操作符后换行
l 在表达式的高层次处换行
l 新行与前一行在同一层次,并与表达式的起始对齐
方法分行的例子:
long MethodCall(expr1, expr2,
expr3, expr4, expr5);
算术表达式分行的例子:
好的:
var = a * b / (c – g + f) +
4 * z;
坏的风格,要避免:
var = a * b / (c – g +
f) + 4 * z;
第一个是好的,因为分行符合高层次规则。
2.2 空白
不要使用空格缩进 - 使用tabs!
3 注释
3.1 块注释
通常要避免块注释,而使用C#标准的///注释来描述。如果希望使用块注释,应该使用下面的风格:
/ * Line 1
* Line 2
* Line 3
*/
块注释很少使用,通常是用来注释掉大块的代码。
3.2 单行注释
应该使用//注释掉一行代码,也可以用它注释掉代码块。当单行注释用来做代码解释时,必须要缩进到与代码对齐。
3.3 文档注释
单行XML注释的形式如下:
/// <summary>
/// This class…
/// </summary>
多行XML注释的形式如下:
/// <exception cref=”BogusException”>
/// This exception gets thrown as soon as a
/// Bogus flag gets set.
/// </exception>
4 声明
4.1每行声明的数量
建议每行只有一个声明,还方便注释,如:
int level; // indentation level
int size; // size of table
变量的命名意义要明确。如果能够自解释,如indentLevel,就不用注释。
不好的:
int a, b; // What is ‘a’? What does ‘b’ stand for?
4.2 初始化
尽量在局部变量声明时进行初始化,例如:
string name = myObject.Name;
或
int val = time.Hours;
注意:初始化对话框时,尽量使用语句:
Using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
……
}
4.3 类和接口的声明
当写C#类和接口时,应按照下面的格式规则:
l 在方法名字和参数列表的起始括号“(”之间没有空格
l 开括号“{”应出现在声明语句之后的下一行
l 闭括号“}”自己占一行,并缩进到对应的开括号位置
例如:
class MySample : MyClass, IMyInterface
{
int myInt;
public MySample(int myInt)
{
this.myInt = myInt;
}
void Inc()
{
++myInt;
}
void EmptyMethod()
{
}
}
5 语句
5.1 简单语句
每行应该只包含一个语句。
5.2 返回语句
返回语句不应该带有最外面的括号。
不应该使用:
return (n * (n + 1) / 2);
应该使用:
return n * (n + 1) / 2;
5.3 If, if - else, if else - if else语句
if, if – else和if else – if else语句应该按照下面格式:
if (condition)
{
……
}
if (condition)
{
……
}
else
{
……
}
if (condition)
{
……
}
else if (condition)
{
……
}
else
{
……
}
注意:即使某条件下只有一个语句,也要使用大括号“{”“}”。后面的循环等语句也一样。
5.4 for / foreach语句
for语句形式如下:
for (int i = 0; i < 5; ++i)
{
……
}
或者使用单行形式:
for (initialization; condition; updat);
单行形式可考虑使用while语句代替。
foreach语句如下:
foreach (int i in intList)
{
……
}
5.5 while / do – while语句
while语句如下:
while (condition)
{
……
}
空的while语句形式如下:
while (condition);
do – while语句如下:
do
{
……
}
while (condition);
5.6 switch语句
switch语句形式如下:
switch (condition)
{
case A :
……
break;
case B :
……
break;
default :
……
break;
}
5.7 try – catch语句
try – catch语句形式如下:
try
{
……
}
catch (Exception e)
{
……
}
或者
try
{
……
}
catch (Exception e)
{
……
}
finally
{
……
}
5.8 属性
属性形式如下:
public string Name
{
get
{
……
}
set
{
……
}
}
对于抽象属性:
public string Name
{
get;
set;
}
5.9 枚举
枚举形式如下:
public enum Color
{
Red,
Green,
Blue
}
6 空白
6.1 空行
使用空行按照逻辑关系分隔代码,能提高可读性。
在下面元素之间要使用一个空行:
l 构造函数
l 属性
l 方法
l 方法内的逻辑块
6.2 内部空格
在逗号或分号之后应该有一个空格,例如:
应该使用:
TestMethod(a, b, c);
不应该使用:
TestMethod(a,b,c);或者TestMethod( a, b, c );
操作符两边要有一个空格(递增和逻辑否等一元操作符除外),例如:
应该使用:
a = b;
不应该使用:
a=b;
应该使用:
for (int i = 0; i < 10; ++i)
不应该使用:
for (int i=0; i<10; ++i)或者for(int i=0;i<10;++i)
7命名约定
7.1 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 |
7.2 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 |
7.3 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 |
7.4变量
1、 变量的作用域及前缀
前缀 | 说明 | 举例 |
P | 全局变量 | pstrName |
St | 静态变量 | ststrName |
M | 模块或者窗体的局部变量 | MstrName |
A | 数组 | AintCount[] |
2、 变量数据类型的前缀
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 |
7.5其他
常量定义
常量=作用域+ c+数据类型+变量名
类对象定义
类实例=作用域+cls+变量名
类对象=C+名称
结构对象定义
结构对象实例=作用域+struc+变量名
结构对象=S+名称
命名空间定义
以层为前缀进行命名
接口定义
以大写I为前缀
窗体的命名规则
窗体名=frm+窗体名(名词+动词)
注意:保存的文件明和窗体名相同。
枚举定义规则
以Enum为前缀
事件命名规则
事件控制器要带有EventHandler后缀
使用sender和e命名两个参数
事件参数类要带有EventArgs后缀
考虑使用动词命名事件
对于有“之前”或“之后”概念的事件,要使用现在时或过去时命名
8 编程实践
8.1 书写顺序
书写类时,按照从上到下的顺序,类成员应该是域,构造函数,属性,方法。
8.2 成员可视性
类的域都应该是private,如果需要被外部访问,使用public属性进行访问。但也有例外:
l 如果类的域仅作为一种数据集合,可以将域设定为public,这样的类不要有任何方法
l 常量域,静态域或静态常量域可以设定为public
l private是默认的类成员访问修饰符,可以省略,但为了明确表达,应该书写出来。
8.3功能单一
类的功能要单一,不要组合没有直接关联的功能。方法也一样。一个方法只完成一个任务,不要把多个任务组合进一个方法,即使那些任务很小。就是说,应该以逻辑功能来界分类或方法。
8.4使用枚举
不要使用数字或字符串来指示离散值,应该使用枚举。
不好的:
void SendMail(string message, string mailType)
{
switch (mailType)
{
case "Html" :
……
break;
case "PlainText" :
……
break;
case "Attachment" :
……
break;
default :
……
break;
}
}
好的:
enum MailType
{
Html,
PlainText,
Attachment
}
void SendMail(string message, MailType mailType)
{
switch (mailType)
{
case MailType.Html :
……
break;
case MailType.PlainText :
……
break;
case MailType.Attachment :
……
break;
default :
……
break;
}
}
8.5 捕获异常
只捕获特定的异常,如读取外部文件,而不要捕获一般异常,有利于调试排错。
不要捕获了异常却什么也不错,应该做适当处理,并把结果反馈到界面。如果隐藏了一个异常,将很难知道异