捕获异常.是否替换或包装using语句

本文关键字:using 语句 包装 是否 替换 捕获异常 | 更新日期: 2023-09-27 18:14:59

using语句不捕获异常。要捕获异常,您有两种选择:

1)打开使用并手动实现:

void MyFunc()
{
    StreamReader myReader = null;
    try
    {
        myReader = new StreamReader(path);
        //use myReader
    }
    catch (Exception e)
    {
        //do something with exception
    }
    finally
    {
        if (myReader != null)
            myReader.Dispose();
    }
}

或2)保持使用,并将其包装在另一个try catch块

void MyFunc()
{
    try
    {
        using (StreamReader myReader = new StreamReader(path))
        {
             //use myReader
        }
    }
    catch (Exception e)
    {
        //do something with exception
    }
}

对我来说,第二个看起来更整洁,特别是当您有多个using语句时,因为它更好地描述了流,并删除了显式声明、null检查和Dispose()调用。

但是,由于额外的try catch开销,这感觉是错误的。

标准做法是什么?

捕获异常.是否替换或包装using语句

异常处理构造的开销只是元数据。如果没有抛出异常,则不会产生运行时性能开销。与其他运行时不同,在。net中进入/离开异常处理子句是免费的。当抛出异常时,运行库使用元数据和当前指令指针来确定执行哪个处理子句。

我喜欢第二个。释放资源和处理异常是两个独立的概念,所以它们在代码中是分开的。

您应该尽量避免在方法中使用"try - catch",除非有非常具体的要求。例如,在应用程序启动之前检查数据库连接。

异常处理成为。net应用程序中非常昂贵的事情。

然而,如果你必须这样做,那么显示的第二个选项更好。同样,对于异常处理的要求来说,这也是主观的。

如果它是用于一般的错误处理(如记录或发送错误邮件),那么使用Global.asax。或者至少将其限制为Page_Error事件

另一个需要注意的模式——在创建一个对象将获得另一个对象的所有权的情况下特别有用(我通常编写vb.net代码,因此请原谅任何c#错误)

<>之前类MyDisposableClass{SomeDisposableThing神话;MyDisposableClass()//构造函数{Bool = false;试一试{myThing = new SomeDisposableThing();…做一些其他的事情Ok = true;}最后{如果(!好){zap (ref神话);}}}静态void zap(ref T thing) where T:IDisposable,class{T oldValue = System.Threading.Interlocked。交换(东西,空);if (oldValue != null)oldValue.Dispose ();}}之前

请注意,虽然可以捕获并重新抛出构造函数期间发生的任何异常,但如果永远不会对异常做任何事情,除了在不更改的情况下重新抛出它,那么最好不要捕获异常,而不是捕获并重新抛出。