我有一个用属性填充的类。当访问属性时,它从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就是为了不复制大部分代码,有没有办法让它像这样自动工作?
发布于 2010-08-10 21:01:49
正如"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); }
}
}这样,每个属性最终都相当紧凑-它基本上表达了所涉及的缓存键,以及如何计算属性。如果您需要不同类型的属性,您可能希望缓存只使用TValue作为object,并使Fetch方法成为泛型,在必要时进行强制转换。无可否认,这最终将封装值类型。
如果您在多个地方使用此方法,您可能希望创建一个通用的ComputingCache类,以避免重复该逻辑。
发布于 2010-08-10 20:57:58
将属性保存在枚举中,并将值缓存在哈希表中。提供单个属性访问器。
未测试:
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);发布于 2010-08-10 21:05:33
如果你使用的是.NET 4.0,你可以使用handy Lazy类。
http://weblogs.asp.net/gunnarpeipman/archive/2009/05/19/net-framework-4-0-using-system-lazy-lt-t-gt.aspx
如果你使用的是以前版本的框架,你可以编写你自己版本的Lazy类(它并不是特别复杂)。
https://stackoverflow.com/questions/3449114
复制相似问题