Click here to Skip to main content
Click here to Skip to main content

LazyWeakReference

, 10 Dec 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
A simple class for implementing Lazy Phoenix-like weak reference.

Introduction

This tip presents a small and useful class for having a weak reference that reconstructs itself if needed.

Using the code 

Consider the code below:

BigObject someBigObject = new SomeBigObject();
WeakReference aReference = new WeakReference(someBigObject);
//...
//somewhere else, where someBigObject variable is not accessible any more:
if (aReference.IsAlive == true)
{
 //OK, work with it
}
else
{
 //react
}

For those who have worked with weak references this code is quite familiar. Sometimes the action that should be done about weak reference is known - in my case it's often reinitializing the object back to life. Just consider the following code to see what I got:

[Serializable]
public class LazyWeakReference<T>
     where T : class
{
    WeakReference reference;
    Func<T> constructor = null;
    private int reinitializingCounter = 0;

    public LazyWeakReference(T anObject, Func<T> aConstructor = null)
    {
        reference = new WeakReference(anObject);
        constructor = aConstructor;
    }

    public int Reinitialized { get { return reinitializingCounter; } }

    public T Target
    {
        get
        {
            object target = reference.Target;
            if (target == null)
            {
                if (constructor == null) return null;
                T newObject = constructor();
                reinitializingCounter++;
                reference = new WeakReference(newObject);
                return newObject;
            }
            return (T)target;
        }
    }

}

class Program
{

    public static void Main(string[] args)
    {
        LazyWeakReference<StringBuilder> builder = 
          new LazyWeakReference<StringBuilder>(
          new StringBuilder("A builder"), () => 
          new StringBuilder("Acopy"));
        StringBuilder aTarget = builder.Target;
        aTarget = null;
        GC.Collect();
        Console.WriteLine("Reinitialized {0} times",builder.Reinitialized);
        aTarget = builder.Target;
        aTarget = null;
        GC.Collect();
        Console.WriteLine("Reinitialized {0} times", builder.Reinitialized);
        aTarget = builder.Target;
        aTarget = null;
        GC.Collect();
        Console.WriteLine("Reinitialized {0} times", builder.Reinitialized);
        aTarget = builder.Target;
        aTarget = null;
        Console.WriteLine("Reinitialized {0} times", builder.Reinitialized);
        Console.ReadKey();
    }
}

The output is shown below:

Reinitialized 0 times
Reinitialized 1 times
Reinitialized 2 times
Reinitialized 3 times

Points of Interest 

There is no thread-safety issue in this code. You could add it. This functionality is enough for my needs.

History

  • December 10, 2012 - First published.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

kosmoh
Software Developer Crypton-M
Ukraine Ukraine
No Biography provided

Comments and Discussions

 
Questionok.. PinmemberFatCatProgrammer10-Dec-12 4:38 
AnswerRe: ok.. Pinmemberkosmoh10-Dec-12 5:22 
GeneralRe: ok.. PinmemberFatCatProgrammer10-Dec-12 14:50 
GeneralRe: ok.. Pinmemberkosmoh12-Dec-12 7:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.1411019.1 | Last Updated 10 Dec 2012
Article Copyright 2012 by kosmoh
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid