c语言安全编码指南(编码指南和最佳实践)
c语言安全编码指南(编码指南和最佳实践)
2024-06-22 12:07:03  作者:醉酒生疼  网址:https://m.xinb2b.cn/know/otp237039.html

本文档描述了使用C#作为语言在.NET中开发软件应用程序和类库的规则和建议。主要目的是定义通用的指导方针,以实施一致的编码风格和格式,这对开发人员避免在使用c#开发软件应用程序时经常犯的错误是有用的。本文档涵盖了命名约定、编码风格和一些体系结构级别的建议。

编码标准的目的和实现它的最佳实践

编码标准是一套用于编程语言的指导方针,它推荐编程风格和最佳实践来实现它。

编码标准通常包括缩进、注释、命名约定、编程实践、项目中的文件结构、架构最佳实践等。强烈建议软件开发人员遵循这些指导方针。编码指南有以下优点。

增加编写的源代码的可读性。将包含更少的错误,工作效率更高。需要较少的维护。对于新旧开发人员来说,维护和修改代码都更容易。提高了开发人员的生产力。降低软件开发的总成本。这是一个成功的项目和一个在最坏的情况下交付失败的项目之间的区别。

命名约定

在C#编程中有三种常用的命名约定,

Pascal约定-所有单词的第一个字符为大写,其他字符为小写。

例如:HelloWorld

驼峰格式约定——除第一个单词外,所有单词的第一个字符都是大写,其他字符都是小写。

例如:helloWorld

匈牙利式约定——很久以前开发人员就使用数据类型作为前缀来定义变量。这个约定现在除了局部变量声明外,不在任何地方使用。

例如:string m_sName; string strName; int iAge;

c语言安全编码指南(编码指南和最佳实践)(1)

控制前缀命名约定

在开发WEB和窗口应用程序时,通常使用的最佳实践是为UI元素使用前缀。因为ASP.NET和Windows Form有太多可用的控件,因此可以用表格来总结它们。

c语言安全编码指南(编码指南和最佳实践)(2)

代码缩进和注释

好的布局使用格式来强调代码的结构,使代码更容易阅读。要做到这一点,以下几点是有帮助的:使用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{}}

MVC中的控制器动作应该有有意义的名字,每个动作只有一个责任。

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;

不要硬编码字符串或数字;相反,创建单独的文件sfor常量并将所有常量放入其中,或者在文件顶部声明常量并将这些常量引用到代码中。您还可以在配置文件中以密钥和值对的形式放置一些常量,如数据库连接、记录器文件名、SMTP信息变量等。不要硬编码字符串。使用资源文件。当比较字符串时,将字符串变量转换为大写或小写

Good:if(firstName.ToLower()=="yogesh"){}if(firstName.ToUpper()==“YOGESH”){}Bad:if(firstName==“rohit”){}

使用String.Empty 替代 “”

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;}}

事件处理程序不应包含执行所需操作的代码。而是从事件处理程序调用另一个私有或公共方法。保持事件处理程序或动作方法尽可能干净。不要在代码中硬编码路径或驱动器名。以编程方式获取应用程序路径并使用相对路径。使用输入或输出类System.IO)来实现这一点。在访问对象和复杂对象之前,总是对它们进行空检查。

Good:publicContactGetContactDetails(Addressaddress){if(address!=null&&address.Contact!=null){returnaddress.Contact;}}Bad:publicContactGetContactDetails(Addressaddress){returnaddress.Contact;}

最终使用的错误消息应该是用户友好和自解释的,但使用logger记录实际的异常细节。为此创建常量并在应用程序中使用它们。

Good:“Erroroccurredwhileconnectingtodatabase.Pleasecontactadministrator.”“Yoursessionhasbeenexpired.Pleaseloginagain.”Bad:“ErrorinApplication.”“Thereisanerrorinapplication.”

避免公开公共方法和属性,除非确实需要从类外部访问它们。如果仅在同一个程序集中访问,则使用internal;如果在同一个类中使用,则使用private。避免向函数传递太多参数。如果你有超过4-5个参数,使用类或结构来传递它。

Good:publicvoidUpdateAddress(Addressaddress){}Bad:publicvoidUpdateAddress(intaddressId,stringcountry,stringstate,stringphoneNumber,stringpinCode,stringaddress1,stringaddress2){}

在使用collection时,请注意以下几点:返回集合时,如果没有要返回的数据,则返回空集合,而不是返回null。总是检查Any()运算符,而不是检查count,例如:collection.Count > 0和空值检查遍历时使用foreach而不是for循环。使用IList<T>、IEnumerable<T>、ICollection<T>而不是具体的类,例如使用List<>使用对象初始化器来简化对象创建

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;

如果你正在打开数据库连接、套接字、文件流等,总是在最后一个块中关闭它们。这将确保即使在打开连接后发生异常,该连接也将在finally块中安全关闭。使用c# using语句简化代码。如果您有一个try-finally语句,其中finally块中唯一的代码是对Dispose方法的调用,则使用using语句代替。

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{}}

当必须在循环中操作字符串对象时,使用StringBuilder类而不是String。String对象在.NET中的工作方式很奇怪。每次添加字符串时,它实际上是丢弃旧的字符串对象并重新创建一个新对象,这是一个相对昂贵的操作。

架构设计级别指南

始终使用多层(N-Tier)架构。使用接口和抽象类实现松散耦合的体系结构。使用泛型可以帮助您创建可重用的类和函数

