2009-08-07 30 views
1

我正在寻找一种方法来获得任何对象的通用本地缓存。这里是代码:类型安全的C#通用缓存

private static readonly Dictionary<Type,Dictionary<string,object>> _cache 
     = new Dictionary<Type, Dictionary<string, object>>(); 

    //The generic parameter allow null values to be cached 
    private static void AddToCache<T>(string key, T value) 
    { 
     if(!_cache.ContainsKey(typeof(T))) 
      _cache.Add(typeof(T),new Dictionary<string, object>()); 

     _cache[typeof (T)][key] = value; 
    } 

    private static T GetFromCache<T>(string key) 
    { 
     return (T)_cache[typeof (T)][key]; 
    } 

1-有没有办法不使用getfromcache方法?

2-有没有一种方法可以确保第二个字典中的类型安全,即所有的对象都有相同的类型。 (这是由addToCache方法提供的,但我更喜欢设计中的类型控制)。对于例如,有_cache以下类型的

Dictionary<Type,Dictionary<string,typeof(type)>> 

THX

回答

12

试试这个:

static class Helper<T> 
{ 
     internal static readonly Dictionary<string, T> cache = new Dictionary<string, T>(); 
} 
private static void AddToCache<T>(string key, T value) 
{ 
    Helper<T>.cache[key] = value; 
} 
private static T GetFromCache<T>(string key) 
{ 
    return Helper<T>.cache[key]; 
} 
+1

+1更好,因为每种类型现在都有自己的“名称空间”。缺点是,最好不要从多个线程中使用它。 – 2009-08-07 13:55:02

+1

那么,问题是关于类型安全性,而不是线程安全性。 公共静态方法通常应该是线程安全的,所以需要在这里添加锁。 – Daniel 2009-08-07 14:02:22

+0

我真的很喜欢这个解决方案! – Toto 2009-08-07 14:07:33

3

为什么不干脆把泛型参数和类声明:

public class Cache<T> 
{ 
    private Dictionary<string, T> _cache = new Dictionary<string, T>(); 
    ... 

} 

它可以如果您愿意,请保持静态

0

如果在编译时不知道所需的类型,将无法创建强类型的缓存。如果在运行时间之前您不知道所需的类型,那么您的问题的答案是否定的,恐怕。

1

除非原始类型没有装盒,否则你不会获得太多的收益。

private static readonly Dictionary<Type,Dictionary<string,object>> _cache 
    = new Dictionary<Type, IDictionary>(); 

//The generic parameter allow null values to be cached 
private static void AddToCache<T>(string key, T value) 
{ 
    // create a dictionary of the correct type 
    if(!_cache.ContainsKey(typeof(T))) 
     _cache.Add(typeof(T),new Dictionary<string, T>()); 

    _cache[typeof (T)][key] = value; 
} 

private static T GetFromCache<T>(string key) 
{ 
    // casting the dictionary instead of the value 
    Dictionary<string, T> typedDictionary = (Dictionary<string, T>)_cache[typeof (T)]; 
    return typedDictionary[key]; 
} 

当然,它需要更多未发现的处理。

+0

没必要,请参阅Daniel的答案。将一个静态字段放在一个泛型类中,它会自动成为一个有效类型值的字典。 – 2009-08-07 14:01:15

+0

这是真的,但然后你有一个静态字典,这并不总是适当的。 – 2009-08-07 14:11:40

0

应该可能在几个锁,也许几个克隆折腾...但这应该做的。

class Program 
{ 
    static void Main(string[] args) 
    { 
     CacheObject<int>.Instance["hello"] = 5; 
     CacheObject<int>.Instance["hello2"] = 6; 
     CacheObject<string>.Instance["hello2"] = "hi"; 
     Console.WriteLine(CacheObject<string>.Instance["hello2"]); //returns hi 
    } 
} 

public class CacheObject<V> : CacheObject<string, V> { } 
public class CacheObject<K,V> 
{ 
    private static CacheObject<K, V> _instance = new CacheObject<K, V>(); 
    public static CacheObject<K, V> Instance { get { return _instance; } } 

    private Dictionary<K, V> _store = new Dictionary<K, V>(); 
    public T this[K index] 
    { 
     get { return _store.ContainsKey(index) ? _store[index] : default(V); } 
     set 
     { 
      if (_store.ContainsKey(index)) _store.Remove(index); 
      if (value != null) _store.Add(index, value); 
     } 
    } 
} 
0

我必须把它扔掉,这看起来并不像你应该做的。无论你使用的是依赖注入/反转控制库,Enterprise Library CacheManager这样的工具,还是使用分布式内存缓存程序(如Memcache或Microsoft Velocity),都可能更好地实现。