C# 自定义异常总结及严格遵循几个原则

在C#中所有的异常类型都继承自System.Exception,也就是说,System.Exception是所有异常类的基类. 总起来说,其派生类分为两种:
1. SystemException类: 所有的CLR提供的异常类型都是由SystemException派生。
2. ApplicationException类: 由用户程序引发,用于派生自定义的异常类型,一般不直接进行实例化。

创建自定义异常类应严格遵循几个原则
1. 声明可序列化(用于进行系列化,当然如果你不需要序列化。那么可以不声明为可序列化的)
2. 添加一个默认的构造函数
3. 添加包含message的构造函数
4. 添加一个包含message,及内部异常类型参数的构造函数
5. 添加一个序列化信息相关参数的构造函数.


代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace ConsoleApplication3
{
[Serializable] //声明为可序列化的 因为要写入文件中
public class PayOverflowException : ApplicationException//由用户程序引发,用于派生自定义的异常类型
{
/// <summary>
/// 默认构造函数
/// </summary>
public PayOverflowException() { }
public PayOverflowException(string message)
: base(message) { }
public PayOverflowException(string message, Exception inner)
: base(message, inner) { }
//public PayOverflowException(System.Runtime.Serialization.SerializationInfo info,
// System.Runtime.Serialization.StreamingContext context)
// : base(info, context) { }
}
internal class Employee
{
public int ID { get; set; }
public string Name { get; set; }
/// <summary>
/// current pay
/// </summary>
public int CurrPay { get; set; }
public Employee() { }
public Employee(int id, string name, int currpay)
{
this.ID = id;
this.Name = name;
this.CurrPay = currpay;
}
/// <summary>
/// 定义一个GiveBunus的虚方法以供不同的派生类进行重载
/// </summary>
/// <param name="amount">奖金额度</param>
public virtual void GiveBunus(int amount)
{
//用一个临时变量记录递增之前的值
var pay = CurrPay;
this.CurrPay += amount;
if (CurrPay > 10000)
{
//发生异常,将CurrPay的值进行恢复,
//并抛出异常,外部程序捕获次异常
this.CurrPay = pay;
var ex = new PayOverflowException("The employee's max pay should be no more than 10000.");
throw ex;
}
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("**** 创建Employee对象,并用try/catch捕获异常 *****");
var emp = new Employee(10001, "Yilly", 8000);
try
{
emp.GiveBunus(3000);
}
catch (PayOverflowException ex)
{
Console.WriteLine("异常信息:{0}\n发生于{1}类的{2}方法", ex.Message,
ex.TargetSite.DeclaringType, ex.TargetSite.Name);
try
{
var file = new FileStream(@"c:\customerexception.txt", FileMode.Create);
//*** 异常信息写入文件中的代码省略...
//以序列化方式写入
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(file, ex);
file.Close();
//以字节方式写入
//byte[] buffer = System.Text.Encoding.Default.GetBytes(ex.Message);
//int leng = 0;
//leng = buffer.GetLength(0);
//file.Write(buffer, 0, leng);
//file.Close();
}
catch (Exception ex1)
{
var inner = new PayOverflowException(ex.Message, ex1);
throw inner;
}
}
}
}
}

值得注意的是:在实例化的时候调用的是PayOverflowException(string message, Exception inner)构造函数,
如果本程序如果有其他程序在调用的时候, 可以通过.InnerExcetpion的Message属性进行查看内部异常。

(0)

