本文档描述了使用C#作为语言在.NET中开发软件应用程序和类库的规则和建议。主要目的是定义通用的指导方针,以实施一致的编码风格和格式,这对开发人员避免在使用c#开发软件应用程序时经常犯的错误是有用的。本文档涵盖了命名约定、编码风格和一些体系结构级别的建议。
编码标准的目的和实现它的最佳实践
编码标准是一套用于编程语言的指导方针,它推荐编程风格和最佳实践来实现它。
编码标准通常包括缩进、注释、命名约定、编程实践、项目中的文件结构、架构最佳实践等。强烈建议软件开发人员遵循这些指导方针。编码指南有以下优点。
增加编写的源代码的可读性。将包含更少的错误,工作效率更高。需要较少的维护。对于新旧开发人员来说,维护和修改代码都更容易。提高了开发人员的生产力。降低软件开发的总成本。这是一个成功的项目和一个在最坏的情况下交付失败的项目之间的区别。命名约定
在C#编程中有三种常用的命名约定,
Pascal约定-所有单词的第一个字符为大写,其他字符为小写。例如:HelloWorld
驼峰格式约定——除第一个单词外,所有单词的第一个字符都是大写,其他字符都是小写。例如:helloWorld
匈牙利式约定——很久以前开发人员就使用数据类型作为前缀来定义变量。这个约定现在除了局部变量声明外,不在任何地方使用。例如:string m_sName; string strName; int iAge;
控制前缀命名约定
在开发WEB和窗口应用程序时,通常使用的最佳实践是为UI元素使用前缀。因为ASP.NET和Windows Form有太多可用的控件,因此可以用表格来总结它们。
代码缩进和注释
好的布局使用格式来强调代码的结构,使代码更容易阅读。要做到这一点,以下几点是有帮助的:使用Microsoft Visual Studio提供的默认代码编辑器设置。每行只写一条语句和声明。在每个方法之间添加一个空格。使用括号来理解编写的代码。使用xml注释来描述函数、类和构造函数。使用Tab来缩进。使用一个空行来分隔代码的逻辑组。按照下面的方法,使用#region和#endregion来分组相关的代码段私有成员私有财产公共属性构造函数事件处理程序/操作方法私有方法公共方法不要为每一行代码和声明的每个变量都写注释。注释使用//或///避免使用/*如果您因为任何原因不得不使用一些复杂的程序,请用足够的注释很好地记录它。如果所有的变量和方法名都是有意义的,这将使代码非常易读,并且不需要很多注释。良好的编程实践
避免编写长函数。典型的函数最多应该有40-50行代码。如果方法的代码超过50行,则必须考虑将其重构为单独的私有方法。避免编写长类文件。典型的类文件应该包含600-700行代码。如果类文件有700行以上的代码,则必须创建partial类。partial类在编译后将代码组合成单个单元。不要在一个文件中有类的数量。为每个类创建一个单独的文件。避免使用var代替dynamic。在操作符周围添加空格,如 、-、==等。始终在关键字if、else、do、while、for和foreach后面加上开括号和闭括号,即使语言不需要这样做。方法名应该具有有意义的名称,以便它不会误导名称。有意义的方法名不需要代码注释。Good:privatevoidSaveAddress(Addressaddress){}Bad://ThismethodusedtosaveaddressprivatevoidSave(Addressaddress){}
Good:publicvoidUpdateAddress(Addressaddress){}publicvoidInsertAddress(Addressaddress){}Bad:publicvoidSaveAddress(Addressaddress){if(address.AddressId==0){}else{}}
Good:publicclassEmployeeController:Controller{publicActionResultIndex(){}publicActionResultCreate(){}[HttpPost]publicActionResultCreate(EmployeeModelemployee){}publicActionResultEdit(intid){}[HttpPut]publicActionResultUpdate(EmployeeModelemployee){}[HttpDelete]publicJsonResultDelete(intid){}}Bad:publicclassEmployeeController:Controller{publicActionResultGetAll(){}publicActionResultCreateEmployee(){}[HttpPost]publicActionResultCreateEmployee(EmployeeModelemployee){}publicActionResultEditEmployee(intid){}[HttpPut]publicActionResultUpdateEmployee(EmployeeModelemployee){}[HttpDelete]publicJsonResultEmployeeDelete(intid){}}
在上面的例子中,你谈论的是employee,那么不应该有带有employee前缀或扩展名的动作方法名
避免使用普通类型系统。使用语言特定的别名Good:intage;stringfirstName;objectaddressInfo;Bad:System.Int32age;StringfirstName;ObjectaddressInfo;
Good:if(firstName.ToLower()=="yogesh"){}if(firstName.ToUpper()==“YOGESH”){}Bad:if(firstName==“rohit”){}
Good:if(firstName==String.Empty){}Bad:if(firstName==“”){}
Good:publicenumLoggerType{Event,File,Database}publicvoidLogException(stringmessage,LoggerTypeloggerType){switch(loggerType){caseLoggerType.Event://Dosomethingbreak;caseLoggerType.File://Dosomethingbreak;caseLoggerType.Database://Dosomethingbreak;default://Dosomethingbreak;}}Bad:publicvoidLogException(stringmessage,LoggerTypeloggerType){switch(loggerType){case"Event"://Dosomethingbreak;case"File"://Dosomethingbreak;case"Database"://Dosomethingbreak;default://Dosomethingbreak;}}
Good:publicContactGetContactDetails(Addressaddress){if(address!=null&&address.Contact!=null){returnaddress.Contact;}}Bad:publicContactGetContactDetails(Addressaddress){returnaddress.Contact;}
Good:“Erroroccurredwhileconnectingtodatabase.Pleasecontactadministrator.”“Yoursessionhasbeenexpired.Pleaseloginagain.”Bad:“ErrorinApplication.”“Thereisanerrorinapplication.”
Good:publicvoidUpdateAddress(Addressaddress){}Bad:publicvoidUpdateAddress(intaddressId,stringcountry,stringstate,stringphoneNumber,stringpinCode,stringaddress1,stringaddress2){}
Good:varemployee=newEmployee{FirstName=“ABC”,LastName=“PQR”,Manager=“XYZ”,Salary=12346.25};Bad:varemployee=newEmployee();employee.FirstName=“ABC”;employee.LastName=“PQR”;employee.Manager=“XYZ”;employee.Salary=12346.25;
usingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Text;usingCompany.Product.BusinessLayer;
Good:using(varfileToOpen=newFileInfo(fileName)){//Fileoperation}Bad:varfileInfo=newFileInfo(fileName);try{//Fileoperation}finally{if(fileInfo!=null){fileInfo.Delete();}}
voidReadFile(stringfileName){try{//readfromfile.}catch(System.IO.IOExceptionfileException){//logtheerror.Re-throwexceptionthrowfileException;}finally{}}Bad:voidReadFile(stringfileName){try{//readfromfile.}catch(Exceptionex){//catchinggeneralexception}finally{}}
架构设计级别指南
始终使用多层(N-Tier)架构。使用接口和抽象类实现松散耦合的体系结构。使用泛型可以帮助您创建可重用的类和函数publicclassMyClass<T>whereT:SomeOtherClass{publicvoidSomeMethod(Tt){SomeOtherClassobj=t;}}