3

让我们举个例子:

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

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

4

8 回答 8

11

不会。只会释放 using 子句中的字段。在你的情况下只有一些对象。

基本上该代码被翻译成

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

  var someOtherObject = new SomeOtherObject();
  someOtherObject.someMethod(); 
}
finally
{
  if (someObject != null )
  someObject.Dispose()
}
于 2010-03-05T10:42:18.697 回答
5

不,SomeOtherObject不会处置。

您的代码由编译器重组如下:

var someObject = new SomeObject();
try
{
    var someOtherObject = new SomeOtherObject();
    someOtherObject.someMethod(); 
}
finally
{
    if (someObject != null)
        someObject.Dispose();
}
于 2010-03-05T10:42:45.573 回答
5

没有 someOtherObject 不会被释放。

您的代码将转换为如下内容:

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

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

于 2010-03-05T10:44:25.260 回答
1

直接引用MSDN

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

因此,只有在 using 语句中声明和实例化的对象才会被释放。对于此类问题,我建议您在发布问题之前进行一些测试。

于 2010-03-05T10:45:23.387 回答
1

someOtherObject将由垃圾收集器正常收集。如果您没有提供调用的适当终结器(析构函数),Dispose()则永远不会调用它。只有在执行流离开块someObject.Dispose()时才会调用。using

于 2010-03-05T10:45:31.043 回答
1

你应该这样写:

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

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

于 2010-03-05T12:14:15.603 回答
0

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

于 2010-03-05T11:09:22.510 回答
0

不确定这是否是您来自的地方;将someOtherObject无法在using街区外访问;因为范围规则

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."

请参阅以获得更多帮助。

于 2010-03-05T12:16:43.507 回答