c# - 在 C# 记录中缓存昂贵的重新计算属性或字段
问题描述
我有一个像下面这样的 C# 记录,它的属性计算起来很昂贵:
sealed record MyAwesomeRecord(Dictionary<int, int> SomeDictionary)
{
public int ExpensiveToComputeProperty => SomeDictionary.Sum(e => e.Value);
//...
}
var original = new MyAwesomeRecord( new() { [0] = 0 });
var modified = original with { SomeDictionary = new() { [1] = 1 } };
我不想在每次访问时重新计算ExpensiveToComputeProperty
值,我只想在“构造”之后计算一次。但显然对于 C# 记录,构造函数在修改后不会再次调用with
. 我尝试了以下方法来解决这个问题:
- 改用正则
class
,但这样我就不能再使用with
我想继续使用的语法了。 - 将 存储
ExpensiveToComputeProperty
在常规属性或字段中。这不起作用,因为它被初始化一次,但不是在SomeDictionary
用with
. - AFAIK,有计划引入很好的语法,让我在 C# 10 中更新这个属性。不幸的是,C# 10 还没有出现。
有没有办法使用记录来避免重新进行昂贵的计算?
解决方案
您可以使用自定义设置器,而不是使用属性的默认设置器。在这个设置器中,您可以进行昂贵的计算。
这是一个完整的示例(经过测试和工作):
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
sealed record MyAwesomeRecord
{
public MyAwesomeRecord(Dictionary<int, int> SomeDictionary)
{
this.SomeDictionary = SomeDictionary;
}
public int ExpensiveToComputeProperty { get; private set; }
private Dictionary<int, int>? _SomeDictionary;
public Dictionary<int, int> SomeDictionary
{
get => _SomeDictionary!;
set
{
_SomeDictionary = value;
ExpensiveToComputeProperty = SomeDictionary.Sum(e => e.Value);
}
}
//...
}
class Program
{
static void Main()
{
var original = new MyAwesomeRecord(new() { [0] = 0 });
Console.WriteLine($"ExpensiveToComputeProperty = {original.ExpensiveToComputeProperty}");
var modified = original with { SomeDictionary = new() { [1] = 1 } };
Console.WriteLine($"ExpensiveToComputeProperty = {modified.ExpensiveToComputeProperty}");
}
}
}
推荐阅读
- java - 如何找到n次因子的因子
- r - 测量 R 中的峰值内存使用量
- predicate - Mountebank 使用了错误的谓词并忽略了 contains 中的值
- javascript - 按唯一键的最后一个索引过滤数组
- c++ - 不执行 C++ 类函数
- scala - 如何为 mutable.Map 中的键添加新元素?
- root-framework - 如何找到分支ROOT的积分
- c++ - 通过 C++ 模型在 QML 中设置主窗口数据
- reactjs - Material UI 自动完成:无法将嵌套数组数据填充为单独的标签选项
- swift - 无法启动具有 Carthage 依赖项的应用程序 (SnapKit)