Pet*_*rdk 37 c# caching properties
我有一个对象,其属性的计算成本很高,因此它们仅在首次访问时计算,然后进行缓存.
private List<Note> notes;
public List<Note> Notes
{
get
{
if (this.notes == null)
{
this.notes = CalcNotes();
}
return this.notes;
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道,有更好的方法吗?是否有可能在C#中创建一个Cached属性或类似的东西?
xyz*_*xyz 23
就语法而言,如果你想要花哨,你可以使用null-coalescing运算符,但它不一定是可读的.
get
{
return notes ?? (notes = CalcNotes());
}
Run Code Online (Sandbox Code Playgroud)
编辑:马修更新了礼貌.另外,我认为其他答案对提问者更有帮助!
Ree*_*sey 21
在.NET 3.5或更早版本中,您拥有的是非常标准的实践和精细的模型.
(虽然,我建议返回IList<T>,或者IEnumerable<T>如果可能的话,而不是List<T>在您的公共API中 - List<T>应该是一个实现细节......)
但是,在.NET 4中,有一个更简单的选项:Lazy<T>.这可以让你做到:
private Lazy<IList<Note>> notes;
public IEnumerable<Note> Notes
{
get
{
return this.notes.Value;
}
}
// In constructor:
this.notes = new Lazy<IList<Note>>(this.CalcNotes);
Run Code Online (Sandbox Code Playgroud)
问题??是,如果CalcNotes()返回,null那么它将不再被缓存.值类型同上举例来说,如果既0和NaN被允许作为属性值.
更好的是一个"面向方面"的解决方案,像Post - Sharp使用属性然后修改MSIL(字节码).
代码看起来像:
[Cached]
public List<Note> Notes { get { return CalcNotes(); } }
Run Code Online (Sandbox Code Playgroud)
编辑: CciSharp.LazyProperty.dll正是这样做的!
使用 C# 8 和空合并赋值的两行选项:
private List<Note>? notes;
public List<Note> Notes => notes ??= CalcNotes();
Run Code Online (Sandbox Code Playgroud)