缓存属性VS懒< T> [英] Cached property vs Lazy<T>

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

问题描述

在.NET 4以下片段与缓存的性能,也可以使用<书面href="http://msdn.microsoft.com/en-us/library/dd642331%28VS.100%29.aspx"><$c$c>System.Lazy<T>类。我测量这两种方法的性能和它的pretty的大致相同。是否有任何实际的好处或魔术我为什么要使用一个比其他?

缓存属性

 公共静态类刷
{
    私有静态一个LinearGradientBrush _myBrush;

    公共静态一个LinearGradientBrush MyBrush
    {
        得到
        {
            如果(_myBrush == NULL)
            {
                VAR一个LinearGradientBrush =新一个LinearGradientBrush {...};
                linearGradientBrush.GradientStops.Add(...);
                linearGradientBrush.GradientStops.Add(...);

                _myBrush =一个LinearGradientBrush;
            }

            返回_myBrush;
        }
    }
}
 

延迟&LT; T&GT;

 公共静态类刷
{
    私人静态只读懒&LT;一个LinearGradientBrush&GT; _myBrush =
        新的懒惰&LT;一个LinearGradientBrush&GT;(()=&GT;
            {
                VAR一个LinearGradientBrush =新一个LinearGradientBrush {...};
                linearGradientBrush.GradientStops.Add(...);
                linearGradientBrush.GradientStops.Add(...);

                返回一个LinearGradientBrush;
            }
        );

    公共静态一个LinearGradientBrush MyBrush
    {
        {返回_myBrush.Value; }
    }
}
 

解决方案

我会使用延迟&LT; T&GT; 一般:

  • 这是线程安全的(可能无法在这种情况下的问题,但会在其他国家)
  • 这使得很明显是怎么回事只是名字
  • 在它允许空是一个有效的值

请注意,你不的有无的使用lambda EX pression的委托。例如,下面是这可能会稍微更清洁的方法:

 公共静态类刷
{
    私人静态只读懒&LT;一个LinearGradientBrush&GT; _myBrush =
        新的懒惰&LT;一个LinearGradientBrush&GT;(CreateMyBrush);

    私有静态一个LinearGradientBrush CreateMyBrush()
    {
        VAR一个LinearGradientBrush =新一个LinearGradientBrush {...};
        linearGradientBrush.GradientStops.Add(...);
        linearGradientBrush.GradientStops.Add(...);

        返回一个LinearGradientBrush;
    }

    公共静态一个LinearGradientBrush MyBrush
    {
        {返回_myBrush.Value; }
    }
}
 

这是特别方便,当创建过程变得复杂与循环等。请注意,它的外观,你可以在你的创作$使用一个集合初始化为 GradientStops C $℃。

另一种选择是的没有的做到这一点懒洋洋的,当然......除非你在你们班几个这样的特性,你只需要在一个接一个的基础上创建相关对象,你可以依靠懒惰类的初始化对于许多情况。

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?

Cached Property

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;
        }
    }
}

Lazy<T>

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; }
    }
}

解决方案

I would use Lazy<T> in general:

  • It's thread-safe (may not be an issue in this case, but would be in others)
  • It makes it obvious what's going on just by the name
  • It allows null to be a valid value

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; }
    }
}

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.

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

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