捕获在Using块的目标对象的构造函数中抛出的异常

Mr.*_*Boy 5 c# exception-handling using-statement

using(SomeClass x = new SomeClass("c:/temp/test.txt"))
{
...
}
Run Code Online (Sandbox Code Playgroud)

在使用块内,一切正常,正常处理异常.但是如果构造函数SomeClass可以抛出异常呢?

Łuk*_*.pl 5

把你的使用放入try catch fe

try
{
   using(SomeClass x = new SomeClass("c:/temp/test.txt"))
   {
       ...
   }
}
catch(Exception ex)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

  • 什么样的答案?我看不到一个. (2认同)

thi*_*eek 4

是的,当构造函数抛出异常时,这将是一个问题。您所能做的就是将 using 块包装在 try/catch 块中。这就是为什么你必须这样做。

using 块只是语法糖,编译器将每个 using 块替换为等效的 try/finally 块。唯一的问题是编译器不会将构造函数包装在 try 块中。编译后的代码将在 IL 中进行以下转换。

        //Declare object x of type SomeClass.
        SomeClass x;

        //Instantiate the object by calling the constructor.
        x = new SomeClass("c:/temp/test.txt");

        try
        {
            //Do some work on x.
        }
        finally
        {
            if(x != null)
                x.Dispose();
        }
Run Code Online (Sandbox Code Playgroud)

从代码中可以看出,如果构造函数抛出异常,则对象 x 将不会被实例化,并且如果不处理,控件将不会从异常引发点进一步移动。

昨晚我刚刚在我的博客上发布了一篇关于这个主题的博文。

我现在想知道为什么 C# 设计者没有将对象构造包装在 try 块中,而根据我的说法,这应该是完成的。

编辑

我想我找到了为什么 C# 不将对象构造包装到生成的 try 块中来代替 using 块的答案。

原因很简单。如果将声明和实例化都包装在 try 块中,the object would be out of scope for the proceeding finally block则代码将无法编译,因为对于 finally 块,对象几乎不存在。如果您仅将构造包装在 try 块中并在 try 块之前保留声明,即使在这种情况下,它也不会编译,因为它找到了you're trying to use an assigned variable.