C# 属性Getter中的缓存密集型计算
在以下代码中:C# 属性Getter中的缓存密集型计算,c#,C#,在以下代码中: public class SomeClass { // ... constructor and other stuff public in SomeProperty { get { return SomeHeavyCalculation(); } } } 我认为类是不可变的,因此每次访问某个属性< /C>时,都应该返回相同的值。我的问题是,是否有可能避免每次计算该值。是否
public class SomeClass
{
// ... constructor and other stuff
public in SomeProperty
{
get
{
return SomeHeavyCalculation();
}
}
}
我认为类是不可变的,因此每次访问<代码>某个属性< /C>时,都应该返回相同的值。我的问题是,是否有可能避免每次计算该值。是否有一些内置的机制来缓存这些东西?
是的,假设您使用的是.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;
}
}
}
公共类SomeClass
{
private readonly Lazy foo=新的Lazy(SomeHeayCalculation);
//…构造函数和其他东西
公共餐饮酒店
{
得到
{
返回foo.Value;
}
}
}
我假设您试图避免在从未访问该属性时执行计算。否则,只需在构建时预先执行它
请注意,属性的评估通常被理解为“便宜”——虽然您将此设置为懒惰,以便以后的访问便宜,但在第一次访问时,此设置仍然可能“沉重”,足以使属性变得不合适。请考虑<代码> CytExxz 方法。< P> >乔恩建议的以外,您可以使用这种模式:
public class SomeClass
{
// ... constructor and other stuff
private Foo _foo;
public Foo SomeProperty
{
get
{
return _foo ?? (_foo = SomeHeayCalculation());
}
}
}
值得注意的是,对于值类型,这确实会发生故障(读取:变得不那么可读),除非您想将它们包装在
Nullable
中。在这种情况下,如果可用,您可能希望坚持使用Lazy
。只需将计算缓存在私有变量中,如下所示:
public class SomeClass
{
// ... constructor and other stuff
private int? calculation = null;
public int SomeProperty
{
get
{
if (!calculation.HasValue)
calculation = SomeHeayCalculation();
return calculation.Value;
}
}
}
只需保留一个标志,以记住是否已完成计算
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;
}
}
}
我想他的意思是每次调用.SomeProperty来检索缓存的版本,这样就不必每次都进行计算了。@0A0D:是的,Lazy
就是这样做的。它将执行SomeHeavyCalculation
一次(当第一次访问Value
时),然后返回缓存版本。哦,好的,我从您提供的链接中不理解这一点。感谢您的澄清。它看起来比在类中将结果保存为私有标志和变量的想法更简洁,但仍然不是完美的。我希望你能在你想要缓存的方法上加上一个注释。@Artium:那是不存在的。。。至少不在core.NET中。不要忘记,这意味着属性将不得不向类中添加字段……如果null是有效值,它也会中断。