1、12.1 错误和异常处理12.2 C#编程规则12.3 小结12.1 错误和异常处理错误可以分为以下错误可以分为以下3类。类。语法错误:程序代码的编写中,没有按照语法错误:程序代码的编写中,没有按照规定的语法则会产生语法错误。规定的语法则会产生语法错误。逻辑错误:程序逻辑处理出现的错误。逻逻辑错误:程序逻辑处理出现的错误。逻辑错误会导致实际处理结果和预测结果不辑错误会导致实际处理结果和预测结果不相符。相符。运行时错误:该错误通常表现为内存泄露、运行时错误:该错误通常表现为内存泄露、以零作除数等,这些异常会在运行时出现,以零作除数等,这些异常会在运行时出现,难以确定错误起因。难以确定错误起因。1
2、2.1.1 异常处理类Exception是异常类的基类。是异常类的基类。Exception类的常用属性:类的常用属性:Message、Data、Source、StackTrace等。等。异常类中最重要的属性就是异常类中最重要的属性就是Message属性属性和和StackTrace属性。属性。Message属性中包含属性中包含了出错的原因。了出错的原因。StackTrace属性记录了出属性记录了出错的详细方法名称。错的详细方法名称。异常可由系统抛出,也可由客户程序使用异常可由系统抛出,也可由客户程序使用throw关键字引发关键字引发 12.1.1 异常处理类 异常继承体系:异常继承体系:12.1
3、.1 异常处理类常用系统异常类:常用系统异常类:OutOfMemoryException:没有足够的内存继续:没有足够的内存继续执行程序引发的异常;执行程序引发的异常;InvalidCastException:因无效类型转换或显式转:因无效类型转换或显式转换引发的异常;换引发的异常;OverflowException进行算术运算、类型转换或转进行算术运算、类型转换或转换操作导致溢出的异常;换操作导致溢出的异常;ApplicationException:是第三方定义的异常基:是第三方定义的异常基类类,此异常只能由用户程序引发,而不能由系统引,此异常只能由用户程序引发,而不能由系统引发。发。12.
4、1.2 捕获异常方式错误发现方式错误发现方式:使用调试器测试:通常每种开发语言环境使用调试器测试:通常每种开发语言环境都有调试器,并且都方便实用。都有调试器,并且都方便实用。单元测试:即针对程序模块进行的测试。单元测试:即针对程序模块进行的测试。集成测试:也称为联合测试或组装测试。集成测试:也称为联合测试或组装测试。确认测试:也称为有效性测试。确认测试确认测试:也称为有效性测试。确认测试通常也使用黑盒测试方式,需要根据用户通常也使用黑盒测试方式,需要根据用户的需求输入一些数据,以检查软件是否可的需求输入一些数据,以检查软件是否可以正常运行。以正常运行。12.1.2 捕获异常方式使用调试器进行调
5、试的方式:使用调试器进行调试的方式:断点:是程序执行暂停的地方。断点:是程序执行暂停的地方。3个方法设置断点,在个方法设置断点,在菜单栏中单击菜单栏中单击【调试调试】|【新建断点新建断点】命令,或者在行命令,或者在行的最左边单击,或者按的最左边单击,或者按【F9】键。只需再执行一遍和键。只需再执行一遍和设置断点相同的操作即可取消断点。设置断点相同的操作即可取消断点。执行光标:执行光标一般黄色的,用于标识程序当前执行光标:执行光标一般黄色的,用于标识程序当前运行到的行。运行到的行。调试工具栏:是包含调试时的常用命令的工具栏调试工具栏:是包含调试时的常用命令的工具栏,包,包括启动调试、全部中断、停
6、止调试、重新启动、显示括启动调试、全部中断、停止调试、重新启动、显示下一语句、逐语句、逐过程和跳出命令按钮。下一语句、逐语句、逐过程和跳出命令按钮。断点管理窗口断点管理窗口自动窗口自动窗口局部变量窗口局部变量窗口监视窗口监视窗口即时窗口即时窗口12.1.2 捕获异常方式 断点管理窗口:该窗口列出了所有断点,其断点管理窗口:该窗口列出了所有断点,其中每一行都代表一个断点,每个断点都由所中每一行都代表一个断点,每个断点都由所在文件、条件、命中次数等项来描述。在文件、条件、命中次数等项来描述。自动窗口:必须在调试运行时才能打开自动窗口:必须在调试运行时才能打开,“自动窗口自动窗口”自动跟踪运行光标的
7、当前行和自动跟踪运行光标的当前行和下一行的变量,显示变量列表和变量当前值。下一行的变量,显示变量列表和变量当前值。“自动窗口自动窗口”的变量是系统自动跟踪的,无的变量是系统自动跟踪的,无需自行添加。而且,当运行光标所在语句行需自行添加。而且,当运行光标所在语句行有方法调用时,有方法调用时,“自动窗口自动窗口”将显示该方法将显示该方法以及包含该方法调用的所有方法的返回值。以及包含该方法调用的所有方法的返回值。12.1.2 捕获异常方式局部变量窗口:局部变量窗口跟踪当前局部范局部变量窗口:局部变量窗口跟踪当前局部范围内所有变量,跟踪的局部范围就是该方法的围内所有变量,跟踪的局部范围就是该方法的作用
8、范围,也就是说局部变量窗口可以显示方作用范围,也就是说局部变量窗口可以显示方法内出现的所有变量。法内出现的所有变量。监视窗口:可以自定义要跟踪的变量监视窗口:可以自定义要跟踪的变量。即时窗口:即时窗口:“即时窗口即时窗口”可以不在调试时执行。可以不在调试时执行。如果在调试中执行,在如果在调试中执行,在“即时窗口即时窗口”里可以计里可以计算表达式、执行语句、跟踪变量等。算表达式、执行语句、跟踪变量等。12.1.2 捕获异常方式结构化异常处理结构化异常处理:对于结构化异常处理,使用:对于结构化异常处理,使用try catch语句结构来捕获和处理错误语句结构来捕获和处理错误。如果进。如果进行了异常处
9、理,那么行了异常处理,那么CLR将调用异常处理代码;将调用异常处理代码;如果未进行异常处理,那么如果未进行异常处理,那么CLR会终止程序的会终止程序的执行并弹出错误提示窗口。其语法形式为:执行并弹出错误提示窗口。其语法形式为:try 正常处理模块正常处理模块Catch(Exception e)错误处理模块错误处理模块12.1.2 捕获异常方式示例:示例:static void Main(string args)int a=new int5;try a10=1;catch(Exception e)Console.WriteLine(数组访问错误数组访问错误,0,e.Message);Consol
10、e.ReadLine();12.1.3 自定义异常处理类 自定义异常类语法形式如下。自定义异常类语法形式如下。public class UserMessageException:ApplicationException public UserMessageException(String msg):base(msg)对于自定义异常处理类,需要人为引发异常,对于自定义异常处理类,需要人为引发异常,因此需要使用因此需要使用throw关键字显式引发异常。关键字显式引发异常。12.1.3 自定义异常处理类throw使用示例:使用示例:static void Main(string args)try .
11、if(ia.Length)throw new IndexOutOfRangeException();ai=int.Parse(Console.Readline();catch(System.IndexOutOfRangeException e)/数组越界异常数组越界异常 12.1.3 自定义异常处理类自定义异常类使用示例:自定义异常类使用示例:class EmailException:Exception string errorname;/出错人姓名出错人姓名 string errmsg;/错误信息错误信息 public EmailException(string msg,string nam
12、e):base(msg)/构构造函数造函数 errorname=name;errordate=DateTime.Now.ToString();errormsg=msg;public void SendToMail()Console.WriteLine(errorname+”+errormsg);12.1.3 自定义异常处理类代码接上节代码接上节 class Test static bool CheckEmail()return false;static void Main(string args)try if(!CheckEmail()throw new EmailException(电子邮件
13、地址有误!电子邮件地址有误!,杰克杰克);catch(EmailException e)e.SendToMail();12.2 C#编程规则 12.2.1 源代码内部注释规则 文件头部注释 规则1:文件包含文件头,需要说明文件名、作者、创建时间、变更记录等。/*文件名:文件名:NetPrint.cs*作者:作者:xxx*创建日期:创建日期:2008年年12月月3日日*描述:完成打印功能描述:完成打印功能*修改日期:修改日期:2008年年12月月31日日*Email:*/12.2.1 源代码内部注释规则 规则规则2:推荐采用:推荐采用.NET形式书写头部注释。形式书写头部注释。示例:示例:/文件
14、名:文件名:NetPrint.cs/作者:作者:xxx/创建日期:创建日期:2008年年12月月3日日/描述:完成打印功能描述:完成打印功能/修改日期:修改日期:2008年年12月月31日日/Email:VisualS 源代码内部注释规则类及其成员注释类及其成员注释 规则规则1:对方法和类的注释要使用三斜线(:对方法和类的注释要使用三斜线(/)示例:示例:/功能:对于此类功能的描述功能:对于此类功能的描述/作者:作者中文名作者:作者中文名/日期:编写日期等日期:编写日期等/class BookSystem /图书详细信息查询图书详细信息查询 /public DataSet SelectBook
15、s(int id)12.2.1 源代码内部注释规则 规则规则2:代码行文注释需使用:代码行文注释需使用“/”和和“/*/”,应尽量详细说明。,应尽量详细说明。示例:示例:public DataSet SelectBooks(int id)/*书籍书籍ID*/DataSet dsBook;/书籍数据集书籍数据集12.2.2 用法约定 命名规则命名规则 骆驼命名法(骆驼命名法(Camel):即名称像骆驼背一):即名称像骆驼背一样跌宕起伏。该命名法要求名称的首单词要样跌宕起伏。该命名法要求名称的首单词要小写,随后的单词首字母要大写,例如下列小写,随后的单词首字母要大写,例如下列代码:代码:void
16、printEmployeePaychecks()帕斯卡命名法(帕斯卡命名法(Pascal):与骆驼命名法类):与骆驼命名法类似,区别在于要求首单词大写,而骆驼命名似,区别在于要求首单词大写,而骆驼命名法要求小写,例如下列代码:法要求小写,例如下列代码:void PrintEmployeePaychecks()命名规则命名规则 匈牙利命名法(匈牙利命名法(Hungarian):匈牙利命):匈牙利命名法是一位名为名法是一位名为Charles Simonyi的匈牙的匈牙利程序员发明的。基本原则是变量名类利程序员发明的。基本原则是变量名类型对象描述。型对象描述。示例:示例:class cBitmap;
17、string sCustomers;int nLength;bool bEnable;命名规范命名规范命名规范命名规范 类的命名规范:类的命名规范:在类中需使用在类中需使用Pascal规则命名类名。规则命名类名。class Person使用能够反映类功能的名词或名词短语命名类。使用能够反映类功能的名词或名词短语命名类。public class FileStream不能使用不能使用“_”、“C”、“I”等具备特定含义的前缀。等具备特定含义的前缀。class _ManagerSystem/最好不要这样定义。最好不要这样定义。自定义异常类应以自定义异常类应以Exception结尾。结尾。class
18、TvException 命名规范命名规范 类字段命名规范如下类字段命名规范如下 使用使用Camel命名规则为类成员变量命名,即命名规则为类成员变量命名,即首单词(或单词缩写)小写。首单词(或单词缩写)小写。string stuName;类字段变量名前可加类字段变量名前可加“_”前缀。前缀。string _stuName;禁止在普通变量前加禁止在普通变量前加“m_”前缀,这是前缀,这是C语语言中较老的命名规则。言中较老的命名规则。string m_stuName;命名规范命名规范方法的命名规范方法的命名规范使用使用Pascal命名规则为方法命名,即首字母大命名规则为方法命名,即首字母大写。写。p
19、ublic void DoubleValue()方法名应尽量使用动词或动词短语。方法名应尽量使用动词或动词短语。void RemoveAll()类中的访问修饰符或功能相同的方法应该放置类中的访问修饰符或功能相同的方法应该放置在一起,且公共或实现接口的方法在前。在一起,且公共或实现接口的方法在前。命名规范命名规范 属性的命名规范属性的命名规范:使用名词定义属性,使用使用名词定义属性,使用Pascal命令规则为命令规则为属性命名,即首字母大写。属性命名,即首字母大写。public Color BookName 属性和相应字段名称要关联。属性和相应字段名称要关联。public class Book
20、private string bookName;public Color BookName get return bookName;命名规范命名规范参数的命名规范参数的命名规范 使用使用Camel命名规则为参数命名,即首字母小命名规则为参数命名,即首字母小写,例如下列代码。写,例如下列代码。string Format(string format,object args)使用描述性参数名称,参数名称应当具有说明使用描述性参数名称,参数名称应当具有说明性。性。不能给参数加匈牙利类型表示法的前缀。不能给参数加匈牙利类型表示法的前缀。例如下列代码是不合理的。例如下列代码是不合理的。void Inser
21、t(string sName,string strAddress)正确形式如下。正确形式如下。void Insert(string name,string address)命名规范命名规范常量的命名规范常量的命名规范 使用使用Pascal命名规则为只读常量命名,即首字命名规则为只读常量命名,即首字母大写母大写使用使用Pascal命名规则为枚举命名,因为枚举成命名规则为枚举命名,因为枚举成员本属于常量,命名规则同上员本属于常量,命名规则同上 使用使用Pascal命名规则为静态成员或属性命名,命名规则为静态成员或属性命名,即首字母大写即首字母大写 命名规范命名规范接口的命名规范接口的命名规范 使用
22、使用Pascal规则为接口命名,且必须以大写规则为接口命名,且必须以大写I开开头。头。public interface IDataPortpublic interface IFormTable接口名称要有意义,中间不能有下划线接口名称要有意义,中间不能有下划线“_”等字符,例如下列代码。等字符,例如下列代码。interface I_Data_Port;/这是不合适的这是不合适的如果类实现了接口,名称尽量和接口相同,只如果类实现了接口,名称尽量和接口相同,只是省略掉是省略掉“I”字符。字符。命名规范命名规范事件的命名规范事件的命名规范 使用使用Pascal命名规则为委托命名,即首字母大命名规则为
23、委托命名,即首字母大写,例如下列代码。写,例如下列代码。public delegate void CountHandler(int x,int y)定义事件的委托要使用定义事件的委托要使用EventHandler后缀,且后缀,且包含包含sender和和e两个参数,例如下列代码。两个参数,例如下列代码。delegate void MouseEventHandler(object sender,MouseEventArgs e);事件用到的参数类,名称要用到带事件用到的参数类,名称要用到带EventArgs的后缀。的后缀。public class MouseEventArgs:EventArgs命
24、名规范命名规范命名空间的命名规范命名空间的命名规范使用使用Pascal命名规则为命名空间命名,即首字命名规则为命名空间命名,即首字母大写。母大写。namespace HairCompany /命名空间内容命名空间内容命名空间的名称要尽量能够反映其内容所提供命名空间的名称要尽量能够反映其内容所提供的整体功能。的整体功能。Microsoft.MediaMicrosoft.Media.Design行文规范 缩写规范缩写规范 排版规范排版规范 语句结构的规范语句结构的规范 代码缩进规范代码缩进规范 大小写规范大小写规范 重名规范重名规范 系统命名规范系统命名规范 12.3 小结 本章详细介绍了结构化异
25、常处理、本章详细介绍了结构化异常处理、C#的的语言规范及其注意事项。程序中的错误主语言规范及其注意事项。程序中的错误主要为语法错误、逻辑错误和运行时错误。要为语法错误、逻辑错误和运行时错误。其中,语法错误可以通过编译过程发现,其中,语法错误可以通过编译过程发现,而逻辑错误和运行时错需通过系统提供的而逻辑错误和运行时错需通过系统提供的结构化异常处理查找错误。针对异常处理,结构化异常处理查找错误。针对异常处理,介绍了异常处理类和捕获异常的方式,并介绍了异常处理类和捕获异常的方式,并介绍了如何自定义异常处理类。本章最后介绍了如何自定义异常处理类。本章最后对代码的注释规范、命名规范、行文规范对代码的注释规范、命名规范、行文规范分别进行了详细介绍。分别进行了详细介绍。