using System;

namespace Example
{
    public class Test4 
    {
        private static int intTest4Count = 0;
        public string strMyValue;
        public Test4(string inMyValue)
        {
            Console.WriteLine("    Test4 ({0}) Constructor",inMyValue);
            if(MemoryExample.objHolder != null)
            {
                ((Test4)MemoryExample.objHolder).Dispose();
                MemoryExample.objHolder = null;
            }
            strMyValue = inMyValue;
            intTest4Count++;
        }
        
        //protected override void Finalize()
        //see the note above
        ~Test4()
        {
            Console.WriteLine("    Test4 Finalize [{0}][{1}]", strMyValue,intTest4Count--);
            if (intTest4Count <= 0)
            {
                Console.WriteLine("    Test4 Resurrecting [{0}][{1}]", strMyValue,++intTest4Count);
                MemoryExample.objHolder = this;
                GC.ReRegisterForFinalize(this);
            }
            else
            {
                MemoryExample.objHolder = null;
            }
        }
        
        public void Dispose()
        {
            Console.WriteLine("    Test4 Dispose [{0}][{1}]", strMyValue,intTest4Count--);
            GC.SuppressFinalize(this);
        }
    }

    public class MemoryExample
    {
        static public object objHolder;  // defaults to null

        static void Main(string[] args)
        {
            object one;
            object two;
            
            Console.WriteLine("BEGIN:");
            one = new Test4("blarg");
            two = new Test4("futz");
            one = null;
            two = null;
            Console.WriteLine("  Start First Collection Point");
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Console.WriteLine("  End First Collection Point");

            one = new Test4("blarg2");
            two = new Test4("futz2");
            ((Test4)one).Dispose();
            one = null;
            ((Test4)two).Dispose();
            two = null;
            Console.WriteLine("  Start Second Collection Point");
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Console.WriteLine("  End Second Collection Point");
            Console.WriteLine("END");
        }
    }
}