C#,为一个对象数组生成一个常量Key

时间:2018-03-13 20:01:16

标签: c# valueconverter

我想在Cache中保存一个带有常量Key的对象。

myextension/Private/Resources/Private/Forms/contactForm.yaml

finishers:
  -
    options:
      message: 'Thanks for the enquiry.'
    identifier: Confirmation

我通过以下函数获取对象:

    public TItem Set<TItem>(string key, TItem value)
    {
        return = _memoryCache.Set(key, value);
    }

我想为TItem,Id(int)和一些params(object [] args)生成一个常量键。

这是我生成常量键的函数:

    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;
    }

[功能调用] 是我正在寻找的功能。

因此,下次我使用相同的参数调用该函数时,我将使用相同的密钥。

例如

    internal static string GetKey<TItem>(int id, params object[] args)
    {
        return string.Format("{0}#{1}[{2}]", typeof(TItem).FullName, id, args?[FUNCTION TO CALL]);
    }

一开始,我想使用GetHashCode,但生成的int总是不同的。

我该怎么做?

1 个答案:

答案 0 :(得分:0)

我认为GetHashCode是你需要的;你是在数组上调用GetHashCode,还是在数组的每个成员上调用它?你想做后者。

以下内容应与您想要的类似;如果params为null或为空,或者为空对象,那么代码将为00000000。

否则,如果params相同,则生成的散列将是相同的。如果params处于不同的顺序或不同的值,那么哈希将是不同的。

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实现。