Lazy<T>
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Threading;
namespace System
{
[Serializable]
[ComVisible(false)]
[DebuggerDisplay("ThreadSafetyMode={mode}, IsValueCreated={IsValueCreated}, IsValueFaulted={exception != null}, Value={value}")]
[HostProtection(SecurityAction.LinkDemand)]
internal class Lazy<T>
{
private T value;
private Func<T> factory;
private object monitor;
private Exception exception;
private System.Threading.LazyThreadSafetyMode mode;
private bool inited;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public T Value {
get {
if (inited)
return value;
if (exception != null)
throw exception;
return InitValue();
}
}
public bool IsValueCreated => inited;
public Lazy()
: this(System.Threading.LazyThreadSafetyMode.ExecutionAndPublication)
{
}
public Lazy(Func<T> valueFactory)
: this(valueFactory, System.Threading.LazyThreadSafetyMode.ExecutionAndPublication)
{
}
public Lazy(bool isThreadSafe)
: this((Func<T>)Activator.CreateInstance<T>, isThreadSafe ? System.Threading.LazyThreadSafetyMode.ExecutionAndPublication : System.Threading.LazyThreadSafetyMode.None)
{
}
public Lazy(Func<T> valueFactory, bool isThreadSafe)
: this(valueFactory, isThreadSafe ? System.Threading.LazyThreadSafetyMode.ExecutionAndPublication : System.Threading.LazyThreadSafetyMode.None)
{
}
public Lazy(System.Threading.LazyThreadSafetyMode mode)
: this((Func<T>)Activator.CreateInstance<T>, mode)
{
}
public Lazy(Func<T> valueFactory, System.Threading.LazyThreadSafetyMode mode)
{
if (valueFactory == null)
throw new ArgumentNullException("valueFactory");
factory = valueFactory;
if (mode != 0)
monitor = new object();
this.mode = mode;
}
private T InitValue()
{
switch (mode) {
case System.Threading.LazyThreadSafetyMode.None: {
Func<T> func = factory;
if (func == null) {
if (exception == null)
throw new InvalidOperationException("The initialization function tries to access Value on this instance");
throw exception;
}
try {
factory = null;
T val = value = func();
Thread.MemoryBarrier();
inited = true;
} catch (Exception ex3) {
Exception ex4 = exception = ex3;
throw;
}
break;
}
case System.Threading.LazyThreadSafetyMode.PublicationOnly: {
Func<T> func = factory;
T val = (func == null) ? default(T) : func();
lock (monitor) {
if (inited)
return value;
value = val;
Thread.MemoryBarrier();
inited = true;
factory = null;
}
break;
}
case System.Threading.LazyThreadSafetyMode.ExecutionAndPublication:
lock (monitor) {
if (inited)
return value;
if (factory == null) {
if (exception == null)
throw new InvalidOperationException("The initialization function tries to access Value on this instance");
throw exception;
}
Func<T> func = factory;
try {
factory = null;
T val = value = func();
Thread.MemoryBarrier();
inited = true;
} catch (Exception ex) {
Exception ex2 = exception = ex;
throw;
}
}
break;
default:
throw new InvalidOperationException("Invalid LazyThreadSafetyMode " + mode);
}
return value;
}
public override string ToString()
{
if (inited)
return value.ToString();
return "Value is not created";
}
}
}