2009-07-07 21 views
4

如果ExecuteReader引发异常,我如何确定在IDataReader处置的以下代码片段中?如果using语句引发异常,我该如何处理一个IDisposable对象?

using (IDataReader rdr = cmd.ExecuteReader()) 
{ 
    // use it 
} 

这对我来说很有意义的using语法糖不调用Dispose(因为没有实例,调用它)。但是,我怎样才能确定通常由实现IDisposable的类分配的稀有资源将会被释放?

+5

如果ExecuteReader引发异常,则IDataReader为null并且不需要配置。 ExecuteReader中的非托管资源需要清理,并且应该在自己的finally块中处理。 – cjk 2009-07-07 08:43:22

回答

14

如果ExecuteReader在你的例子中引发了一个异常,它永远不会返回任何东西。然后由ExecuteReader的实现来处理在异常之前创建的任何东西。

-2

我认为using语句被翻译到类似于IL:

try 
{ 
} 
finally 
{ 
    disposableUsedObject.Dispose(); 
} 

所以,我认为,在正常情况下,处置应该叫什么名字?

另外,您不应该在构造函数内抛出异常,因为用户不会期望在实例化对象时抛出异常。 我会将可以抛出异常的初始化逻辑移动到实例化对象后必须调用的另一个方法(Initialize)。

+1

但是,如果构造函数抛出异常,没有对象来处理? – cjk 2009-07-07 08:42:05

+0

@ck完全是我的问题 – jpoh 2009-07-07 08:43:02

+0

您不应该在构造函数中抛出异常,因为这有点意外。你的类的用户不希望在实例化一个对象时可以在构造函数中抛出异常。 :) 我认为最好移动该初始化逻辑(可以显示另一个方法的异常(初始化,或类似的东西) – 2009-07-07 08:47:10

3

如果对象的构造函数无法运行,那么您没有需要处理的对象。

如果您正在编写可能会引发异常的构造函数,最好通过使用using或try-catch块来确保清理所需的任何内容。

在您的IDataReader示例中,如果cmd.ExecuteReader()方法调用失败,只需处理命令对象就足够了。

0

如何将在构造函数外执行初始化的代码移动到单独的函数中。实质上,您将拥有

using (var tc = new TestClass()) 
{ 
    tc.Initialize(); // setup the object. acquire expensive resources here, etc. 

    ..more code .. 
} 
相关问题