.NET 7中如何获取MemoryCache的所有键?
在.NET 7中获取MemoryCache所有键的替代方案
由于.NET 7移除了EntriesCollection私有属性,原先通过反射获取该属性的方法已失效。以下是两种可行的解决方式:
1. 自行维护缓存键集合(推荐)
这种方式不依赖MemoryCache的内部实现,稳定性最高。在添加/删除缓存时同步维护一个键集合,同时利用缓存过期回调自动清理失效的键:
public class TrackedMemoryCache { private readonly MemoryCache _innerCache; private readonly ConcurrentDictionary<object, object> _cacheKeys = new(); public TrackedMemoryCache(MemoryCacheOptions options) { _innerCache = new MemoryCache(options); } public void Set<TKey, TValue>(TKey key, TValue value, MemoryCacheEntryOptions entryOptions) { _innerCache.Set(key, value, entryOptions); _cacheKeys.TryAdd(key, null); // 注册回调,缓存过期/移除时同步删除键 entryOptions.RegisterPostEvictionCallback((evictedKey, _, reason, _) => { if (reason != EvictionReason.Replaced) { _cacheKeys.TryRemove(evictedKey, out _); } }); } public IEnumerable<object> GetAllKeys() { return _cacheKeys.Keys; } // 根据需要封装Get、Remove等其他MemoryCache方法 }
2. 通过反射访问新的内部字段(不推荐)
.NET 7之后,MemoryCache内部改用_entries字段存储缓存项,类型为ConcurrentDictionary<object, CacheEntry>。可以通过反射获取该字段来提取键,但此方法依赖内部实现,后续版本可能再次失效:
using System.Reflection; public static IEnumerable<object> GetMemoryCacheKeys(MemoryCache cache) { var entriesField = typeof(MemoryCache).GetField( "_entries", BindingFlags.NonPublic | BindingFlags.Instance); if (entriesField == null) throw new InvalidOperationException("无法访问MemoryCache的内部_entries字段"); var entriesDict = entriesField.GetValue(cache) as ConcurrentDictionary<object, object>; return entriesDict?.Keys ?? Enumerable.Empty<object>(); }
注意:反射方式存在兼容性风险,微软可能在后续.NET版本中修改内部字段名或结构,优先使用自行维护键集合的方案。
内容的提问来源于stack exchange,提问作者EaxZone
相关产品推荐
相关产品推荐

