IDisposable Question

前端 未结 8 1650
野的像风
野的像风 2021-01-11 18:35

Say I have the following:

public abstract class ControlLimitBase : IDisposable 
{
}

public abstract class UpperAlarmLimit : ControlLimitBase 
{
}

public cl         


        
相关标签:
8条回答
  • 2021-01-11 19:11
    1. When someone calls .Dispose on it.
    2. No, it already implements it through inheritance.
    0 讨论(0)
  • 2021-01-11 19:13
    1. No, IDisposable won't be called just automatically. You'd normally call Dispose with a using statement, like this:

      using (ControlLimitBase limit = new UpperAlarmLimit())
      {
          // Code using the limit
      }
      

      This is effectively a try/finally block, so Dispose will be called however you leave the block.

    2. CdsUpperAlarmLimit already implements IDisposable indirectly. If you follow the normal pattern for implementing IDisposable in non-sealed classes, you'll override void Dispose(bool disposing) and dispose your composed resources there.

    Note that the garbage collector does not call Dispose itself - although it can call a finalizer. You should rarely use a finalizer unless you have a direct handle on unmanaged resources though.

    To be honest, I usually find it's worth trying to change the design to avoid needing to keep hold of unmanaged resources in classes - implementing IDisposable properly in the general case is frankly a pain. It's not so bad if your class is sealed (no need for the extra method; just implement the Dispose() method) - but it still means your clients need to be aware of it, so that they can use an appropriate using statement.

    0 讨论(0)
  • 2021-01-11 19:18

    IDisposable is implemented when you want to indicate that your resource has dependencies that must be explicitly unloaded and cleaned up. As such, IDisposable is never called automatically (like with Garbage Collection).

    Generally, to handle IDisposables, you should wrap their usage in a using block

    using(var x = new CdsUpperAlarmLimit()) { ... }
    

    this compiles to:

    CdsUpperAlarmLimit x = null;
    try
    {
       x = new CdsUpperAlarmLimit();
       ...
    }
    finally
    {
       x.Dispose();
    }
    

    So, back to topic, if your type, CdsUpperAlarmLimit, is implementing IDisposable, it's saying to the world: "I have stuff that must be disposed". Common reasons for this would be:

    • CdsUpperAlarmLimit keeps some OTHER IDisposable resources (like FileStreams, ObjectContexts, Timers, etc.) and when CdsUpperAlarmLimit is done being used, it needs to make sure the FileStreams, ObjectContexts, Timers, etc. also get Dispose called.
    • CdsUpperAlarmLimit is using unmanaged resources or memory and must clean up when it's done or there will be a memory leak
    0 讨论(0)
  • 2021-01-11 19:20

    The best practice recommend when you implement Dispose() method in non sealed class you should have a virtual method for your derived classes to override.

    Read more on Dispose pattern here http://www.codeproject.com/KB/cs/idisposable.aspx

    0 讨论(0)
  • 2021-01-11 19:23

    Dispose() is never called automatically - it depends on how the code is actually used.

    1.) Dispose() is called when you specifically call Dispose():

    myAlarm.Dispose();
    

    2.) Dispose() is called at the end of a using block using an instance of your type.

    using(var myAlarm = new CdsUpperAlarmLimit())
    {
    
    }
    

    The using block is syntactic sugar for a try/finally block with a call to Dispose() on the object "being used" in the finally block.

    0 讨论(0)
  • 2021-01-11 19:28

    I'm a little confused on when my IDisposable members would actually get called. Would they get called when an instance of CdsUpperAlarmLimit goes out of scope?

    No. Its get called when you use using construct as:

    using(var inst = new CdsUpperAlarmLimit())
    {
        //...
    }//<-------- here inst.Dispose() gets called.
    

    But it doesn't get called if you write this:

    {
       var inst = new CdsUpperAlarmLimit();
       //...
    }//<-------- here inst.Dispose() does NOT get called.
    

    However, you can write this as well:

    var inst = new CdsUpperAlarmLimit();
    using( inst )
    {
        //...
    }//<-------- here inst.Dispose() gets called.
    
    0 讨论(0)
提交回复
热议问题