2010-08-10 83 views
1

我有一個類充滿了屬性。當訪問屬性時,它從XDocument中讀取一些值。'緩存'屬性

public class Foo 
{ 
private XDocument root; 

public Foo(Stream str) 
{ 
    root = XDocument.load(str); 
} 

public String Bar 
{ 
    get 
    { 
    return root.Element("bar").Value; 
    } 
} 

} 

只是看起來有些開銷,因爲每次訪問它都必須再次讀取XDocument。我試圖'緩存'這一點如下

public String Bar 
{ 
get 
{ 
    if(String.IsNullOrEmpty(this.Bar)) 
    return root.Element("bar").Value; 
    else 
    return this.Bar; 
} 
} 

這對我來說似乎很不錯,只有我有一個問題。這個班有〜200個屬性。每次我必須做這個檢查,並且由於OOP是關於不復制大部分代碼的,有沒有什麼辦法可以使這個工作自動完成?

+1

你確定你沒有過早地優化它嗎? – Marc 2010-08-10 13:02:45

+0

不,實際上我不是:P – 2010-08-10 14:07:50

回答

4

如前所述 「thelost」,沒有一個單一領域的每個屬性。將字典保存爲緩存,因此您不會爲任何未訪問的屬性支付任何費用。

我會建議你有一個方法,你可以提供與檢索真正價值的機制。例如:

public class Foo 
{ 
    private enum CacheKey 
    { 
     Bar, Baz, ...; 
    } 

    private readonly XDocument doc; 
    private readonly Dictionary<CacheKey, string> cache; 

    private string Fetch(CacheKey key, Func<XDocument, string> computation) 
    { 
     string result; 
     if (!cache.TryGetValue(key, out result)) 
     { 
      result = computation(doc); 
      cache[key] = result; 
     } 
     return result; 
    } 

    public string Bar 
    { 
     get { return Fetch(CacheKey.Bar, doc => doc.Element("bar").Value); } 
    } 
} 

這樣,每個屬性結束了緊湊合理 - 這基本上表示所涉及的緩存鍵,以及如何計算該屬性。如果您需要不同類型的屬性,則可能需要緩存的TValueobject,並使Fetch方法爲通用,並在必要時進行轉換。無可否認,這最終會導致拳擊價值類型。

如果您在幾個地方使用此方法,您可能需要創建一個通用ComputingCache類以避免重複邏輯。

2

保留enum中的屬性並將值緩存在散列表中。提供一個屬性訪問器。

沒有測試:

enum MyProperties { 
    Prop1, 
    Prop2 
} 

// ... 

static class PropertyProvider { 
    static Hashtable<MyProperties, Object> cache = new Hashtable<MyProperties, Object>(); 
    static Object getProperty(MyProperties prop) { 
     if (!cache.ContainsKey(prop)) { 
      cache.add(prop, "SOMETHING"); 
     } 

     return cache[prop]; 
    } 
} 

// ... 

Object result = PropertyProvider.getProperty(MyProperties.Prop1); 
1

是懶惰部分重要嗎?如果沒有,只需在ctor時間填入所有屬性(它們都可以是自動的),然後就完成了。我寧願這樣做,因爲如果xml出現問題,它會更快地失敗。如果懶惰很重要,那麼在.NET 4中,您可以使用Lazy。

請注意,無論您使用哪種緩存方法,請確保1)您的getter沒有堆棧溢出問題,並且2)填充緩存條目時,空/缺失值仍然被認爲是有效的(如果的確如此源xml)