.NET基础 (07)异常的处理

异常的处理
1 如何针对不同的异常进行捕捉
2 如何使用Conditional特性
3 如何避免类型转换时的异常

 

异常的处理

1 如何针对不同的异常进行捕捉

C#中一个try块可以有多个catch块,每个catch块可以针对特别的异常进行特别的处理。但是安全起见,最后应该添加一个对象Exception类型的异常捕捉的catch块,以保证没有异常被毫无处理地抛出。

实例代码如下:

    class CatchException
    {
        static void Main(string[] args)
        {
            CatchException ce = new CatchException();
            ce.RiskWork();
            Console.Read();
        }

        public void RiskWork()
        {
            try
            {
                /*
                 一些预计可能产生异常的代码
                 */
            }
            catch (NullReferenceException ex)
            {
                HandleExpectedException(ex);
            }
            catch (ArgumentException ex)
            {
                HandleExpectedException(ex);
            }
            catch (FileNotFoundException ex)
            {
                HandleError(ex);
            }
            catch (Exception ex)
            {
                HandleCrash(ex);
            }
        }

        //这里处理预计可能会发生的,不属于错误范畴的异常
        private void HandleExpectedException(Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

         //这里处理在系统出错时可能会发生的,比较严重的异常
        private void HandleError(Exception ex)
        {
            Console.WriteLine(ex.ToString());
            throw ex;   //严重的异常,抛到上层处理
        }

        private void HandleCrash(Exception ex)
        {
            Console.WriteLine(ex.ToString());
            System.Threading.Thread.CurrentThread.Abort();
        }
    }


2 如何使用Conditional特性

Conditional特性用于编写在某个特定编译版本中运行的方法,通常它编写一些在Debug版本中支持测试的方法。当版本不匹配时,编译器会把Conditional特性的方法内容置空。

示例代码:

    //含有两个成员,生日和身份证
    //身份证的第6位到第14位必须是生日
    //身份证必须是18位
    public class People
    {
        private DateTime _birthday;
        private String _id;

        public DateTime Birthday
        {
            set
            {
                _birthday = value;
                if (!Check())
                    throw new ArgumentException();
            }
            get
            {
                Debug();
                return _birthday;
            }
        }
        public String ID
        {
            set
            {
                _id = value;
                if (!Check())
                    throw new ArgumentException();
            }
            get
            {
                Debug();
                return _id;
            }
        }
        public People(String id,DateTime birthday)
        {
            _id = id;
            _birthday = birthday;
            Check();
            Debug();
        }

        //只希望在DEBUG版本中出现
        [Conditional("DEBUG")]
        protected void Debug()
        {
            Console.WriteLine(_birthday.ToString("yyyy-MM-dd"));
            Console.WriteLine(_id);
        }
        //检查是否符合业务逻辑
        //在所有版本中都需要
        protected bool Check()
        {
            if (_id.Length != 18 ||
                _id.Substring(6, 8) != _birthday.ToString("yyyyMMdd"))
                return false;
            return true;
        }
        static void Main(string[] args)
        {
            try
            {
                People p = new People("310101198008010031", 
                    new DateTime(1980, 8, 1));
                p.ID = "310101198709080031";
            }
            catch (ArgumentException ex)
            {
                Console.WriteLine(ex.GetType().ToString());
            }
            finally
            {
                Console.Read();
            }
        }
    }

下面分别是Debug版本和Release版本的输出:

Debug版本:

1980-08-01
310101198008010031
System.ArgumentException

Release版本:

System.ArgumentException


3 如何避免类型转换时的异常

用 is 和 as 语句代替强制类型转换,可以有效避免InvalidCaseException 异常,执行效率相对较高。

示例代码:

    public class UseIsAs
    {
        static void Main(string[] args)
        {
            Base b = new Base();
            Son s = new Son();
            String mystring = "我的类型不匹配";
            DateTime n = DateTime.Now;

            //对三套方法进行验证,结果应该是一样的
            CastToBase1(b);
            CastToBase1(s);
            CastToBase1(mystring);
            CastToBase1(n);
            CastToBase2(b);
            CastToBase2(s);
            CastToBase2(mystring);
            CastToBase2(n);
            CastToBase3(b);
            CastToBase3(s);
            CastToBase3(mystring);
            CastToBase3(n);
            Console.Read();
        }
        //用is进行转换
        static void CastToBase1(Object o)
        {
            if (o is Base)
            {
                Base b = (Base)o;
                Console.WriteLine(b.ToString());
            }
            else
                Console.WriteLine("转换失败");
        }
        //用as进行转换
        static void CastToBase2(Object o)
        {
            Base b = o as Base;
            if(b!=null)
                Console.WriteLine(b.ToString());
            else
                Console.WriteLine("转换失败");
        }
        static void CastToBase3(Object o)
        {
            try
            {
                Base b = (Base)o;
                Console.WriteLine(b.ToString());
            }
            catch
            {
                Console.WriteLine("转换失败");
            }
        }
    }

    /// <summary>
    /// 简单的基类和子类
    /// </summary>
    public class Base
    {
        public override string ToString()
        {
            return "我是基类";
        }
    }
    public class Son : Base
    {
        public override string ToString()
        {
            return "我是子类";
        }
    }

输出结果:

我是基类
我是子类
转换失败
转换失败
我是基类
我是子类
转换失败
转换失败
我是基类
我是子类
转换失败
转换失败

 

转载请注明出处:

作者:JesseLZJ
出处:http://jesselzj.cnblogs.com

posted @ 2015-09-08 21:19  JesseLZJ  阅读(230)  评论(0编辑  收藏  举报