using System.Collections.Generic;
using System.Runtime.InteropServices;
public abstract class Base : IDisposable
private bool disposed = false;
private string instanceName;
private List<object> trackingList;
public Base(string instanceName, List<object> tracking)
this.instanceName = instanceName;
public string InstanceName
Console.WriteLine("\n[{0}].Base.Dispose()", instanceName);
GC.SuppressFinalize(this);
protected virtual void Dispose(bool disposing)
Console.WriteLine("[{0}].Base.Dispose(true)", instanceName);
trackingList.Remove(this);
Console.WriteLine("[{0}] Removed from tracking list: {1:x16}",
instanceName, this.GetHashCode());
Console.WriteLine("[{0}].Base.Dispose(false)", instanceName);
Console.WriteLine("\n[{0}].Base.Finalize()", instanceName);
public class Derived : Base
private bool disposed = false;
private IntPtr umResource;
public Derived(string instanceName, List<object> tracking) :
base(instanceName, tracking)
umResource = Marshal.StringToCoTaskMemAuto(instanceName);
protected override void Dispose(bool disposing)
Console.WriteLine("[{0}].Derived.Dispose(true)", InstanceName);
Console.WriteLine("[{0}].Derived.Dispose(false)", InstanceName);
if (umResource != IntPtr.Zero)
Marshal.FreeCoTaskMem(umResource);
Console.WriteLine("[{0}] Unmanaged memory freed at {1:x16}",
InstanceName, umResource.ToInt64());
umResource = IntPtr.Zero;
public class TestDisposal
public static void Main()
List<object> tracking = new List<object>();
Console.WriteLine("\nDisposal Scenario: #1\n");
Derived d3 = new Derived("d1", tracking);
using (Derived d1 = new Derived("d2", tracking))
Console.WriteLine("\nDisposal Scenario: #2\n");
Console.WriteLine("\nDisposal Scenario: #3\n");
Derived d2 = new Derived("d3", tracking);
Console.WriteLine("\nDisposal Scenario: #4\n");
Derived d4 = new Derived("d4", tracking);
Console.WriteLine("\nObjects remaining to dispose = {0:d}", tracking.Count);
foreach (Derived dd in tracking)
Console.WriteLine(" Reference Object: {0:s}, {1:x16}",
dd.InstanceName, dd.GetHashCode());
Console.WriteLine("\nDequeueing finalizers...");