Memoizer Class
Definition
Provides factory methods that wrap a function with a thread-safe cache, so each distinct argument is computed at most once and subsequent calls return the stored result.
public static class Memoizer
- Inheritance
-
Memoizer
- Inherited Members
Remarks
Results are cached in a ConcurrentDictionary<TKey, TValue>. Only successful results are stored: if the underlying function throws, nothing is cached and the next call retries. A null result is a valid cached value. For sequential use the function runs exactly once per distinct argument; under concurrent first access for the same argument the function may run more than once, but only one result is published.
Arguments are constrained to non-nullable types because they are used as dictionary keys. Memoizing a recursive function requires the function to call the memoized delegate for its recursive step.
The cache is unbounded and never evicts: every distinct argument's result is retained for the lifetime of the
memoized delegate. Memoizing a function over an unbounded argument domain therefore grows memory without limit; for
bounded caching with eviction, use EvictingDictionary<TKey, TValue> from the Bodu.Collections package
instead.
Methods
Memoize<TArg, TResult>(Func<TArg, TResult>)
Wraps a single-argument function with a cache that uses the default equality comparer for its argument.
public static Func<TArg, TResult> Memoize<TArg, TResult>(Func<TArg, TResult> func) where TArg : notnull
Parameters
funcFunc<TArg, TResult>The function to memoize.
Returns
- Func<TArg, TResult>
A memoizing wrapper around
func.
Type Parameters
TArgThe argument type.
TResultThe result type.
Examples
var square = Memoizer.Memoize<int, int>(n => ExpensiveSquare(n));
int a = square(8); // runs ExpensiveSquare
int b = square(8); // returns the cached result
Exceptions
- ArgumentNullException
funcis null.
Memoize<TArg, TResult>(Func<TArg, TResult>, IEqualityComparer<TArg>?)
Wraps a single-argument function with a cache that uses the specified equality comparer for its argument.
public static Func<TArg, TResult> Memoize<TArg, TResult>(Func<TArg, TResult> func, IEqualityComparer<TArg>? comparer) where TArg : notnull
Parameters
funcFunc<TArg, TResult>The function to memoize.
comparerIEqualityComparer<TArg>The comparer used to compare arguments, or null to use the default comparer.
Returns
- Func<TArg, TResult>
A memoizing wrapper around
func.
Type Parameters
TArgThe argument type.
TResultThe result type.
Examples
// Case-insensitive cache: "Hello" and "HELLO" resolve to one entry.
var lengthOf = Memoizer.Memoize<string, int>(s => s.Length, StringComparer.OrdinalIgnoreCase);
int x = lengthOf("Hello"); // computed
int y = lengthOf("HELLO"); // cache hit
Exceptions
- ArgumentNullException
funcis null.
Memoize<T1, T2, TResult>(Func<T1, T2, TResult>)
Wraps a two-argument function with a cache keyed on the pair of arguments.
public static Func<T1, T2, TResult> Memoize<T1, T2, TResult>(Func<T1, T2, TResult> func) where T1 : notnull where T2 : notnull
Parameters
funcFunc<T1, T2, TResult>The function to memoize.
Returns
- Func<T1, T2, TResult>
A memoizing wrapper around
func.
Type Parameters
T1The first argument type.
T2The second argument type.
TResultThe result type.
Examples
// Cache keyed on the (x, y) argument pair.
var add = Memoizer.Memoize<int, int, int>((x, y) => SlowAdd(x, y));
int s1 = add(3, 4); // computed
int s2 = add(3, 4); // cache hit
Exceptions
- ArgumentNullException
funcis null.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |