属性获取器中的缓存密集型计算

本文关键字:缓存 密集型 计算 获取 属性 | 更新日期: 2023-09-27 18:04:22

在以下代码中:

public class SomeClass
{
    // ... constructor and other stuff
    public in SomeProperty
    {
        get
        {
            return SomeHeavyCalculation();
        }
    } 
}

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

属性获取器中的缓存密集型计算

Yup-Lazy<T>,假设您正在使用。网络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方法。

只需将计算缓存在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;
        }
    } 
}

除了Jon建议的以外,您还可以使用以下模式:

public class SomeClass
{
    // ... constructor and other stuff
    private Foo _foo;
    public Foo SomeProperty
    {
        get
        {
            return _foo ?? (_foo = SomeHeayCalculation());
        }
    } 
}

值得注意的是,对于值类型,这确实会分解(读:变得不那么可读(,除非您想将它们封装在Nullable<T>中。在这种情况下,如果有Lazy<T>,您可能需要继续使用。

只要保留一个标志来记住计算是否已经完成。

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