-3

WiresharkFile abstract class:

public abstract class WiresharkFile
{
    private PlayBehavior _playBehavior;

    public void Transmit()
    {
        _playBehavior.Transmit();
    }

    public virtual void Dispose()
    {
        // Implemented inside inherit classes.
    }
}

Play options abstract class:

public abstract class PlayBehavior
{
    public WiresharkFile wiresharkFile;

    public abstract void Transmit();                        
}

Play options son class:

public class Normal : PlayBehavior
{
    public override void Transmit()
    {
        using (this.wiresharkFile)
        {

        }
    }
}

So i have this derived class:

public class Libpcap : WiresharkFile, IDisposable, IEnumerable<Packet>
{
    private BinaryReader binaryReader;

    public void Dispose()
    {
        if (binaryReader != null)
            binaryReader.Close();
    }
    ...
    // Severl methods
    ...

    public override void SendPackets()
    {
       base.Transmit();
    }
}

My question:

Inside this Libpcap class when call base.Transmit(): where to use the using ? Inside this Libpcap class SendPackets():

public override void SendPackets()
{
   using(this)
   {
      base.Transmit();
   }
}

Or inside Normal class Transmit():

public class Normal : PlayBehavior
{
    public override void Transmit()
    {
        using (this.wiresharkFile)
        {

        }
    }
}
david hol
  • 1,272
  • 7
  • 22
  • 44

1 Answers1

3

Calling using(this) never makes sense. It means you're calling Dispose on yourself, which means that A) your class will be at an undefined state at the end of the using block, and B) code calling you will see you're IDisposable and expect to be able to control your lifetime, but you're actually controlling it yourself from within your code.

If your Libpcap's lifetime ends after the Transmit call, you can use using on it from your PlayBehavior class - it holds the reference to it, so it controls its lifetime.

Implementing IDisposable is a contract. By doing so, you're saying "My operation holds references to unmanaged resources (files, tcp connections, etc), and you, my caller, need to call my Dispose method when you're done with me to release them". If this is not the usage contract that WiresharkFile expects, don't implement IDisposable.

If you have unmanaged resources that are created and released as part of your normal operations, but which doesn't require your caller to explicitly release, simply do it yourself - release an internal unmanaged resource when you're done with it.

Avner Shahar-Kashtan
  • 14,492
  • 3
  • 37
  • 63