ResettableLazy: a resettable version of .NET Lazy I implemented a resettable version of .NET Lazy (context: mostly to use it in a MemoryCache for auto refresh purposes on item expiration)

This is a very naive implementation and I am pretty sure there are couple of things that are not okay. In particular, I am not really sure whether the reset is fine. I think the assignment is atomic but I am not sure what can happen when there is an attempt to get the Value while it is resetting at the same (e.g. I am not sure whether the fact that the assignment is atomic is enough to guarantee proper operations).

public class ResettableLazy&lt;T&gt;
{
    private Lazy&lt;T&gt; _lazy;

    public bool IsValueCreated =&gt; _lazy.IsValueCreated;

    public T Value =&gt; _lazy.Value;

    public LazyThreadSafetyMode LazyThreadSafetyMode { get; }

    private readonly Func&lt;T&gt; _valueFactory;

    public ResettableLazy(Func&lt;T&gt; valueFactory, LazyThreadSafetyMode lazyThreadSafetyMode = LazyThreadSafetyMode.ExecutionAndPublication)
    {
        _valueFactory = valueFactory;
        LazyThreadSafetyMode = lazyThreadSafetyMode;
        _lazy = new Lazy&lt;T&gt;(_valueFactory, LazyThreadSafetyMode);
    }

    public ResettableLazy(Func&lt;T&gt; valueFactory, bool isThreadSafe)
        : this(valueFactory, isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None)
    {
    }

    public void Reset()
    {
        _lazy = new Lazy&lt;T&gt;(_valueFactory, LazyThreadSafetyMode);
    }
}


And played a bit around with:

public static class Program
{
    public static void Main(params string[] args)
    {
        var lazy = new ResettableLazy&lt;int&gt;(() =&gt;
        {
            Thread.Sleep(2000);
            return new Random().Next();
        });

        for (var i = 0; i &lt; 1000; i++)
        {
            if (i % 2 == 0)
            {
                Thread.Sleep(200);
            }

            Task.Run(() =&gt; Console.WriteLine(lazy.Value));

            if (i % 3 == 0)
            {
                Task.Run(() =&gt; lazy.Reset());
            }
        }

        Console.ReadKey();
    }
}


Is there any red flags in my implementation?
Overall, it looks good to me.  There aren't any real threading concerns with simultaneously resetting and accessing the value.  The body of the Value property getter will either use the old _lazy or the new _lazy, but those are the only options.  Since there isn't any locking it is possible for one thread to continue to see the old value after another thread resets (due to caching a value of the _lazy reference), but this is likely not a problem in most use cases.

One thing to note is that if Lazy&lt;T&gt;.IsValueCreated ever becomes true it stays true for the lifetime of the object, and this is not the case with your class.  It's worth calling out that if the object is shared between threads than many of the reasons to use IsValueCreated become less reliable (e.g. accessing .Value may be expensive).