Implementation of Lazy for .NET 3.5

后端 未结 4 1562
生来不讨喜
生来不讨喜 2020-12-04 16:54

.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

相关标签:
4条回答
  • 2020-12-04 17:20

    A somewhat simplify version of aaron's

    public class Lazy<T> where T : new()
    { 
      private T value; 
    
      public bool IsValueCreated { get; private set;}
    
      public T Value 
      { 
        get 
        { 
            if (!IsValueCreated) 
            { 
                value = new T();
                IsValueCreated = true; 
            } 
            return value; 
        } 
      } 
    } 
    
    0 讨论(0)
  • 2020-12-04 17:23

    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;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-04 17:40

    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();
        }
    }
    
    0 讨论(0)
  • 2020-12-04 17:45

    Some funny (but not very usable) stuff can be added: implicit coversion from delegate:

    public static implicit operator Lazy<T>(Func<T> initializer)
    {
        return new Lazy<T>(initializer);
    }  
    

    And usage

    private static Lazy<int> Value = new Func<int>(() => 24 * 22);
    

    C# compiler have some problem with performing this conversion, for example assigning lambda expression does not work, but it is one more thing causes your colleguas to think a bit :)

    0 讨论(0)
提交回复
热议问题