我想在缓存中保存一个具有常量键的对象。
public TItem Set<TItem>(string key, TItem value)
{
return = _memoryCache.Set(key, value);
}
我用这样的函数获取我的对象:
public TItem Get(
TPrimaryKey id,
params object[] args,
bool byPassCaching = false
)
{
if (byPassCaching || !_cacheManager.TryGetValue<TItem>(GetKey(id, args), out TItem result)){
item = [FUNCTION TO GET ITEM];
_cacheManager.Set(GetKey(id, args), item)
}
return item;
}
我想为 TItem、Id (int( 和一些参数(object[] args(生成一个常量键。
这是我生成常量键的函数:
internal static string GetKey<TItem>(int id, params object[] args)
{
return string.Format("{0}#{1}[{2}]", typeof(TItem).FullName, id, args?[FUNCTION TO CALL]);
}
[要调用的函数]是我正在寻找的函数。
所以下次我使用相同的参数调用函数时,我将使用相同的键。
例如
GetKey<MyClass>(1, null) => "MyApp.MyClass#1[]"
GetKey<MyClass>(1, "Hello", "World") => "MyApp.MyClass#1[sdas5d1as5d4sd8]"
GetKey<MyClass>(1, "Hello", "World") => "MyApp.MyClass#1[sdas5d1as5d4sd8]"
GetKey<MyClass>(1, item => item.Include(s => s.Categories)) => "MyApp.MyClass#1[asdasdasd87wqw]"
一开始,我想使用 GetHashCode,但生成的 int 总是不同的。
我该怎么做?
是你需要的;你是在数组上调用GetHashCode,还是在数组的每个成员上调用它?你想做后者。
以下内容应该类似于您想要的;如果参数为 null 或空,或者充满了 null 对象,则代码将为 00000000。
否则,如果参数相同,则生成的哈希将相同。如果参数的顺序或值不同,那么哈希值就会不同。
internal static string GetKey<TEntity>(int id, params object[] args)
{
return string.Format("{0}#{1}[{2}]", typeof(TEntity).FullName, id, ArrayHash(args));
}
static string ArrayHash(params object[] values)
{
return BitConverter.ToString(BitConverter.GetBytes(ArrayHashCode(values))).Replace("-", "").ToLowerInvariant();
}
static int ArrayHashCode(params object[] values)
{
if (values == null || values.Length == 0) return 0;
var value = values[0];
int hashCode = value == null ? 0 : value.GetHashCode();
for (int i = 1; i < values.Length; i++)
{
value = values[i];
unchecked
{
hashCode = (hashCode * 397) ^ (value == null ? 0 : value.GetHashCode());
}
}
return hashCode;
}
请注意,397 是我从 ReSharper 的 GetHashCode 实现中获取的质数,允许通过溢出很好地分发哈希代码(未选中的块优雅地允许(。
散列参数的示例如下所示:
ArrayHash( 1, null, "test" ) => "dee9e1ea"
ArrayHash( 1, null, "test" ) => "dee9e1ea"
ArrayHash( null, 1, "test" ) => "fa8fe3ea"
ArrayHash("one", "two", "three") => "8841b2be"
ArrayHash() => "00000000"
ArrayHash(null) => "00000000"
ArrayHash(new object[] {}) => "00000000"
请注意,如果 params 数组包含对象,它们也需要具有适当的 GetHashCode 实现。