Mon*_*der 8 c# hash caching dictionary
我决定在我们的一个应用程序中实现缓存外观 - 目的是最终减少网络开销并限制db命中量.我们正在使用Castle.Windsor我们IoC Container,我们决定Interceptors使用System.Runtime.Caching命名空间在我们的服务层之上添加缓存功能.
在这一刻,我无法弄清楚什么是构建它的最佳方法cache key.目标是区分不同的方法,并且还包括传递的参数值 - 这意味着这两个方法调用应该缓存在两个不同的键下:
IEnumerable<MyObject> GetMyObjectByParam(56); // key1
IEnumerable<MyObject> GetMyObjectByParam(23); // key2
Run Code Online (Sandbox Code Playgroud)
现在我可以看到两种可能的实现:
选项1: 装配| 班级| 方法返回类型| 方法名称| 参数类型| 参数哈希码
"MyAssembly.MyClass IEnumerable<MyObject> GetMyObjectByParam(long) { 56 }";
Run Code Online (Sandbox Code Playgroud)
选项2: MD5或SHA-256基于方法的完全限定名称和传递的参数值计算散列
string key = new SHA256Managed().ComputeHash(name + args).ToString();
Run Code Online (Sandbox Code Playgroud)
我正在考虑第一个选项,因为第二个选项需要更多的处理时间 - 另一方面,第二个选项强制执行所有生成的键的完全相同的"长度".
假设第一个选项将为使用复杂参数类型的方法生成唯一键是否安全?或者也许有一种完全不同的做法?
帮助和意见将受到高度赞赏!
基于我在这里和这里找到的一些非常有用的链接,我决定或多或少地实现它:
public sealed class CacheKey : IEquatable<CacheKey>
{
private readonly Type reflectedType;
private readonly Type returnType;
private readonly string name;
private readonly Type[] parameterTypes;
private readonly object[] arguments;
public User(Type reflectedType, Type returnType, string name,
Type[] parameterTypes, object[] arguments)
{
// check for null, incorrect values etc.
this.reflectedType = reflectedType;
this.returnType = returnType;
this.name = name;
this.parameterTypes = parameterTypes;
this.arguments = arguments;
}
public override bool Equals(object obj)
{
return Equals(obj as CacheKey);
}
public bool Equals(CacheKey other)
{
if (other == null)
{
return false;
}
for (int i = 0; i < parameterTypes.Count; i++)
{
if (!parameterTypes[i].Equals(other.parameterTypes[i]))
{
return false;
}
}
for (int i = 0; i < arguments.Count; i++)
{
if (!arguments[i].Equals(other.arguments[i]))
{
return false;
}
}
return reflectedType.Equals(other.reflectedType) &&
returnType.Equals(other.returnType) &&
name.Equals(other.name);
}
private override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 31 + reflectedType.GetHashCode();
hash = hash * 31 + returnType.GetHashCode();
hash = hash * 31 + name.GetHashCode();
for (int i = 0; i < parameterTypes.Count; i++)
{
hash = hash * 31 + parameterTypes[i].GetHashCode();
}
for (int i = 0; i < arguments.Count; i++)
{
hash = hash * 31 + arguments[i].GetHashCode();
}
return hash;
}
}
}
Run Code Online (Sandbox Code Playgroud)
基本上这只是一个一般性的想法 - 上面的代码可以很容易地重写为一个更通用的版本,其中包含一个集合Fields- 必须对集合的每个元素应用相同的规则。我可以分享完整的代码。
| 归档时间: |
|
| 查看次数: |
4655 次 |
| 最近记录: |