Click here to Skip to main content
15,879,535 members
Articles / Programming Languages / C#
Tip/Trick

LazyWeakReference

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
10 Dec 2012CPOL 10.7K   5   4
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:

C#
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:

C#
[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)


Written By
Software Developer Crypton-M
Ukraine Ukraine
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionok.. Pin
FatCatProgrammer10-Dec-12 3:38
FatCatProgrammer10-Dec-12 3:38 
AnswerRe: ok.. Pin
kosmoh10-Dec-12 4:22
kosmoh10-Dec-12 4:22 
Good remark.
Let`s just remember, why do we need Lazy and WeakReference classes: their purpose is to get rid of big objects, when they are not in use yet/haven`t been used for a while. Do not use such class when your actual object is small. They`re not designed for such purpose.
Imagine the situation when desktop application deals with images, plenty of images. It`s very likely, that the user will return to the clothest images back but not further. This is where LazyWeakReference will show itself superb: it`ll reload the whole picture or use the one that remained.
GeneralRe: ok.. Pin
FatCatProgrammer10-Dec-12 13:50
FatCatProgrammer10-Dec-12 13:50 
GeneralRe: ok.. Pin
kosmoh12-Dec-12 6:40
kosmoh12-Dec-12 6:40 

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

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