缓存属性Getter中的密集计算

时间:2011-08-01 13:09:00

标签: c#

在以下代码中:

public class SomeClass
{
    // ... constructor and other stuff

    public in SomeProperty
    {
        get
        {
            return SomeHeayCalculation();
        }
    } 
}

我认为该类是不可变的,因此每次访问SomeProperty时,都应返回相同的值。我的问题是,是否有可能避免每次计算值。是否有一些内置的机制来缓存这些东西?

4 个答案:

答案 0 :(得分:16)

Yup - Lazy<T>,假设您使用的是.NET 4:

public class SomeClass
{
    private readonly Lazy<Foo> foo = new Lazy<Foo>(SomeHeayCalculation);
    // ... constructor and other stuff

    public Foo SomeProperty
    {
        get
        {
            return foo.Value;
        }
    } 
}

如果永远不会访问该属性,我假设您正在尝试避免执行计算。否则,只需在施工时预先执行。

请注意,属性通常被认为是“便宜”来评估 - 而当你使这个懒惰,以便以后访问是便宜的,这仍然可能会“足够”在第一次访问使一个属性不合适。请考虑使用ComputeXyz方法。

答案 1 :(得分:5)

只需将计算缓存在private variable中,如下所示:

public class SomeClass
{        
    // ... constructor and other stuff

    private int? calculation = null;

    public int SomeProperty
    {
        get
        {
            if (!calculation.HasValue)
                calculation = SomeHeayCalculation();

            return calculation.Value;
        }
    } 
}

答案 2 :(得分:2)

除了乔恩建议的,你可以使用这种模式:

public class SomeClass
{
    // ... constructor and other stuff
    private Foo _foo;

    public Foo SomeProperty
    {
        get
        {
            return _foo ?? (_foo = SomeHeayCalculation());
        }
    } 
}

值得注意的是,除非您想将它们包装在Nullable<T>中,否则这对于值类型确实会崩溃(读取:变得不那么可读)。在您的情况下,如果可用,您可能希望坚持使用Lazy<T>

答案 3 :(得分:1)

只需保留一个标记即可记住计算是否已完成。

public class SomeClass
{
    // ... constructor and other stuff

   private bool _propertyCalculated;
   private int _someProperty;

    public int SomeProperty
    {
        get
        {
            if (!_propertyCaculated)
            {
                _someProperty = SomeHeayCalculation();
                _propertyCaculated = true;
            }
            return _someProperty;
        }
    } 
}