publicclassMyClass<T>whereT:SomeOtherClass{publicvoidSomeMethod(Tt){SomeOtherClassobj=t;}}

将应用程序分离为多个程序集。为UI、业务层、数据访问层、框架、异常处理和日志组件创建单独的组件。不要从UI页面访问数据库。使用数据访问层来执行所有与数据库相关的任务。总是使用存储过程而不是在c#代码中编写内联查询。在创建、更新和删除等数据库操作中始终使用事务。这将有助于在Sql语句执行过程中发生任何异常时再次回滚旧数据。不要将复杂的逻辑放入存储过程中,而是将其放入业务层。类似地,所有系统级的过程都以“sp”开头,函数以“fn”开头,这将触发重载来搜索过程。为了在客户端机器上安装数据库,用户安装程序sql脚本。尝试使用设计模式、实践和坚实的原则。对于相同的代码,创建单独的实用程序文件或将其移动到基类中。在数据层中使用try-catch-finally来捕获所有数据库异常。这个异常处理程序应该记录数据库中的所有异常。记录的详细信息应该包括正在执行的命令的名称、存储的proc名称、参数、使用的连接字符串等。在记录异常之后,它可以被重新抛出到调用者层,这样应用程序就可以捕获它并在UI上显示特定于用户的消息不要将大型对象存储到会话中。将大型或复杂对象存储到会话中可能会消耗服务器内存。在使用后销毁或处置这些会话变量。不要将大型对象存储到视图状态,这会增加页面加载时间。请始终通过NuGet包引用第三方dll、javascripts和css框架,以便随时更新最新版本。总是引用缩小版的javascript或css文件,这将减少服务器不必要的开销。,
  • 旅行回家后每天的样子(简单的记录生活1)
  • 2024-06-22简单的记录生活1今天早上去会展中心开会,8点半的会议,我想着特殊时期,又是查行程,又是看核酸的,得早点到才行,结果我7点50到的时候,连工作人员都没到,饿着肚子,瑟瑟发抖等到8点15分工作人员才到,会议差不多9点才开。
  • 如何投资商铺才能不踩坑(解密商铺投资技巧)
  • 2024-06-22解密商铺投资技巧随着通货膨胀趋势不可阻挡,人民币贬值严重,人们的投资理财意识越来越强,大到买房买铺,小到余额宝你会发现,在你身边的人,无论资产的多少,都会进行一定程度的资产配置但如今,债券、股市风险大,金融平台不靠谱。
  • 临沂火车站片区站前广场:沂蒙路旁天地宽
  • 2024-06-22临沂火车站片区站前广场:沂蒙路旁天地宽沂蒙路纵贯南北,兖石铁路向东西无限延伸,交汇处崭新的临沂火车站在西风中巍然耸立,宽阔的站前广场正在进行最后的地面装饰建设近日,记者通过火车站片区改造项目部获悉,站前广场目前已经进入了最后的地面铺装和装。
  • 尿液很腥臭怎么回事(为什么尿液会有异味)
  • 2024-06-22为什么尿液会有异味正常人每天都会小便但一般很少去关注,但是如果出现异味的话就有可能会问这是什么原因引起来的?这个时候你就要知道可能的一些原因,该不该去找医生咨询?下面是9个最常见的尿液异味尿的原因1.泌尿系结石尿路结石。
  • 六座合资suv奇骏价格(买它合资经典SUV奇骏)
  • 2024-06-22买它合资经典SUV奇骏虽然新能源汽车正在蹿红,但是磕不得碰不得的娇惯劲儿,再加上与同级别燃油车相比价格金贵不少,让许多消费者难以接受对于许多希望在节假日说走就走的人来说,能装能跑,没有里程焦虑的燃油SUV车型仍是理想的选择。
  • 刚顺产的产妇怎样躺着有助恢复(产后妈妈如何选择卧床姿势)
  • 2024-06-22产后妈妈如何选择卧床姿势为了保证精力恢复和乳汁充沛,产后妈妈要注意劳逸结合为了方便母乳喂养,妈妈休息的时间最好与宝宝睡觉的时间保持一致,每天保证8-9个小时的充足睡眠产后妈妈休息时应经常变换卧床姿势,最好俯卧、侧卧和膝胸卧位。
  • 完结小说推荐第一期(03.25完结小说推荐)
  • 2024-06-2203.25完结小说推荐03.25言情丨仙侠修真、快穿、狗血古言、妖艳纯妹1.慢慢仙途之仙灵界作者:绝世小白2.满级大佬带娃记(快穿)作者:木子金三3.画屏美人作者:山间人4.小纯风作者:宋墨归03.25纯爱丨合约、贫穷受、。
  • 夜雨寄北李商隐原文翻译及赏析(夜雨寄北简介)
  • 2024-06-22夜雨寄北简介原文:君问归期未有期,巴山夜雨涨秋池何当共剪西窗烛,却话巴山夜雨时译文:你问我回家的日期,归期难定,今晚巴山下着大雨,雨水已涨满秋池什么时候我们才能一起秉烛长谈,相互倾诉今宵巴山夜雨中的思念之情赏析:。
  • 采茶工有什么工具装茶叶(又是一年采茶季)
  • 2024-06-22又是一年采茶季茶园里,大家采下新芽红网时刻新闻3月11日讯(记者宋沛珊通讯员黄德开)阳春三月,茶乡安化,艳阳高照,春茶飘香3月10日上午,湖南省褒家冲茶场有限公司在安化青山园茶叶基地举行开园仪式,伴随着悠扬的采茶歌。