如何在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属性进行查看内部异常。

时间: 2024-11-01 19:30:20

如何在C#中自定义自己的异常的相关文章

bcb 如何在DLL中捕捉系统级异常

http://topic.csdn.net/t/20031023/09/2385627.html -------------------------------------------------- 我创建了一个动态库,库中实现了对Socket(TCP.UDP)的封装,其中使用了BCB的TClientSocket,当使用该ClientSocket去连接一个并不存在的服务器时必然导致会ESocketError异常.问题:我该如何捕捉到该异常? 如下代码明显不行,请哪位高手帮帮忙!!!!!!!!!!

如何在CODESOFT中自定义删除文档备料

CODESOFT 2015是先进的标签设计与集成软件.在使用CODESOFT制作条码标签时,为方便省时,我们可以事先创建自己的文档模板,保存它们以供将来使用.接下来,小编就讲讲CODESOFT 2015自定义备料创建与删除的方法. 查看更多内容请直接前往:http://www.codesoftchina.com/faq/zidingyi-beiliao.html CODESOFT 2015自定义备料的创建: 1.在CODESOFT 2015自定义备料之前,您必须先选择用于生成文档的打印机型号.选

iOS开发之如何在xcode中自定义快捷键

一些常用的注释和常用的代码,因为每次都要重复写,所以显得很麻烦.这时不妨试一试xcode的自定义快捷键功能吧! 为注释添加快捷键: 1. 2. 3.

如何在XAF中显示自定义窗体和控件

https://www.devexpress.com/Support/Center/Example/Details/E911 如何在XAF中显示自定义窗体和控件,布布扣,bubuko.com

如何在SharePoint中配置和自定义Content Query Web Part

如何在SharePoint中配置和自定义Content Query Web Part 2014-01-07 11:15 718人阅读 评论(0) 收藏 举报 之前有一篇blog提到过SharePoint中的Content Query Web Part (CQWP),说的是当SharePoint开启了匿名访问模式后,Content Query Web Part读取Document Library数据失败的问题.从这篇博客开始,我将说一下Content Query Web Part这个东西能做什么,

Android开发如何在4.0及以上系统中自定义TitleBar

本文将通过一个实例讲解怎么实现在4.0及以上系统版本中实现自定义TitleBar,这只是我自己找到的一种方法; xml布局文件 activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="m

如何在App中实现朋友圈功能之二快速实现用户信息的自定义——箭扣科技Arrownock

如何在App中实现朋友圈功能 之二 快速实现用户信息的自定义 自我关联社交元素: anSocial中很多的社交元素API,如帖子(Post).相册(Album).文件(File)等,这些API的可选参数中允许传入其他社交元素的id. 当我们传了这些id时,服务器数据库里保存的是id,但是在返回结果里,会将这些id以对象的形式返回. 这样就大大提升了查询效率,原本需要查询两次的功能,现在可以一次实现,比如接下来要说的用户头像功能开发里可以利用的字段. 用户头像: 当我们在APP上创建用户,需要调用

如何在logback.xml中自定义动态属性

原文地址:http://blog.jboost.cn/trick-logback-prop.html 当使用logback来记录Web应用的日志时,我们通过在logback.xml中配置appender来指定日志输出格式及输出文件路径,这在一台主机或一个文件系统上部署单个实例没有问题,但是如果部署多个实例(比如通过容器的方式),多个实例同时往同一文件写日志可能就会引起问题.这时可以将每个实例的日志文件加以区分,如IP或UUID,或两者结合的形式.这其实就涉及如何在logback.xml中自定义动

如何在ASP.NET Core中自定义Azure Storage File Provider

文章标题:如何在ASP.NET Core中自定义Azure Storage File Provider作者:Lamond Lu地址:https://www.cnblogs.com/lwqlun/p/10406566.html项目源代码: https://github.com/lamondlu/AzureFileProvider 背景# ASP.NET Core是一个扩展性非常高的框架,开发人员可以根据自己的需求扩展出想要的功能.File Provider是ASP.NET Core中的一个重要组件