Helpers for lazy initialization in .NET applications.
SyncLazy
is System.Lazy<T>
wrapper which re-creates lazily initiated value when lazy initialization throws exception.
It supports the same interface as System.Lazy<T>
.
var counter = 0;
var lazy = new SyncLazy<int>(() => ++counter);
var value1 = lazy.Value;
Assert.AreEqual(1, value1);
var value2 = lazy.Value;
Assert.AreEqual(1, value2);
It also supports clearing of lazily initiated value.
var counter = 0;
var lazy = new SyncLazy<int>(() => ++counter);
var value1 = lazy.Value;
Assert.AreEqual(1, value1);
lazy.ClearValue();
var value2 = lazy.Value;
Assert.AreEqual(2, value2);
It does not cache lazy initialization exceptions.
string returnValue = null;
var lazy = new SyncLazy<string>(() => returnValue ?? throw new InvalidOperationException("Error"));
try
{
var unused = lazy.Value;
Assert.Fail("Exception is not thrown");
}
catch (InvalidOperationException ex) when (ex.Message == "Error")
{
}
returnValue = "Some value";
var value = lazy.Value;
Assert.AreEqual(returnValue, value);
AsyncLazy
is limited async implementation of System.Lazy<T>
with System.Threading.Tasks.Task<TResult>
re-initialization when System.Threading.Tasks.Task<TResult>
is not succefully completed.
It supports basic functionality of System.Lazy<T>
.
var counter = 0;
async Task<int> ValueFactory() => await Task.Run(() => ++counter);
var lazy = new AsyncLazy<int>(ValueFactory);
var value1 = await lazy.GetValueAsync();
Assert.AreEqual(1, value1);
var value2 = await lazy.GetValueAsync();
Assert.AreEqual(1, value2);
It also supports clearing of lazily initiated value.
var counter = 0;
async Task<int> ValueFactory() => await Task.Run(() => ++counter);
var lazy = new AsyncLazy<int>(ValueFactory);
var value1 = await lazy.GetValueAsync();
Assert.AreEqual(1, value1);
lazy.ClearValue();
var value2 = await lazy.GetValueAsync();
Assert.AreEqual(2, value2);