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);
if (aReference.IsAlive == true)
{
}
else
{
}
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.