.NET Catch常规异常

更新时间:2024-05-09 下载TXT文档 下载Word文档

.NET编程指南声明我们不应该捕获一般异常。 我假设以下代码不是很好,因为一般异常类型catch:

    private object CreateObject(string classname)
    {
        object obj = null;
        if (!string.IsNullOrEmpty(classname))
        {
           try
           {
              System.Type oType = System.Type.GetTypeFromProgID(customClass);
              obj = System.Activator.CreateInstance(oType);
           }
           catch (Exception ex)
           {
               Log.Error("Unable to create instance for COM Object with class name" + classname +"
" + ex.Message);
           }
        }
        return obj;
    }

在下面的代码中,我捕获特定的异常但不是所有异常,然后我重新抛出异常,以防异常与非泛型异常。 但是,函数"CreateInstance"可能会抛出许多异常(ArgumentNullException,ArgumentException,NotSupportedException,TargetInvocationException,MethodAccessException,MemberAccessException,InvalidComObjectException,MissingMethodException,COMException,TypeLoadException)。

捕获所有其他个别例外是否可以接受? 或者,还有更好的方法?

    private object CreateObject(string classname)
    {
        object obj = null;
        if (!string.IsNullOrEmpty(classname))
        {
           try
           {
              System.Type oType = System.Type.GetTypeFromProgID(customClass);
              obj = System.Activator.CreateInstance(oType);
           }
           catch (NotSupportedException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (TargetInvocationException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (COMException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (TypeLoadException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (InvalidComObjectException ex)
           {
              Log.Error("...." + ex.Message);
           }
           catch (Exception ex)
           {
               Log.Error("Unable to create instance for COM Object with class name" + classname +"
" + ex.Message);
               throw;
           }
        }
        return obj;
    }
  • 重复:stackoverflow.com/questions/204814/

作为一般规则,您不应该捕获异常,除非:

  • 您有一个特定的例外,您可以处理和执行某些操作。但是,在这种情况下,您应该始终检查您是否应该首先考虑并避免例外。

  • 您位于应用程序的顶层(例如UI),并且不希望将默认行为呈现给用户。例如,您可能需要一个带有"请发送给我们您的日志"样式消息的错误对话框。

  • 在以某种方式处理异常后重新抛出异常,例如,如果您回滚数据库事务。

  • 在这个例子中,你为什么要捕捉所有这些不同的类型?在我看来,您的代码可以是:

    try
    {
        System.Type oType = System.Type.GetTypeFromProgID(customClass);
        return System.Activator.CreateInstance(oType);
    }
    catch (Exception ex)
    {
        Log.Error("...." + ex.Message);
    
        //the generic catch is always fine if you then do this:
        throw;
    }

    所以你的问题是规则(3)的一个例子 - 你想记录一个异常,但是然后继续并将其抛出。

    所有不同的类型都在那里,以便在某些情况下你知道你可以处理(即案例1)。例如,假设您知道有一个非托管调用可以解决COMException - 那么您的代码将变为:

    try
    {
        System.Type oType = System.Type.GetTypeFromProgID(customClass);
        return System.Activator.CreateInstance(oType);
    }
    catch (COMException cex)
    {   //deal with special case:
        return LoadUnmanaged();
    }
    catch (Exception ex)
    {
        Log.Error("...." + ex.Message);
    
        //the generic catch is always fine if you then do this:
        throw;
    }
    • 我捕获所有这些不同类型的异常,因为它们可能发生(例如,使用可以传递一个不受支持或未正确注册的类名),在这种情况下,没有一种好的方法可以提前检查异常(因为我可以检查ArgumentNullException)。
    • 我确信它们都可以发生,但除非你要针对那种异常类型做一些特定的事情,否则你最好只抓住一般的Exception然后把它扔掉。
    • 这个答案是完全正确的。关键是你向上抛出一般异常而不是吞下它们。

    在框架的.NET 2+中捕获一般异常是完全可以接受的。

    - 编辑

    你不会这样做的唯一原因是,如果你可以用不同的例外做一些不同的事情。如果你打算一直处理它们,只需抓住一般(或你所追求的特定的,并让其他任何东西上升)。

    • 我同意。有时候我觉得我们认为这不是极端的一般例外。
    • 我不同意。这将使您的应用程序处于异常状态。您应该只处理可以执行某些操作的异常。简单地记录和继续前进是一个坏主意。
    • @ justin.m.chase:这是一个非常奇怪的立场。因此,只要您的应用崩溃,您更愿意让您的用户看到.net常规错误页面而不是您自己的错误页面?
    • 对于未知异常,记录和继续操作是一个坏主意,因为您不知道异常有多糟糕。例如,如果您遇到OutOfMemoryException会发生什么?您不应该记录该错误并继续前进。该程序应该停止运行。最好是"快速失败"而不是试图保持不稳定的程序运行。 martinfowler.com/ieeeSoftware/failFast.pdf
    • @Phil:你不明白我的回答。我建议你将来要多加小心。
    • 我得到的印象是你说它可以捕获一般的System.Exception,处理它,并继续执行。正确?
    • @Phil:不,不对。他想知道是否有某些特定原因不能捕捉到一般例外情况。我说,如果你能用它做点什么就好了。也就是说,记录,或优雅退出,或任何你认为合适的。我不是说你抓住异常并忽略它们,让你的应用程序继续向前,好像没有出错。捕获太多特定异常是错误的。捕获一些特定的异常显然是正确的(例如,FileNotFound,无论你能想象到什么)。
    • @Noon我同意这一点。但是"如果你打算一直处理它们,只需捕获一般"可以由一个没有经验的程序员解释它可以捕获一般的System.Exception,做某事,然后继续执行。如果你不知道你正在处理什么类型的错误,那么最好指定一下,你最好重新抛出它或退出。

    我同意基思的回答。 两个代码示例的真正问题是它们可以返回null。 您有一个名为CreateObject的方法,它返回一个object类型的实例。 该方法由于某种原因失败,例如COMException。 然后,两个代码示例都将返回null。 调用代码现在负责检查结果与null,否则将抛出NullReferenceException。

    引用框架设计指南第2版: 短码网=DuanMa.NET

    If a member cannot successfully do
    what it is designed to do, it should
    be considered an execution failure,
    and an exception should be thrown.

    它的名字没有表现出来。 扔!

    基思的代码很好; 记录异常并重新抛出是可以的。

    这是一种私有方法,因此可以说设计指南不适用。 我仍然会在这里应用它们 - 当你可以使用异常处理时,为什么要用"if(result == null)"来丢弃你的代码?

    • 有时会有一个尝试创建对象的方法,但如果不能则返回null;然而,给这个方法起一个名称来表明它会做什么通常是一个好主意。 Microsoft更喜欢让这样的例程返回一个成功/失败的布尔值,并将byref参数作为一个对象引用变量来存储新对象,但我更喜欢返回值或null,因为它允许在语句中定义一个新变量试图创建实例。
    • @supercat:如果我们可以信任其他开发人员(和我们自己)总是检查返回的值是否为null,那就没关系...
    • 如果调用一个名为TryGetFoo的函数而不考虑它可能会失败,那么它们应该得到它们得到的东西。他们甚至可以更容易地忽略MS模式"TryGetFoo"方法的返回值(成功/失败标志)。 MS模式版本在某些情况下确实有一个功能,可能是好事还是坏事:它可能会使函数抛出异常,但仍然会在传递变量之前将其设置为某个东西。如果变量是IDisposable,这可能会很好,但如果忽略create方法的返回代码,可能会引起混淆。

    在处理错误时习惯性地捕获基数Exception被认为是不好的做法,因为它表明可能缺乏对实际处理内容的理解。当你看到一个代码块时,它会读取Exception它所读取的内容,"如果这里出现任何问题,请执行此操作",其中任何内容都可以从NullReferenceExceptionOutOfMemoryException

    处理所有错误的危险相同,这意味着您并不关心错误的严重程度或解决错误的方式。 99%的情况下,当我看到代码catch(Exception ex)时,紧接着是吞下异常的代码,并没有提供实际上为什么语句失败的线索。啊。

    您的错误日志记录示例显示了使用base Exception的正确方法,在您真正希望将所有异常处理相同的情况下,通常在应用程序的顶层,以防止应用程序在丑陋的混乱中终止。

    没有一个严格的规则,我们不应该使用一般的例外,但指南说,只要我们有一个选项来处理特定类型的异常,我们就不应该使用一般异常。

    如果我们确定所有异常都将以相同的方式处理,那么使用泛型异常,否则将针对每个特定异常,并且泛型应该最后用于某个未知异常。

    有时在你的应用程序中发生任何由于特定的异常处理而未在代码中处理的异常,那么你的应用程序可能会崩溃。

    因此,更好的方法是处理所有特定的异常,然后为一般异常提供一个角落,以便应用程序保持稳定而不会崩溃。

    并且可以在某处报告或记录那些不需要的通用异常,以便将来版本改进应用程序。

    如果你想用不同类型的异常做一些特殊的事情,那么在一个单独的catch块中捕获它。否则单独记录它们是没有意义的。

    我认为可以捕获所有异常以拦截问题并向用户显示友好消息而不是一些可怕的堆栈输出。

    只要您不只是吞下异常,而是记录它们并在后台适当地对它们作出反应。

    以上就是短码网小编为大家整理的《.NET Catch常规异常》相关内容,希望大家喜欢。

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

    如若内容造成侵权/违法违规/事实不符,请将联系本站反馈,一经查实,立即处理!

    .NET Catch常规异常》文档下载仅供参考学习,下载后请在24小时内删除。

    转载注明出处:https://www.duanma.net/article/ed7617e9222.html

    回到顶部