Skip to content

Make Microsoft.Extensions.Caching.Memory.MemoryCache support generics #54771

Closed

Description

Background and Motivation

We use MemoryCache extensively in our project and found that MemoryCache could greatly benefit from 2 features:

  1. Most of the times we use strings as keys, and look ups are mostly case insensitive. If an IEqualityComparer can be supported then we can avoid a lot of unnecessary allocations by normalizing the casing of strings
  2. Sometimes we use value types (int) as keys; since MemoryCache forces keys to be objects right now there are a lot of unnecessary boxing costs

Making MemoryCache support generics can solve both issues, since we can enforce TKey to be IEquatable

Proposed API

To fully preserve backward compatibility, we can make a generic interface, and make original MemoryCache implement that generic interface:

namespace Microsoft.Extensions.Caching.Memory
{
+    public interface IMemoryCache<TKey, TValue> : IDisposable {
     }
namespace Microsoft.Extensions.Caching.Memory
{
-    public interface IMemoryCache : IDisposable {
+    public interface IMemoryCache : IMemoryCache<object, object> {
     }
namespace Microsoft.Extensions.Caching.Memory
{
+    public class MemoryCache<TKey, TValue> : IMemoryCache<TKey, TValue> where TKey : IEquatable<TKey> {
     }
namespace Microsoft.Extensions.Caching.Memory
{
     public interface MemoryCache : IMemoryCache {
     }

Usage Examples

var cache = new MemoryCache<string, string>(cacheOptions, comparer: StringComparer.OrdinalIgnoreCase);
cache["key"] = "value";
// Now this returns "value" as well
var value = cache["KEY"];
var cache = new MemoryCache<long, string>(cacheOptions);
// No more boxing
cache["value".GetHashCode()] = "value";

Alternative Designs

N/A

Risks

The only risk is that this can potentially produce significant memory pressure if a consumer has a large number of different concrete MemoryCache<> types. Considering common usages of this cache, it is highly unlikely (Please correct me if I am wrong).

I am glad to help publish a PR for the proposed change as we would love to consume it if the design is approved!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions