using System; using System.Threading; namespace Implab.Components { public class LazyAndWeak where T : class { readonly Func m_factory; readonly object m_lock; WeakReference m_reference; public LazyAndWeak(Func factory, bool useLock) { Safe.ArgumentNotNull(factory, "factory"); m_factory = factory; m_lock = useLock ? new object() : null; } public LazyAndWeak(Func factory) : this(factory, false) { } public T Value { get { while (true) { var weak = m_reference; T value; if (weak != null) { value = weak.Target as T; if (value != null) return value; } if (m_lock == null) { value = m_factory(); if (Interlocked.CompareExchange(ref m_reference, new WeakReference(value), weak) == weak) return value; } else { } } } } } }