代码之家  ›  专栏  ›  技术社区  ›  BC.

.NET 3.5的Lazy<t>实现

  •  23
  • BC.  · 技术社区  · 14 年前

    .NET 4.0有一个名为 System.Lazy 执行延迟对象初始化。我想将这个类用于3.5项目。有一次,我在StackOverflow的答案中看到了一个实现,但我再也找不到它了。是否有人可以选择实现lazy?它不需要框架4.0版本的所有线程安全特性。

    更新:

    答案包含非线程安全版本和线程安全版本。

    4 回复  |  直到 14 年前
        1
  •  25
  •   ChaosPandion    14 年前

    这里是我使用的一个实现。

    /// <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();
        }
    }
    
        2
  •  11
  •   Aaronaught    14 年前

    如果您不需要线程安全性,可以很容易地将其与工厂方法组合在一起。我使用的一个非常类似于以下内容:

    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;
            }
        }
    }
    
        3
  •  2
  •   James Curran    14 年前

    有点简单的亚伦的版本

    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; 
        } 
      } 
    } 
    
        4
  •  -1
  •   STO    14 年前

    可以添加一些有趣(但不是非常有用)的内容:从代表处隐式隐藏:

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

    及用法

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

    C编译器在执行此转换时遇到一些问题,例如,分配lambda表达式不起作用,但还有一件事会使您的语言库产生一些思考:)