# Snoozy: A lazy reevaluation upon get

I would appreciate critique and comments in regards of thread-safety on a basic type I'm trying to create.

In C#, the Lazy<T> type is initialized only once, and only when needed the first time.

My type, called Snoozy<T>, is similar, but differs in one important aspect:

The value can be reinitialized when necessary (but only when read).

The purpose is to not perform the value factorization unless someone needs the new value. This could prevent e.g. unnecessary heavy calculations.

Example: A bank account stores a long list of events describing withdrawals and deposits. To get the current balance, all transactions need to be summed up. This could potentially be a very CPU-intensive operation, but the adding of new transactions is rare whereas reading the balance is frequent. When adding a new transaction, there is really no need to recalculate the balance until someone explicitly wants to read it.

This is the code I've come up with so far:

public class Snoozy<T>
{
private T _value;
private bool _isStale;

public Snoozy(Func<T> valueFactory)
{
_factory = valueFactory;
_isStale = true;
}

public T Value
{
get
{

if (_isStale)
{
_lock.EnterWriteLock();

_value = _factory();
_isStale = false;

_lock.ExitWriteLock();
}

return _value;
}
}

// This is how the consumer signals that the underlaying value has changed.
public void Poke()
{
_lock.EnterWriteLock();
_isStale = true;
_lock.ExitWriteLock();
}

public static implicit operator Snoozy<T>(T value)
{
return new Snoozy<T>(() => value);
}

public static implicit operator T(Snoozy<T> snoozy)
{
return snoozy.Value;
}
}

• Well, it looks a lot better than this – Ben Aaronson Aug 25 '16 at 11:10
• What is the purpose of implicit operator Snoozy<T>(T value)? Shouldn't it take a Func<T>? – Stefano d'Antonio Aug 25 '16 at 12:21
• @Uno: You're absolutely right! It should. (: – Reyhn Aug 29 '16 at 9:06

Why don't you just wrap Lazy<T> and recreate it if necessary?

public sealed class Snoozy<T>
{
private Lazy<T> _lazy;

public Snoozy(Func<T> factory)
{
_factory = factory;
_lazy = new Lazy<T>(factory);
}

public T Value => _lazy.Value;

public void Poke()
{
if (_lazy.IsValueCreated)
{
_lazy = new Lazy<T>(_factory);
}
}
}

• Welcome to Code Review; good first answer, enjoy your stay! – ferada Aug 27 '16 at 21:31
• Honestly, it didn't occur to me. (: The only downside with this pretty solution is that _lazy is recreated on every Poke, which probably is unnecessary. Also, what happens when thread 1 is writing the volatile _lazy at the same time as thread 2 is constructing _lazy.Value? – Reyhn Aug 29 '16 at 9:13
• I modified my answer. volatile was not necessary. And I included a check for _lazy to be initialized in Poke method to avoid extra allocation. In the situation you described thread 2 will use the previous value. Yes, it's possible that _factory delegate will be called twice in a short period of time. To avoid it you probably need an asynchronous initialization with cancellation – just.ru Aug 29 '16 at 16:44

That means your current implementation is basically just exclusive locking.

public Snoozy(Func<T> valueFactory)
{
if (valueFactory == null)
{
throw new ArgumentNullException(nameof(valueFactory));
}