title: Should I use IDisposable for purely managed resources?
body: <p>Here is the scenario:</p>
  
  <p>I have an object called a <code>Transaction</code> that needs to make sure that only one entity has permission to edit it at any given time.</p>
  
  <p>In order to facilitate a long-lived lock, I have the class generating a token object that can be used to make the edits.</p>
  
  <p>You would use it like this:</p>
  
  <pre><code>var transaction = new Transaction();
  
  using (var tlock = transaction.Lock())
  {
      transaction.Update(data, tlock);
  }
  </code></pre>
  
  <p>Now, I want the <code>TransactionLock</code> class to implement <code>IDisposable</code> so that its usage can be clear.  But, I don't have any unmanaged resources to dispose.  however, the TransctionLock object itself is a sort of "unmanaged resource" in the sense that the CLR doesn't know how to properly finalize it.</p>
  
  <p>All of this would be fine and dandy, I would just use <code>IDisposable</code> and be done with it.</p>
  
  <p>However, my issue comes when I try to do this in the finalizer:</p>
  
  <pre><code>~TransactionLock()
  {
      this.Dispose(false);
  }
  </code></pre>
  
  <p>I want the finalizer to release the transaction from the lock, if possible.  <strong>How, in the finalizer, do I detect if the parent transaction (<code>this.transaction</code>) has already been finalized?</strong></p>
  
  <p><strong>Is there a better pattern I should be using?</strong></p>
  
  <p>Also, the <code>Transaction</code> class itself needn't be disposable, because it doesn't maintain a reference to the lock, and doesn't care whether or not it is unlocked when it goes to the grave.</p>
  
  <hr/>
  
  <p>The Transaction class looks something like this:</p>
  
  <pre><code>public sealed class Transaction
  {
      private readonly object lockMutex = new object();
  
      private TransactionLock currentLock;
  
      public TransactionLock Lock()
      {
          lock (this.lockMutex)
          {
              if (this.currentLock != null)
                  throw new InvalidOperationException(/* ... */);
  
              this.currentLock = new TransactionLock(this);
              return this.currentLock;
          }
      }
  
      public void Update(object data, TransactionLock tlock)
      {
          lock (this.lockMutex)
          {
              this.ValidateLock(tlock);
  
              // ...
          }
      }
  
      internal void ValidateLock(TransactionLock tlock)
      {
          if (this.currentLock == null)
              throw new InvalidOperationException(/* ... */);
  
          if (this.currentLock != tlock)
              throw new InvalidOperationException(/* ... */);
      }
  
      internal void Unlock(TransactionLock tlock)
      {
          lock (this.lockMutex)
          {
              this.ValidateLock(tlock);
  
              this.currentLock = null;
          }
      }
  }
  </code></pre>
  
  <p>And the <code>Dispose(bool)</code> code for the <code>TransactionLock</code>:</p>
  
  <pre><code>private void Dispose(bool disposing)
  {
      if (disposing)
      {
          if (this.Transaction != null)
          {
              this.Transaction.Unlock(this);
              this.Transaction = null;
          }
      }
  }
  </code></pre>