Это хорошо подходит для кэширования функций, описанных в этом моем блоге .Идея состоит в том, чтобы взять функцию с одним аргументом и превратить ее в другую функцию, которая кэширует результат исходного:
public static Func<TKey, TValue> Cached<TKey, TValue>(this Func<TKey, TValue> valueFunction)
{
var cache = new Dictionary<TKey, TValue>();
return key =>
{
TValue value;
if(!cache.TryGetValue(key, out value))
{
value = valueFunction(key);
cache[key] = value;
}
return value;
};
}
Словарь кеша внедряется в возвращаемое закрытие, поэтому он будет иметь тот жевремя жизни функции, которую мы возвращаем.
Вы бы использовали ее, заменив исходный вызов, чтобы получить данные новой функцией:
public class UsesTheDataType
{
private readonly Func<Foo, TheDataType> _generateData;
public UsesTheDataType()
{
_generateData = GenerateData;
_generateData = _generateData.Cached();
}
public void UseTheDataType(Foo foo)
{
var theDataType = _generateData(foo);
// theDataType is either a new value or cached value
}
private TheDataType GenerateData(Foo foo)
{
// Only called the first time for each foo
}
}
Приятная часть в том, что кеширование написаноодин раз для всех функций , так что вы можете использовать один и тот же подход независимо от того, что вам нужно для кеширования.Это также позволяет избежать возможных утечек памяти в результате использования статического кэша.
Это также может быть выполнено потокобезопасным способом.См. второй пост в серии для ознакомления.