Реализация Lazy <T>для .NET 3.5 - PullRequest
23 голосов
/ 09 июля 2010

.NET 4.0 имеет класс полезных утилит System.Lazy , который выполняет отложенную инициализацию объектов. Я хотел бы использовать этот класс для проекта 3.5. Однажды я увидел реализацию где-то в ответе stackoverflow, но больше не могу ее найти. У кого-нибудь есть альтернативная реализация Lazy? Ему не нужны все функции обеспечения безопасности потоков версии 4.0.

Обновлен:

Ответы содержат не-потокобезопасную и поточно-безопасную версию.

Ответы [ 4 ]

26 голосов
/ 09 июля 2010

Вот реализация, которую я использую.

/// <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();
    }
}
11 голосов
/ 09 июля 2010

Если вам не нужна защита от потоков, довольно легко собрать ее вместе с заводским методом. Я использую один очень похожий на следующее:

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;
        }
    }
}
2 голосов
/ 09 июля 2010

Несколько упрощенная версия Аарона

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 голосов
/ 09 июля 2010

Может быть добавлено несколько забавных (но не очень полезных) вещей: неявное покрытие от делегата:

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 # имеет некоторые проблемы с выполнением этого преобразования, например, назначение лямбда-выражения не работает, но это еще одна вещь, заставляющая ваших коллег немного подумать:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...