“使用”时会处置什么?使用了关键字

发布于 2024-08-24 04:00:01 字数 342 浏览 8 评论 0原文

让我们举个例子:

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

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

Let's have an example:

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

SomeOtherObject also implements IDisposable.
Will be SomeOtherObject also disposed when SomeObject get disposed ? What will happen to the SomeOtherObject ?
(disposing of SomeOtherObject is not implemented in the Dispose method of SomeObject)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

十二 2024-08-31 04:00:01

不会。只有 using 子句中的字段才会被处理。在你的情况下只有 someObject.

基本上该代码被翻译成

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

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

No. Only fields in the using clause will be disposed. In your case only someObject.

Basically that code gets translated into

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

  var someOtherObject = new SomeOtherObject();
  someOtherObject.someMethod(); 
}
finally
{
  if (someObject != null )
  someObject.Dispose()
}
合久必婚 2024-08-31 04:00:01

不,SomeOtherObject不会被处置。

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

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

No, SomeOtherObject will not be Disposed.

Your code is restructured by the compiler as follows:

var someObject = new SomeObject();
try
{
    var someOtherObject = new SomeOtherObject();
    someOtherObject.someMethod(); 
}
finally
{
    if (someObject != null)
        someObject.Dispose();
}
伴梦长久 2024-08-31 04:00:01

没有 someOtherObject 不会被释放。

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

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

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

No someOtherObject will not disposed.

Your code would traslates in something like this:

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

So, there are no additional calls to any newly created object would performed.

唐婉 2024-08-31 04:00:01

直接引用 MSDN

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

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

quote from MSDN directly:

As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned.

Thus only the object declared and instantiated in the using statement will be disposed. For this kind of problem I would suggest you to do some test before post the question.

温馨耳语 2024-08-31 04:00:01

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

someOtherObject will be collected normally by the Garbage Collector. If you did not provide an appropriate finalizer (destructor) that calls Dispose(), this will never get called. Only someObject.Dispose() will be called when execution flow leaves the using block.

ペ泪落弦音 2024-08-31 04:00:01

你应该这样写:

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

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

You should write it like this:

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

This can get out of hand if your method is creating a lot of disposable objects, common in painting code. Refactor into a helper method or switch to an explicit finally block.

梦回旧景 2024-08-31 04:00:01

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

The Dispose method of object that is referenced by someObject will be called when control leaves the using block. You can SuppressFinalize in Dispose method in which case system will not call that object's finalizer (otherwise it will).
The object that referenced by someOtherObject will, however, be collected by GC at appropriate time, because as the control leave the block, it won't be referenced by any object and will be marked for collection.

韵柒 2024-08-31 04:00:01

不确定这是否是您来自的地方; someOtherObjectusing 块之外无法访问;由于范围规则

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

请参阅和< a href="http://www.informit.com/library/content.aspx?b=STY_Csharp_24hours&seqNum=127" rel="nofollow noreferrer">此以获得更多帮助。

Not sure if this is where you are coming from; the someOtherObject is not going to be accessible outside the using block; because of the 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!

Compiler error: "The name v1 does not exist in the current context."

Even following would throw an error.

    {
        int x=10;
    }

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

See this and this for more help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文