.NET 4.0有一个很好的实用程序类,叫做System.Lazy,可以进行惰性对象初始化。我想将这个类用于3.5项目。有一次我在stackoverflow的答案中看到某个实现,但我再也找不到了。有人有Lazy的替代实现吗?它不需要框架4.0版本的所有线程安全功能。
更新
Answers包含非线程安全和线程安全版本。
答案 0 :(得分: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();
}
}
答案 1 :(得分: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;
}
}
}
答案 2 :(得分:2)
aaron的简化版
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;
}
}
}
答案 3 :(得分:-1)
可以添加一些有趣(但不是很有用)的东西:来自委托的隐式转换:
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表达式不起作用,但是还有一件事会导致你的同事思考一下:)