c# - 缓存属性与 Lazy<T>

标签 c# .net .net-4.0 lazy-loading

在 .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/

相关文章:

c# - C# 函数中的 SQL COALESCE UPDATE

c# - c#中的条件确认框

c# - DDD - 实体状态转换

c# - 从数据库中检索更新的数据

c# - .net 中的字符大小不符合预期?

model-view-controller - 操作参数显示在查询字符串而不是 URL 中

c# - C# : using -= operator by events? 是什么意思

c# - NSubstitute:能够在没有返回类型的模拟方法中设置引用对象

c# - 解决方案范围 app.config/web.config?

c# - WPF DispatcherTimer 和鼠标按钮单击计时