gpt4 book ai didi

c# - 使用对象作为键时.Net MemoryCache Miss

转载 作者:行者123 更新时间:2023-11-30 21:30:41 24 4
gpt4 key购买 nike

使用 IMemoryCache 时用object , TryGetValue总是想念。我想要一个 tuple<string, object>作为 key ,和一个 tuple<string, string>工作得很好。

这里的这段代码总是让我缓存未命中:

_cache.TryGetValue(("typeOfCache", query), out var something);
if(something == null) _cache.CreateEntry(("typeOfCache", query));

我正在使用的对象内部有列表列表,而不是没有字典/集合(没有随机排序的东西)。

这是 .net 错误还是我做错了什么?

最佳答案

MemoryCache 内部使用 ConcurrentDictionary<object, CacheEntry> ,它又使用 object 的默认比较器类型,它根据实际类型对 Object.Equals 的覆盖执行相等比较和 Object.GetHashCode .在您的情况下,您的 key 是 ValueTuple<string, Query> ,无论你的Query类(Class)群岛 ValueTuple<T1,T2>.Equals 如果比较实例的组件与当前实例的组件类型相同,并且组件与当前实例的组件相等,则计算结果为真,每个组件的默认相等比较器确定是否相等。

因此,相等比较的执行方式取决于 Query 的实现。类型。如果此类型不覆盖 EqualsGetHashCode , 也没有实现 IEquatable<T> ,然后执行引用相等性,这意味着您只有在传入查询的同一实例时才能获得相等性。如果你想改变这种行为,你应该扩展你的 Query要实现的类 IEquatable<Query> .

我还发现 CreateEntry不会立即将新条目添加到缓存中。 .NET Core 文档少得令人失望,所以我没有找到预期的行为;但是,您可以通过调用 Set 来确保添加条目相反。

例子:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Caching.Memory;

class Program
{
static void Main(string[] args)
{
var query1 = new Query { Parts = { new List<string> { "abc", "def", "ghi" } } };
var query2 = new Query { Parts = { new List<string> { "abc", "def", "ghi" } } };

var memoryCache = new MemoryCache(new MemoryCacheOptions());
memoryCache.Set(("typeOfCache", query1), new object());
var found = memoryCache.TryGetValue(("typeOfCache", query2), out var something);
Console.WriteLine(found);
}

public class Query : IEquatable<Query>
{
public List<List<string>> Parts { get; } = new List<List<string>>();

public bool Equals(Query other)
{
if (ReferenceEquals(this, other)) return true;
if (ReferenceEquals(other, null)) return false;
return this.Parts.Length == other.Parts.Length
&& this.Parts.Zip(other.Parts, (x, y) => x.SequenceEqual(y)).All(b => b);
}

public override bool Equals(object obj)
{
return Equals(obj as Query);
}

public override int GetHashCode()
{
return this.Parts.SelectMany(p => p).Take(10).Aggregate(17, (acc, p) => acc * 23 + p?.GetHashCode() ?? 0);
}
}
}

关于c# - 使用对象作为键时.Net MemoryCache Miss,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54044973/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com