A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 霍春雨 中级黑马   /  2012-10-24 23:55  /  2139 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

定义自己的异常类  
      很多观点认为在自己的方法抛出异常时,永远都不要抛出一个System.Exception对象!比较好的方式的先从FCL里面找一个合适的异常类,而不是第一时间就想抛出自己定义的异常。FCL定义了大量的异常类,如System.OutOfMemoryException可以让你在发生内存溢出的情况下抛出,System.TimeOutException可以让你面对操作超时的问题时抛出。但FCL定义的异常显然不可能满足你所有的要求,这时候可考虑自定义的异常。自定义的异常必须从System.Exception或者其派生类作为自定义异常类派生,为了实现异常对象在跨越应用程序域时得到封送处理(marshaled),同时还能持久化至日志或数据库,这个异常类必须是可序列化的,所以定义这个类型的时候需要应用特性Serializable(关于特性的使用可阅读《你必须懂的.NET中Attribute》),如新增字段的话还有实现ISerializable接口中的用于序列化的GetObjectData方法。

      下面我们来自定义一个异常类,这个异常类新增一个属性IsLog,用以表识是否将异常写入日志,如IsLog设置为true,则写入日志。因为自定义特性比较繁琐,所以VS里面有定义好的代码段可以供我们使用,我们在代码编写区键入ex的时候VS会提示我们exception的代码段可以选择,我们选择exception,然后单击“Tab”键,VS将自动为我们生成我们自定义异常类的部分关键代码。我们定义好这个异常后将之用在前面代码的DividedBy方法中,当代码判断分母为0的时候,就构建这个异常对象抛出,更高一层的代码捕捉到这个异常,判断异常IsLog属性为true时,将异常信息写入日志,代码如下:

namespace ExceptionDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                double result = Calculation.DividedBy(0, 0);
                Console.WriteLine(result);
               
            }
            catch (MyException ex)
            {
                if (ex.IsLog)
                {
                    Console.WriteLine("将异常信息:{0} 写入日志文件",ex.Message);
                }
            }
            
            Console.ReadKey();
        }

    }
    /// <summary>
    /// 计算类
    /// </summary>
    public static class Calculation
    {
        /// <summary>
        /// 除法
        /// </summary>
        public static double DividedBy(int a, int b)
        {
            double result = 0.0;
            if (b == 0)
            {
                MyException ex = new MyException("除数不能为零",true);
                throw ex;
            }
            result = a / b;
            return result;
        }
    }

    [Serializable]
    public class MyException : Exception,ISerializable
    {
        /// <summary>
        /// 新增字段,用以判断是否将异常写入日志文件
        /// </summary>
        private bool _isLog=false ;
        public bool IsLog
        {
            get { return _isLog; }
        }

        public MyException():base() { }
        //为新增字段实现构造函数
        public MyException(string message, bool isLog)
            : base(message)
        {
            _isLog = isLog;

        }
        //为新增字段实现构造函数
        public MyException(string message, bool isLog, Exception inner) : base(message, inner) { _isLog = isLog; }

        //用于序列化的构造函数,以支持跨应用程序域或远程边界的封送处理
        protected MyException(
          System.Runtime.Serialization.SerializationInfo info,
          System.Runtime.Serialization.StreamingContext context)
            : base(info, context) { }

        //重写基类GetObjectData()方法,实现向SerializationInfo中添加自定义字段信息
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            // 序列化自定义数据成员
            info.AddValue("IsLog",IsLog);
            base.GetObjectData(info,context);
        }
    }
   
}
     输出结果如下:
     将异常信息:除数不能为零 写入日志文件

评分

参与人数 1技术分 +2 收起 理由
宋天琪 + 2

查看全部评分

1 个回复

倒序浏览
值得学习ing!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马