LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C#异常处理throw、throw ex、throw new Exception 区别

admin
2024年10月22日 12:59 本文热度 41

前言

异常是在程序执行过程中发生的意外情况,例如除以零、访问 null 对象或遇到 file not found 错误。C#提供使用try、catch和finally块处理的可靠机制。异常处理有助于处理在程序运行期间发生的任何意外或异常情况,异常是使用 throw 关键字创建而成。

正确管理异常是开发健壮的应用程序的一个关键方面。管理好异常的好坏意味着平稳运行的应用程序与故障排除的噩梦之间的区别。

在C#中引发异常的三种常见方法是throw、throw ex 和 throw new Exception(ex),尽管它们看起来很相似,但它们都有不同的行为和实例。本文探讨它们的差异,并以示例介绍每种方法使用。

基础知识

1、throw 语句

throw 语句用于指示异常的发生。用于显式地引发异常或重新引发捕获的异常。使用 throw 语句重新引发异常时,它会保留原始异常的堆栈跟踪,这对于调试至关重要。

下面示例:throw 语句会重新引发捕获的异常,同时保留原始堆栈跟踪。

try{    //文件不存在    string content= File.ReadAllText(string.Format("{0}{1}log.txt",AppDomain.CurrentDomain.BaseDirectory,Path.DirectorySeparatorChar),Encoding.UTF8);}catch (Exception ex){    Console.WriteLine(ex.Message);    throw;}

2、throw ex 语句

throw ex 语句是重新引发异常的另一种方法。但是,与 throw 不同的是,throw ex 会重置堆栈跟踪信息。这意味着新的堆栈跟踪从调用 throw ex 的点开始,丢失发生异常的原始上下文。

下面示例:throw ex 会重新引发捕获的异常,但堆栈跟踪将从 catch 块开始,这可能会掩盖异常的根本原因。

try

{    int firstnum = 1;    int secondnum = 0;    Console.WriteLine(firstnum / secondnum);}catch (Exception ex){    Console.WriteLine(ex.Message);    throw ex;}

3、throw new Exception 语句

throw new Exception() 是将原始异常包装在新异常中,提供额外的上下文,同时仍包含原始异常。

下面示例:将使用自定义消息创建新异常,并将原始异常作为内部异常传递。这提供了额外的上下文,同时保留原异常的详细信息。

try{    // log.txt 文件不存在    string content= File.ReadAllText(string.Format("{0}{1}log.txt",AppDomain.CurrentDomain.BaseDirectory,Path.DirectorySeparatorChar),Encoding.UTF8);}catch (Exception ex){    Console.WriteLine(ex.Message);    throw new Exception("【log.txt】文件不存", ex);}

三者区别

1、堆栈跟踪

throw:保留原始堆栈跟踪,提供有关异常来源的完整信息。

throw ex:重置堆栈跟踪,这可能会使调试异常的根本原因发生改变。

throw new Exception:为新的异常消息提供其他上下文,同时将原始异常保留为内部异常。

2、应用场景

throw:需维护原始异常上下文和堆栈跟踪时,使用该方法。

throw ex:该方法谨慎,如需使用,应在重新引发异常之前向异常添加其他信息。

throw new Exception:如果需要往异常添加更多上下文,同时保留原始异常详细信息,使用该方式。

示例

1、使用 throw

using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace Fountain.WinConsole.ExceptionDemo{    public class UserBiz    {        /// <summary>        /// 登录        /// </summary>        public void Login()        {            try            {                UserDiz userDiz = new UserDiz();                userDiz.GetUserData();            }            catch (Exception ex)            {                throw;            }        }    }
   public class UserDiz    {        /// <summary>        /// 获取用户数据        /// </summary>        public void GetUserData()        {            try            {                throw new InvalidOperationException("用户或密码不正确!");            }            catch (Exception ex)            {                throw;            }        }    }}
说明:

堆栈跟踪将指向 GetUserData 中异常的原始来源,从而更容易调试。

效果:

2、使用 throw ex

using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace Fountain.WinConsole.ExceptionDemo{    public class UserBiz    {        /// <summary>        /// 登录        /// </summary>        public void Login()        {            try            {                UserDiz userDiz = new UserDiz();                userDiz.GetUserData();            }            catch (Exception ex)            {                throw ex;            }        }    }
   public class UserDiz    {        /// <summary>        /// 获取用户数据        /// </summary>        public void GetUserData()        {            try            {                throw new InvalidOperationException("用户或密码不正确!");            }            catch (Exception ex)            {                throw ex;            }        }    }}
说明:

堆栈跟踪将仅显示重新抛出点(Login),而不显示异常的原始来源(GetUserData),从而更难确定错误最初发生的位置。

效果:

3、使用 throw new Exception


using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace Fountain.WinConsole.ExceptionDemo{    public class UserBiz    {        /// <summary>        /// 登录        /// </summary>        public void Login()        {            try            {                UserDiz userDiz = new UserDiz();                userDiz.GetUserData();            }            catch (Exception ex)            {                throw new Exception("用户登录异常", ex);            }        }    }
   public class UserDiz    {        /// <summary>        /// 获取用户数据        /// </summary>        public void GetUserData()        {            try            {                throw new InvalidOperationException("用户或密码不正确!");            }            catch (Exception ex)            {                throw new Exception("获取用户数据异常", ex);            }        }    }}
说明:

新异常提供了额外的上下文,例如发生错误的方法名称,同时仍保留原始异常详细信息。

效果:

示例调用代码
using System;
namespace Fountain.WinConsole.ExceptionDemo{    class Program    {        static void Main(string[] args)        {            try            {                UserBiz userBiz = new UserBiz();                userBiz.Login();            }            catch(Exception ex)            {                if (ex.InnerException != null)                {                    Console.WriteLine(string.Format("{0}{1}{2}", ex.InnerException.Message, Environment.NewLine, ex.InnerException.StackTrace));                    Console.WriteLine(string.Format("{0}{1}{2}", ex.Message, Environment.NewLine, ex.StackTrace));                }                else                {                    Console.WriteLine(string.Format("{0}{1}{2}", ex.Message, Environment.NewLine, ex.StackTrace));                }            }            Console.ReadKey();        }    }}

小结

处理异常时,在throw、throw ex和throw new Exception 三者间进行选择,对于有效处理异常和调试非常重要。从上面了解,throw 语句通常是首选,throw ex 需谨慎使用,对于throw new Exception则可用于复杂应用。


该文章在 2024/10/22 15:16:52 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved