Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation of Lazy<T> for .NET 3.5

Tags:

.NET 4.0 has a nice utility class called System.Lazy that does lazy object initialization. I would like to use this class for a 3.5 project. One time I saw an implementation somewhere in a stackoverflow answer but I can't find it anymore. Does someone have an alternative implementation of Lazy? It doesn't need all the thread safety features of the framework 4.0 version.

Updated:

Answers contain a non thread safe and a thread safe version.

like image 872
BC. Avatar asked Jul 08 '10 20:07

BC.


People also ask

What is Lazy T in C#?

The Lazy<T> object ensures that all threads use the same instance of the lazily initialized object and discards the instances that are not used.

How would you accomplish lazy initialization in net?

To implement a public property by using lazy initialization, define the backing field of the property as a Lazy<T>, and return the Value property from the get accessor of the property. The Value property is read-only; therefore, the property that exposes it has no set accessor.

How does lazy loading work in C#?

The type argument of the Lazy<T> object that you create specifies the type of the object that you want to initialize lazily. The constructor that you use to create the Lazy<T> object determines the characteristics of the initialization. Lazy initialization occurs the first time the Lazy<T>. Value property is accessed.

What is lazy initialization in C++?

In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. It is a kind of lazy evaluation that refers specifically to the instantiation of objects or other resources.


2 Answers

Here is an implementation that I use.

/// <summary> /// Provides support for lazy initialization. /// </summary> /// <typeparam name="T">Specifies the type of object that is being lazily initialized.</typeparam> public sealed class Lazy<T> {     private readonly object padlock = new object();     private readonly Func<T> createValue;     private bool isValueCreated;     private T value;      /// <summary>     /// Gets the lazily initialized value of the current Lazy{T} instance.     /// </summary>     public T Value     {         get         {             if (!isValueCreated)             {                 lock (padlock)                 {                     if (!isValueCreated)                     {                         value = createValue();                         isValueCreated = true;                     }                 }             }             return value;         }     }      /// <summary>     /// Gets a value that indicates whether a value has been created for this Lazy{T} instance.     /// </summary>     public bool IsValueCreated     {         get         {             lock (padlock)             {                 return isValueCreated;             }         }     }       /// <summary>     /// Initializes a new instance of the Lazy{T} class.     /// </summary>     /// <param name="createValue">The delegate that produces the value when it is needed.</param>     public Lazy(Func<T> createValue)     {         if (createValue == null) throw new ArgumentNullException("createValue");          this.createValue = createValue;     }       /// <summary>     /// Creates and returns a string representation of the Lazy{T}.Value.     /// </summary>     /// <returns>The string representation of the Lazy{T}.Value property.</returns>     public override string ToString()     {         return Value.ToString();     } } 
like image 100
ChaosPandion Avatar answered Nov 03 '22 20:11

ChaosPandion


If you don't need thread-safety, it's pretty easy to put one together with a factory method. I use one very similar to the following:

public class Lazy<T> {     private readonly Func<T> initializer;     private bool isValueCreated;     private T value;      public Lazy(Func<T> initializer)     {         if (initializer == null)             throw new ArgumentNullException("initializer");         this.initializer = initializer;     }      public bool IsValueCreated     {         get { return isValueCreated; }     }      public T Value     {         get         {             if (!isValueCreated)             {                 value = initializer();                 isValueCreated = true;             }             return value;         }     } } 
like image 21
Aaronaught Avatar answered Nov 03 '22 20:11

Aaronaught