相关推荐

  • 解析C#自定义控件的制作与使用实例的详解

    上篇:控件制作本例是制作一个简单的自定义控件,然后用一个简单的测试程序,对于初学者来说,本例子比较简单,只能起到抛石引玉的效果.我也是在学习当中,今后会将自己所学的逐步写出来和大家交流共享.第一步:新建一个控件库项目:myControl 第二步:从工具箱里面拖动1个PictureBox.1个Button.6个Lable控件到用户界面上,布局如下: 如上图,设置pictureBox的Name为picBox,背景为白色,Button的Name为btnOpen,另外靠左的三个Lable的Text属性分

  • 自定义实现Json字符串向C#对象转变的方法

    这里使用Atrribute的方式实现了Json字符串向C#对象的转变.因为功能局限,此版本只是针对于Json字符串,如"response":"Hello","id":21231513,"result":100,"msg":"OK."; 而不是Json数组.这里的Atrribute是作用在属性上,像NHibernate中的Atrribute一样,是在运行时通过反射来获取这个属性对应于Jso

  • 用VBScript实现对Windows注册表的修改详解

    大名鼎鼎的WSH听说过吗? 它就是Windows Script Host的缩写形式,WSH是Windows平台的脚本指令,它的功能十分强大,并且它还是利用语法结构简单.易学易用且功能强大的JScript和VBScript脚本语言,来实现其卓越的功能的,除了本文介绍的修改注册表之外,它还可以访问Excel文件,也能与网络沟通,当然它最大的优势莫过于它能与操作系统沟通,而修改注册表只是它与操作系统沟通的冰山一角.正是它有如此诸多的优点与实用性,正倍受很多Windows用户的青睐,本文就为大家介绍一二

  • 直接双击启动tomcat中的startup.bat闪退原因及解决方法

    免安装的tomcat双击startup.bat后,启动窗口一闪而过,而且tomcat服务未启动. 原因是:在启动tomcat是,需要读取环境变量和配置信息,缺少了这些信息,就不能登记环境变量,导致了tomcat的闪退. 解决办法: 1.在已解压的tomcat的bin文件夹下找到startup.bat,右击->编辑.在文件头加入下面两行: SET JAVA_HOME=D:\Java\jdk1.6.0_10 (java jdk目录) SET TOMCAT_HOME=E:\tomcat-6.0.35

  • 在asp.net(C#)中采用自定义标签和XML、XSL显示数据

    标签定义 复制代码 代码如下: public class Encoding { public string Encode(string cSource) { return System.Web.HttpUtility.HtmlEncode(cSource); } } public class EmList : Label { public override bool EnableViewState { get{ return false;} } public string XslFile{get

  • dos(cmd)中删除、添加、修改注册表命令

    regedit的运行参数 REGEDIT [/L:system] [/R:user] filename1 REGEDIT [/L:system] [/R:user] /C filename2 REGEDIT [/L:system] [/R:user] /E filename3 [regpath] /L:system Specifies the location of the SYSTEM.DAT file. /R:user Specifies the location of the USER.D

  • VC++实现文件与应用程序关联的方法(注册表修改)

    本文实例讲述了VC++实现文件与应用程序关联的方法.分享给大家供大家参考,具体如下: 日常工作中,doc文件直接双击后,就能启动word软件,并读取该文档的内容在软件中显示,这都得益于注册表的配置,我们的软件也需要实现这样的功能,该如何写注册表以及写入哪些内容呢?下面的两个函数就能实现这个功能.CheckFileRelation是检查注册表中是否已经将我们期待的文件格式与相应软件关联了:RegisterFileRelation是直接往注册表中写入相关的key和value. /**********

  • C#设置自定义文件图标实现双击启动(修改注册表)

    程序生成的自定义文件,比如后缀是.test 这种文件怎么直接启动打开程序,并打开本文件呢 1.双击打开 2.自定义的文件,有图标显示 3.自定义的文件,点击右键有相应的属性 后台代码:(如何在注册表中修改信息) //工具启动路径 string toolPath = System.Windows.Forms.Application.StartupPath + "\\邮件小工具.exe"; string extension = SptdConst.FileExtension; string

  • C#中自定义事件和委托实例

    在windows 编程中用到最多的就是控件的事件了,微软给我们很好的方式,把注意力放到事件执行方法的设计和编码上,但是但我们真正弄懂了事件的真正出发执行原理的话,对我们的编程的提高真是非常榜的,例如在windows编程中 如果我单击了一个button按钮触发了button 的click事件  Button1_Click(){} ,但是有时候我们编程的时候,不但想要触发button 的单击事件,我还想要把其他的时间也要调用下来顺序执行,要实现这种方式,除了在方法最后对其他方法的调用,还可以利用将其

  • CMD下读取/修改/删除注册表项的方法

    好在系统自带的regedit.exe足够用了. 1,读取注册表 先将想查询的注册表项导出,再用type查看,比如: C:\>regedit /e 1.reg "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" C:\>type 1.reg | find "PortNumber" "PortNumber"=dw

随机推荐