C# 使用语句和IDisposable接口

C# 使用语句和IDisposable接口,c#,vb.net,C#,Vb.net,using语句中声明的变量是一起处理的,因为它们在using块的范围内,这是真的吗 我是否需要做: using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation()) { using(SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2()) { } } 或者这就足够了,“bar”和“fo

using语句中声明的变量是一起处理的,因为它们在using块的范围内,这是真的吗

我是否需要做:

using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation())
{
    using(SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2())
    {

    }
}
或者这就足够了,“bar”和“foo”一起处理吗

或者这就足够了,“bar”和“foo”一起处理吗

不,酒吧不会被处理

使用
语句将转换为
try finally
块,因此即使出现异常,
finally
块也确保调用
Dispose
方法

跟随

using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation())
{
    SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2();
}
转化为

{
    SomeIdisposableImplementation foo;
    try
    {
        foo = new SomeIdisposableImplementation();
        SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2();
    }
    finally
    {
        if (foo != null)
            foo.Dispose();
    }
}

使
未处理

第二个版本栏中的将超出范围,但不会被处理。但您可以使用以下命令将foo和bar放在同一个位置:

using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation(), SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2())
{
    // use foo and bar
}
SomeIdisposableImplementation foo = new SomeIdisposableImplementation();
SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2();
using (foo, bar)
{
    // use foo and bar
}
您也可以将变量放入using命令中:

using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation(), SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2())
{
    // use foo and bar
}
SomeIdisposableImplementation foo = new SomeIdisposableImplementation();
SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2();
using (foo, bar)
{
    // use foo and bar
}

要使用using语句处理它们,您不必嵌套它们,但是您可以编写以下代码

using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation())
{
    using(SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2())
    {

    }
}
作为


您是否错过了
=
中的
?此答案的第一句是正确的。其余的是错误的。你编辑的第二个选项罗兰是错误的。如果
bar=new-someidisposableimplementation 2()
抛出异常,或者在使用
block
foo
(和
bar
)进入
之前发生线程异常,将永远不会被处理。正确的语法是
using(S1-foo=new-S1())using(S2-bar=new-S2()){…
,或者,如果
foo
bar
是同一类型,
使用(S1 foo=new S1(),bar=new S1()){…}
。如果
使用(S1 foo=new S1();S2 bar=new S2()){…}
是合法的,那就太好了,但事实并非如此。@ChrisSinclair:
使用
在线程中止异常面前根本不可靠。考虑:
s1foo=null;尝试{foo=news1();…}最后{if(foo!=null)foo.Dispose();}
。现在假设线程中止异常在
S1
的构造函数中抛出,但在构造函数创建非托管资源之后抛出
foo
将永远不会被分配,因此它在
finally
中仍然为空。在这里释放资源的唯一方法是在终结器中。这就是为什么在面对部分构造的对象时,您需要始终编写健壮的终结器。@ChrisSinclair:对,我的观点是,尽管注意到这里显示的代码在线程中止异常时不健壮是正确的,但这本身并不是使用
using
语句的动机,因为
using
语句也不能抵抗线程中止。一般来说,我真的很少关心在异常场景中清理资源,因为它是异常的。你无法在所有异常情况下清理资源,根据定义,它们是异常的;相反,要担心的是,在典型情况下,总是要清理干净。