Theo and I were talking about places where you might use lazy loading and the singleton pattern.  We were thinking about WeakReferences and how they were valuable but didn't allow you enough control over when the reference might be released.  An example of where this would be important would be in some sort of server caching scenario.  The first time someone hits a page you generate it and cache it.  That way subsequent users will get the cached page.  You want it to be weak so that the server can reclaim those resources if it needs to when people start hitting other pages.  However, say the author of the page updates it.  You don't want people to keep getting the cached version so you need a way to invalidate the reference.  Of course, with our lazy loader we allowed you to provide your own IReference implementation so it would be very simple to add this behavior yourself.  I struggled over the name of what such an object would be:  InvalidatableReference? ResetableReference?  It doesn't really roll of the tongue.  (Names are very important to me and i spend a lot of time thinking about them because they tend to help you understand the system better).  I went to talk to Damon (another guy here who comes in obscenely early like me) about it and he came up with “DisposableReference”.  Sheer brilliance.  By telling me that he connected the two concepts of reference and disposable things.    I started to write it up and got this far:

namespace Testing.References

{

    public class DisposableReference<A> : IReference<A>, IDisposable

    {

        IOptional<A> target = None<A>.Instance;

 

        #region IReference<A> Members

 

        public A Value

        {

            set

            {

                target = new Some<A>(value);

            }

        }

 

        public IOptional<A> Target

        {

            get

            {

                return target;

            }

        }

 

        #endregion

 

        #region IDisposable Members

 

        public void Dispose()

        {

            target = None<A>.Instance;

        }

 

        #endregion

    }

}

But then i started to realize something.  What if you wanted a WeakDisposableReference?  You'd have to introduce another type into your system.  Instead, it clicked that what we were doing was allowing a reference to return to it's original uninitialized state.  So this was an operation that would be allowed on any reference.  i.e.:

    public interface IReference<A> : IDisposable

    {

        A Value { set; }

 

        IOptional<A> Target { get; }

    }

With the two implementations being:

    public class StrongReference<A> : IReference<A>

    {

        IOptional<A> target = None<A>.Instance;

 

        #region IOptional<A> Members

 

        public IOptional<A> Target

        {

            get

            {

                return target;

            }

        }

 

        public A Value

        {

            set

            {

                target = new Some<A>(value);

            }

        }

 

        #endregion

 

        #region IDisposable Members

 

        public void Dispose()

        {

            target = None<A>.Instance;

        }

 

        #endregion

    }

and

    public class WeakReference<A> : IReference<A>

    {

        System.WeakReference reference = new System.WeakReference(null);

 

        #region IOptional<A> Members

 

        public IOptional<A> Target

        {

            get

            {

                IOptional<A> target = (IOptional<A>)reference.Target;

                if (target == null)

                {

                    return None<A>.Instance;

                }

                else

                {

                    return target;

                }

            }

        }

 

        public A Value

        {

            set

            {

                reference = new System.WeakReference(new Some<A>(value));

            }

        }

 

        #endregion

 

        #region IDisposable Members

 

        public void Dispose()

        {

            reference = new System.WeakReference(null);

        }

 

        #endregion

    }

Now you can have all the benefits of lazy loading with weak/strong references, with the ability to invalidate the cached copy any time you want.