• c# 闲谈异常处理


    今天在阅读 .net 源码时发现微软对所有使用枚举类型的地方对枚举值进行了检测,在检测不通过时抛出了异常。

        if (!System.Windows.Forms.ClientUtils.IsEnumValid(value, (int) value, 0, 4))
                    {
                        throw new InvalidEnumArgumentException("value", (int) value, typeof(PictureBoxSizeMode));
                    }

    下面的demo展示了枚举类型的正确使用方法,异常的原因和抛出枚举异常的方法:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            enum Days { Sun, Mon, tue, Wed, thu, Fri, Sat };
            static void Main(string[] args)
            {
                try
                {
                    ConsoleDay(Days.Fri);   //正确的使用枚举
                    ConsoleDay((Days)2);
                    ConsoleDay((Days)8);    //枚举异常的来源
                }
                catch (Exception err)
                {
                    Console.WriteLine(err.Message);
                }
                Console.ReadLine();
            }
            static void ConsoleDay(Days day)
            {
                int dayInt = (int)day;
                if (dayInt < 0 || dayInt > 6)//检测枚举
                {
                    throw new InvalidEnumArgumentException("day", dayInt, typeof(Days));//抛出枚举异常
                }
                Console.WriteLine(day);
            }
        }
    }

     关于异常,除了在各个接口中使用 try catch finally 来处理外,还可以对整个程序的异常统一处理。

    以 winform 为例,可以修改 program.cs 文件:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace PrintTest
    {
        static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false); 
                Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);   //处理 UI 线程的异常
                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); //处理非 UI 线程的异常
                Application.Run(new Form1());
            }
    
            static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
            {
                MessageBox.Show(e.Exception.Message);
            }
            private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
            {
                Console.WriteLine(e.ExceptionObject.ToString());
                MessageBox.Show(e.ExceptionObject.ToString());
            }
        }
    }

     我们可以依赖 .net 来生成异常,也可以自己 new 一个异常,这样可以定制异常的 message:

     class Program
        {static void Main(string[] args)
            {
                try
                {
                    ConsoleDivision(4, 2);
                    ConsoleDivision(4, 0);
                }
                catch (Exception err)
                {
                  Console.WriteLine(err.Message);
                }
                Console.ReadLine();
            }
    
            static void ConsoleDivision(int num1, int num2)
            {
                //if (num2 == 0)
                //{
                //    throw new DivideByZeroException("num2不能是零");
                //}
                Console.WriteLine(num1 / num2);
            }
        }

     当程序的结构较深时需要嵌套异常,使用 new Exception() 的重载,方便定位:

        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    DoSomeThing();
                }
                catch (Exception err)
                {
                    string innerMsg = err.InnerException == null ? "" : " innerExceptionMessage:" + err.InnerException.Message;
                    Console.WriteLine(err.Message + innerMsg);
                }
                Console.ReadLine();
            }
    
            static void DoSomeThing()
            {
                try
                {
                    ConsoleDivision(4, 0);
                }
                catch (Exception err)
                {
                    throw new Exception("DoSomeThing异常", err);
                }
            }
    
            static void ConsoleDivision(int num1, int num2)
            {
                if (num2 == 0)
                {
                    throw new DivideByZeroException("num2不能是零啊");
                }
                Console.WriteLine(num1 / num2);
            }
        }

     当需要区分异常时可以使用多个 catch (注意将catch(Exception err)放在最后面,因为 Exception 是所有异常的基类,必然捕获),可以自定义各种类型的异常。

    namespace ConsoleApplication1
    {
        class MyException : Exception
        {
            public MyException()
                : base()
            {
            }
    
            public MyException(string str)
                : base(str)
            {
            }
    
            public MyException(string str, Exception inner)
                : base(str, inner)
            {
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    throw new MyException("");
                    //throw new DivideByZeroException();
                }
                catch (MyException err)
                {
                    Console.WriteLine("MyException捕获" + err.Message);
                }
                catch (Exception err)
                {
                    Console.WriteLine("Exception捕获" + err.Message);
                }
    
                Console.ReadLine();
            }
        }
    }
  • 相关阅读:
    ArcGIS超级工具SPTOOLS-制图篇
    ArcGIS超级工具SPTOOLS-MXD操作篇
    ArcGIS超级工具SPTOOLS-影像的批量裁剪和批量合并
    Get Raster Properties获得栅格的信息
    ArcGIS超级工具SPTOOLS-按属性裁剪,矢量数据批量裁剪,矢量数据批量合库
    ArcGIS超级工具SPTOOLS-SHP转数据库,批量数据库转数据库,栅格彩色转黑白
    ArcGIS超级工具SPTOOLS-锐角检查,获得内角并判断是否凸多边形,获得线(面)两个折点方向
    ArcGIS超级工具SPTOOLS-线封闭,点集转面
    ArcGIS超级工具-征地部标准坐标导出导入 SPTOOLS
    arcgis的arcpy写入几何怎么创建一个空心面要素并读取几何和属性信息,根本不够管
  • 原文地址:https://www.cnblogs.com/aitong/p/10536411.html
Copyright © 2020-2023  润新知