简体   繁体   中英

How to properly dispose locally created object in another method?

So I have a class which implements IDisposable, and I have several methods (in another class) which follow the pattern below:

public void SomeMethod()
{
    DisposableObject disposableObject = new DisposableObject();

    // Do some stuff with the object

    SomeOtherMethod(disposableObject);
    disposableObject.Dispose();
}

While all of these methods do different things, they all call SomeOtherMethod at the end, which does a few more things with the disposable object before it's no longer needed. When I move disposableObject.Dispose(); into SomeOtherMethod , Visual Studio gives me a message saying: " Use recommended dispose pattern to ensure that object created by 'new DisposableObject()' is disposed on all paths: using statement/declaration or try/finally "

This message appears regardless of whether or not I pass the disposable object to SomeOtherMethod using the ref keyword.

My question is, will that object be disposed as long as SomeOtherMethod calls Dispose() on it? I'm assuming it will, and Visual Studio continues to send the message simply because it isn't "aware" of what's happening to that object in subsequent methods, but I'd love to get some confirmation on that!

It may be disposed or may be not, depends on the fact whether the execution will reach the Dispose invocation or not and that's because an exception can be thrown before the Dispose is called. Using try finally construction explicitly or implicitly by using keyword ensures that it will be called for any scenario and that's why VS gives you the warning.

No matter where one call the Dispose() , it is called.

Not using the language keyword using for the disposable pattern, therefore moving the dispose in another method, is an anti-pattern, therefore it is a bad practice and a source of potential problems.

You can only remove the warning by adding the warning number in the project build settings.

The method Dispose() doesn't destroy the object.

The dispose pattern is only for freeing unmanaged resources like windows handle and shared memories.

After a call to Dispose() you still have the object and so the reference to the object that remains referenced in the managed memory.

Dispose() is made to be called once time at the end of object usage and no more.

The compiler send you a warning because you break the standard behavior of the pattern usage that is to use the using keyword.

And breaking standards can be source of problems.

The using of disposable objects standard is made to avoid bugs by letting the compiler generates the try {... } finally { Dispose() } block to be sure that Dispose() is correctly called in the right place to avoid mistakes.

So avoid calling the Dispose() directly.

Unless you are sure of what you do, prefer using:

public void SomeMethod()
{
  using ( DisposableObject disposableObject = new DisposableObject() )
  {
    // Do some stuff with the object
    SomeOtherMethod(disposableObject);
  }
}

And your code may be robust.

will that object be disposed

Sorry, but that's a meaningless question. The CLR does not keep track of whether an object has had its “dispose” method called or not (see Will the Garbage Collector call IDisposable.Dispose for me? )

As a general rule, it is always much nicer (readable/ maintainable / less-bug-prone / etc) that a method that creates an issue should also be the one that cleans up after itself. As you've just found, this pattern also allows automated checking by the compiler - and again, it is also a good rule to ensure that your code compiles cleanly without errors OR WARNINGS.

In this case, the warning is giving you a couple of ways to implement this cleanly; personally, I would prefer the “using” clause (so avoiding having to have an explicit call to “dispose”) like:

 public void SomeMethod()
 {
     using (DisposableObject disposableObject = new DisposableObject() )
      {

           // Do some stuff with the object

           SomeOtherMethod(disposableObject);
       }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM