2011-08-01 101 views
6

在下面的代碼:在屬性getter緩存密集計算

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

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

我認爲類是不可變的,所以每次SomeProperty被訪問時,相同的值應返回。我的問題是,是否有可能避免每次計算值。是否有一些內置的緩存這種東西的機制?

回答

15

燁 - 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方法。

+0

我覺得他每次調用.SomeProperty時,都會檢索緩存版本,所以計算不必每次都做。 – 2011-08-01 13:12:14

+1

@ 0A0D:是的,這就是'懶惰'會做什麼。它會執行一次'SomeHeavyCalculation'(當'Value'被* first *訪問時),然後返回緩存的版本。 –

+0

噢好吧,我不明白你提供的鏈接。感謝您的澄清。 – 2011-08-01 13:14:03

2

除了什麼喬恩建議,您可以使用此模式:

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

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

值得一提的是,這真的打破了(讀:變得更可讀)值類型,除非你想包起來Nullable<T> 。在這種情況下,如果可能的話,您可能需要使用Lazy<T>

+3

如果null是一個有效的值,它也會中斷。 – Ray

+0

@射線:優點。 – Marc

4

只是緩存計算在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; 
     } 
    } 
} 
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; 
     } 
    } 
}