我们举个例子:
using (var someObject = new SomeObject())
{
var someOtherObject = new SomeOtherObject();
someOtherObject.someMethod();
}
SomeOtherObject
也实现了IDisposable。
当SomeObject被处置时,SomeOtherObject也会被处理掉吗? SomeOtherObject会发生什么?
(处理SomeOtherObject未在SomeObject的Dispose方法中实现)
答案 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."