Generic wrapper for System.Runtime.Caching.MemoryCache I have implemented a simple generic wrapper for MemoryCache class. Its interface looks like ConcurrentDictionary class but I tried to keep it simple. I tried to keep operations atomic, hoping not to break the thread-safety. Is there a mistake about thread-safety? I also want to know if I there are some boxing-unboxing issues I have to think about. Any suggestions about API or some other thing  is appreciated.

public interface IMemoryCacheWrapper&lt;T&gt;
{
    string Name { get; }
    long CacheMemoryLimitInBytes { get; }
    long PhysicalMemoryLimit { get; }
    TimeSpan PollingInterval { get; }
    CacheItemPolicy CacheItemPolicy { get; set; }
    void AddOrUpdate(string key, T value);
    bool TryGetValue(string key, out T value);
    bool TryRemove(string key, out T value);
    void Remove(string key);
    bool ContainsKey(string key);
    long Count { get; }
    void Dispose();
    bool IsDisposed { get; }
}


public class MemoryCacheWrapper&lt;T&gt; : IMemoryCacheWrapper&lt;T&gt;
{
    private readonly MemoryCache _memoryCache;
    private CacheItemPolicy _cacheItemPolicy;
    private bool _isDisposed;

    public MemoryCacheWrapper(string name, NameValueCollection config = null)
    {
        _memoryCache = config != null ? new MemoryCache(name, config) : new MemoryCache(name);
        _isDisposed = false;
        CacheItemPolicy = new CacheItemPolicy { SlidingExpiration = new TimeSpan(1, 0, 0) };
    }

    public string Name
    {
        get { return _memoryCache.Name; }
    }

    public long CacheMemoryLimitInBytes
    {
        get { return _memoryCache.CacheMemoryLimit; }
    }

    public long PhysicalMemoryLimit
    {
        get { return _memoryCache.PhysicalMemoryLimit; }
    }

    public TimeSpan PollingInterval
    {
        get { return _memoryCache.PollingInterval; }
    }

    public CacheItemPolicy CacheItemPolicy
    {
        get
        {
            return _cacheItemPolicy;
        }
        set
        {
            if (value != null)
            {
                _cacheItemPolicy = value;
            }
        }
    }

    public void AddOrUpdate(string key, T value)
    {
        _memoryCache.Set(key, value, CacheItemPolicy);
    }

    public bool TryGetValue(string key, out T value)
    {
        bool result = false;
        value = default(T);

        object item = _memoryCache.Get(key);
        if (item != null)
        {
            value = (T)item;
            result = true;
        }

        return result;
    }

    public bool TryRemove(string key, out T value)
    {
        bool result = false;
        value = default(T);

        object item = _memoryCache.Remove(key);
        if (item != null)
        {
            result = true;
            value = (T)item;
        }

        return result;
    }

    public void Remove(string key)
    {
        _memoryCache.Remove(key);
    }

    public bool ContainsKey(string key)
    {
        return _memoryCache.Contains(key);
    }

    public long Count
    {
        get { return _memoryCache.GetCount(); }
    }

    public void Dispose()
    {
        _memoryCache.Dispose();
        _isDisposed = true;
    }

    public bool IsDisposed
    {
        get { return _isDisposed; }
    }
}
When implementing the Dispose interface it is advisable to use a two stage clean up. So that when you use this not inside a using clause the garage collection can also work correctly.

Technically you can get away with it here; but I find it is useful to always use this pattern. Maintenance/Bug fixing then becomes easier as you do not need to start messing with other stuff just update the Dispose method. Another reason is that MS recommends this. 

    public ~MemoryCacheWrapper()
    {
        // Garbage collection has kicked in tidy up your object.
        Dispose(false);
    }

    // Implement IDisposable.
    public void Dispose()
    {
        // Dispose has been called clean up your object and members that
        // are disposable.
        Dispose(true);

        // Now Make sure that you don't call the cleanup again via the Finalizer
        // Effectively you are taking over garbage collection so make sure you
        // don't do it again
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        // Only do this once.
        if(!this._isDisposed)
        {
            // If called via IDispose interface then clean up sub-objects.
            // That implement the IDispose interface.
            if(disposing)
            {
                // Dispose managed resources.
                _memoryCache.Dispose();
            }

            // Now clean-up and objects that don't implement dispose.
            // i.e close any file handles 

            // Currently nothing to do.    
        }
        _isDisposed = true;         
    }