用于.NET 3.5的Lazy <T>的实现

BC.*_*BC. 23 c# generics lazy-loading

.NET 4.0有一个很好的实用程序类,名为System.Lazy,它执行惰性对象初始化.我想将这个类用于3.5项目.有一次我在stackoverflow的答案中看到某个实现,但我再也找不到了.有人有Lazy的替代实现吗?它不需要框架4.0版本的所有线程安全功能.

更新:

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

Cha*_*ion 26

这是我使用的实现.

/// <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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 代码似乎并不完全是线程安全的.使用维基百科建议的内存屏障可能更好:http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Microsoft_.NET_.28Visual_Basic.2C_C.23.29 (5认同)

Aar*_*ght 11

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

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)