捕获使用块的目标对象的构造函数中抛出的异常 [英] Catching exceptions thrown in the constructor of the target object of a Using block

查看:126
本文介绍了捕获使用块的目标对象的构造函数中抛出的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  using(SomeClass x = new SomeClass(c:/temp/test.txt))
{
...
}

在使用块内,一切正常处理异常都是正常的。但是如果 SomeClass 的构造函数可以引发异常怎么办?

解决方案

,当构造函数引发异常时,这将是一个问题。 所有你可以做的是将try块包装在try / catch块中。这就是为什么你必须这样做。



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

  //声明类型为SomeClass的对象x。 
SomeClass x;

//通过调用构造函数实例化对象。
x = new SomeClass(c:/temp/test.txt);

try
{
//在x上做一些工作。
}
finally
{
if(x!= null)
x.Dispose();
}

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



我刚刚发布了一个 blog-发表在我的博客上关于这个问题昨晚。


我刚刚想知道为什么C#
设计师没有包装对象
在try块
中构建根据我应该已经
完成。




< h2> EDIT

我想我发现了为什么C#不会将对象构造包装到try块生成代替使用块的答案。 / p>

原因很简单。如果您在try块中包含声明和实例化,那么该对象将超出范围,用于进程finally块,并且代码将无法编译,因为最后阻止对象很少存在。如果只将try构造包装在try块中,并在try块之前保持声明,即使在这种情况下也不会编译,因为它找到,你试图使用一个赋值变量


using(SomeClass x = new SomeClass("c:/temp/test.txt"))
{
...
}

Inside the using block, all is fine with treating exceptions as normal. But what if the constructor of SomeClass can throw an exception?

解决方案

Yes, this will be a problem when the constructor throws an exception. All you can do is wrap the using block within a try/catch block. Here's why you must do it that way.

using blocks are just syntactic sugar and compiler replaces each using block with equivalent try/finall block. The only issue is that the compiler does not wrap the constructor within the try block. Your code after compilation would have following conversion in the 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();
        }

As you can see from the code, the object x will not be instantiated in case when the constructor throws an exception and the control will not move further from the point of exception raise if not handled.

I have just posted a blog-post on my blog on this subject last night.

I'm just now wondering why C# designers did not wrap object construction within the try block which according to me should have been done.

EDIT

I think I found the answer why C# does not wrap object construction into try block generated in place of the using block.

The reason is simple. If you wrap both declaration and instantiation within the try block then the object would be out of scope for the proceeding finally block and the code will not compile at because, for finally block the object hardly exists. If you only wrap the construction in the try block and keep declaration before the try block, even in that case the it will not compile since it finds you're trying to use an assigned variable.

这篇关于捕获使用块的目标对象的构造函数中抛出的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