C#-尝试/捕获/最后并使用正确的顺序

时间:2018-08-24 16:15:02

标签: c# resources try-catch dispose using

我知道这个问题已经问了好几次了,但我仍然不知道应该如何正确排序。

如果要在对象创建过程中捕获异常,则必须将try和catch置于using语句之外:

try { using... } catch (Exception e) { }

如果要在创建对象后捕获异常,则:

using(...) { try {...} catch (Exception e) {} }

但是,如果您想在对象创建期间和之后都捕获该怎么办?会是:

try { using(...) { try {...} catch (Exception e) {} } } catch (Exception e) { }

还是仅使用try,catch,最后使用dispose会更好?

4 个答案:

答案 0 :(得分:5)

using block与出售有关的不仅仅是创作。如文档中所述,这是此代码的快捷方式:

{
    Font font1 = new Font("Arial", 10.0f);
    try
    {
        byte charset = font1.GdiCharSet;
    }
    finally
    {
        if (font1 != null)
            ((IDisposable)font1).Dispose();
    }
}

这是try-catch block

的定义
  

try块包含可能导致异常的受保护代码。   该块一直执行到引发异常或完成异常为止   成功。

因此,从那里开始,策略取决于您。这段代码:

try
{
    using(Font font1 = new Font("Arial", 10.0f))
    {
        byte charset = font1.GdiCharSet;
    }
}

将被翻译为:

try
{
    Font font1 = new Font("Arial", 10.0f);
    try
    {
        byte charset = font1.GdiCharSet;
    }
    finally
    {
        if (font1 != null)
            ((IDisposable)font1).Dispose();
   }
}

如您所见,您正在捕获由构造函数,块以及Dispose引起的异常。

鉴于此:

using(Font font1 = new Font("Arial", 10.0f))
{
    try
    {
        byte charset = font1.GdiCharSet;
    }
}

将被翻译为:

Font font1 = new Font("Arial", 10.0f);
try
{
    try //This is your try
    {
      byte charset = font1.GdiCharSet;
    }
}
finally
{
    if (font1 != null)
        ((IDisposable)font1).Dispose();
}

所以在这里,您将捕获构造函数和Dispose都不会引起的异常。

答案 1 :(得分:2)

在try块的上下文中引发的任何异常将由相应的catch块处理。在这种情况下,您可以使用一个try块,该块可以捕获来自多个源的异常并根据需要处理它们。考虑下面的代码...

try
{
    using(var con = DataService.GetSomethingDisposable()) // Possible InvalidOperationException();
    {
        // Do what you need here
        // Possible Exception here
    }
}
catch(InvalidOperationException ex)
{
    // Handle as you will
}
catch(Exception ex) // Catch any other exception
{
    // Handle as you will
}

因此,您可以捕获并响应同一try ... catch块引起的任何异常。

答案 2 :(得分:0)

MSDN参考https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement

  

当IDisposable对象的生存期限制为单个时   方法,您应该在using语句中声明并实例化它。   using语句在对象中的对象上调用Dispose方法。   正确的方式,并且(当您如前所述使用时)也会导致   调用Dispose时,对象本身将超出范围。中   using块,该对象是只读的,无法修改,或者   重新分配。

答案 3 :(得分:0)

选项1会同时遇到两种情况:

try { using() } catch (Exception) {}

如果您创建一个在初始化时引发异常的新对象,则该异常将捕获在您的catch块中。 同样,如果您的using块中的某些东西引发异常,则该异常也会被捕获在catch块中。

异常将始终冒泡到捕获该类型异常的第一个catch块。如果没有什么可以捕获的异常,它可能会一直冒泡并终止您的应用程序