缓存属性 vs Lazy<T> [英] Cached property vs Lazy&lt;T&gt;

查看:29
本文介绍了缓存属性 vs Lazy<T>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 .NET 4 中,也可以使用 System.Lazy 类.我测量了两种方法的性能,结果几乎相同.为什么我应该使用一个而不是另一个有什么真正的好处或魔力?

In .NET 4 the following snippet with a cached property can also be written using the System.Lazy<T> class. I measured the performance of both approaches and it's pretty much the same. Is there any real benefit or magic for why I should use one over the other?

缓存属性

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:

  • 它是线程安全的(在这种情况下可能不是问题,但在其他情况下会出现问题)
  • 从名字就可以看出发生了什么
  • 它允许 null 为有效值

请注意,您不必为委托使用 lambda 表达式.例如,这里有一种可能更简洁的方法:

Note that you don't have to use a lambda expression for the delegate. For example, here's an approach which may be slightly cleaner:

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 使用集合初始值设定项.

This is particularly handy when the creation process gets complicated with loops etc. Note that by the looks of it, you could use a collection initializer for GradientStops in your creation code.

另一个选择是不要懒惰地这样做,当然...除非你的类中有几个这样的属性并且你只想一个一个地创建相关对象,您可以在许多情况下依赖惰性类初始化.

Another option is not to do this lazily, of course... unless you have several such properties in your class and you only want to create the relevant objects on a one-by-one basis, you could rely on lazy class initialization for many situations.

正如 DoubleDown 的回答中所指出的,没有办法重置它以强制重新计算(除非您将 Lazy<T> 字段设为非只读) - 但我很少发现这很重要.

As noted in DoubleDown's answer, there's no way of resetting this to force recomputation (unless you make the Lazy<T> field not readonly) - but I've very rarely found that to be important.

这篇关于缓存属性 vs Lazy<T>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