使用“using”关键字时会被处置的内容

时间:2010-03-05 10:41:09

标签: c# .net using

我们举个例子:

using (var someObject = new SomeObject())
{
    var someOtherObject = new SomeOtherObject();
    someOtherObject.someMethod(); 
}

SomeOtherObject也实现了IDisposable。 当SomeObject被处置时,SomeOtherObject也会被处理掉吗? SomeOtherObject会发生什么? (处理SomeOtherObject未在SomeObject的Dispose方法中实现)

8 个答案:

答案 0 :(得分:11)

没有。只会处理using子句中的字段。在你的情况下只有someObject。

基本上代码被翻译成

var someObject = null;
try
{
  someObject = new SomeObject()

  var someOtherObject = new SomeOtherObject();
  someOtherObject.someMethod(); 
}
finally
{
  if (someObject != null )
  someObject.Dispose()
}

答案 1 :(得分:5)

不,SomeOtherObject处置。

您的代码由编译器重构,如下所示:

var someObject = new SomeObject();
try
{
    var someOtherObject = new SomeOtherObject();
    someOtherObject.someMethod(); 
}
finally
{
    if (someObject != null)
        someObject.Dispose();
}

答案 2 :(得分:5)

不会丢弃someOtherObject。

您的代码会以这样的方式进行翻译:

var someObject = new SomeObject();
try
{
   var someOtherObject = new SomeOtherObject();
   someOtherObject.someMethod(); 
}
finally
{
    ((IDisposable)someObject).Dispose();
}

因此,不会对任何新创建的对象进行额外调用。

答案 3 :(得分:1)

直接引自MSDN

  

通常,当您使用IDisposable对象时,您应该在using语句中声明并实例化它。 using语句以正确的方式调用对象上的Dispose方法,并且(如前所示使用它时)一旦调用Dispose,它也会导致对象本身超出范围。在using块中,该对象是只读的,不能修改或重新分配。

因此,只会处理在using语句中声明和实例化的对象。对于这类问题,我建议你在发布问题之前做一些测试。

答案 4 :(得分:1)

垃圾收集器通常会收集

someOtherObject。如果您没有提供调用Dispose()的适当终结器(析构函数),则永远不会调用它。当执行流程离开someObject.Dispose()块时,将仅调用using

答案 5 :(得分:1)

你应该这样写:

using (var someObject = new SomeObject()) {
    using (var someOtherObject = new SomeOtherObject()) {
        someOtherObject.someMethod(); 
    }
}

如果您的方法创建了许多一次性对象,这在绘画代码中很常见,这可能会失控。重构为辅助方法或切换到显式finally块。

答案 6 :(得分:0)

当控件离开Dispose块时,将调用someObject引用的using对象方法。你可以在Dispose方法中SuppressFinalize,在这种情况下,系统不会调用该对象的finalizer(否则它会)。
但是,someOtherObject引用的对象将在适当的时候由GC收集,因为当控件离开块时,任何对象都不会引用它,并且会标记为要收集。

答案 7 :(得分:0)

不确定这是否是你来自哪里; someOtherObject块之外无法访问using;因为scoping rules

using (Stream stream = File.OpenRead(@"c:\test.txt"))
{
   var v1 = "Hello"; //object declared here, wont be accessible outside the block
   stream.Write(ASCIIEncoding.ASCII.GetBytes("This is a test"), 0, 1024);
} //end of scope of stream object; as well as end of scope of v1 object.

v1 = "World!"; //Error, the object is out of scope!

编译器错误:“当前上下文中不存在名称v1。”

即便跟随也会引发错误。

    {
        int x=10;
    }

    x = 20; //Compiler error: "The name x does not exist in the current context."

请参阅thisthis以获取更多帮助。