在 .NET 4 中,还可以使用 System.Lazy<T>
编写以下带有缓存属性的代码片段类(class)。我测量了这两种方法的性能,结果几乎相同。为什么我应该使用一个而不是另一个有什么真正的好处或魔力吗?
缓存属性
public static class Brushes
{
private static LinearGradientBrush _myBrush;
public static LinearGradientBrush MyBrush
{
get
{
if (_myBrush == null)
{
var linearGradientBrush = new LinearGradientBrush { ...};
linearGradientBrush.GradientStops.Add( ... );
linearGradientBrush.GradientStops.Add( ... );
_myBrush = linearGradientBrush;
}
return _myBrush;
}
}
}
懒惰
public static class Brushes
{
private static readonly Lazy<LinearGradientBrush> _myBrush =
new Lazy<LinearGradientBrush>(() =>
{
var linearGradientBrush = new LinearGradientBrush { ...};
linearGradientBrush.GradientStops.Add( ... );
linearGradientBrush.GradientStops.Add( ... );
return linearGradientBrush;
}
);
public static LinearGradientBrush MyBrush
{
get { return _myBrush.Value; }
}
}
最佳答案
我会使用 Lazy<T>
一般而言:
- 它是线程安全的(在这种情况下可能不是问题,但在其他情况下会是)
- 仅通过名称就可以清楚地了解正在发生的事情
- 它允许 null 是一个有效值
请注意,您必须为委托(delegate)使用 lambda 表达式。例如,这是一种可能稍微更简洁的方法:
public static class Brushes
{
private static readonly Lazy<LinearGradientBrush> _myBrush =
new Lazy<LinearGradientBrush>(CreateMyBrush);
private static LinearGradientBrush CreateMyBrush()
{
var linearGradientBrush = new LinearGradientBrush { ...};
linearGradientBrush.GradientStops.Add( ... );
linearGradientBrush.GradientStops.Add( ... );
return linearGradientBrush;
}
public static LinearGradientBrush MyBrush
{
get { return _myBrush.Value; }
}
}
当创建过程因循环等而变得复杂时,这特别方便。请注意,从外观上看,您可以为 GradientStops
使用集合初始化程序。在您的创建代码中。
当然,另一种选择是不懒惰地执行此操作...除非您的类中有多个此类属性并且您只想逐一创建相关对象,您可以在许多情况下依赖惰性类初始化。
如 DoubleDown 的回答所述,没有办法重置它以强制重新计算(除非您将 Lazy<T>
字段设为非只读)——但我很少发现这很重要。
关于c# - 缓存属性与 Lazy<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5134786/