MichaCo / CacheManager

CacheManager is an open source caching abstraction layer for .NET written in C#. It supports various cache providers and implements many advanced features.
http://cachemanager.michaco.net
Apache License 2.0
2.35k stars 456 forks source link

GetOrAdd API improvements to prevent wrong usage #212

Open MichaCo opened 6 years ago

MichaCo commented 6 years ago

There is currently an issue with the GetOrAdd API. In some scenarios, the generic overloads are ambiguous and lead to very odd error behavior which is not easy to spot.

See #152 for more details

Example: The following code actually compiles because ICacheManager<object> is used

_cache = CacheFactory.Build(c => c.WithDictionaryHandle());
var a = _cache.GetOrAdd("key", (k) => new CacheItem<int>(k, 1));

The factory method of GetOrAdd returns CacheItem<int> and not CacheItem<object> which is a user error. CacheItem<int> is be treated as object value because it doesn't match T = object and the TCacheValue GetOrAdd(string key, Func<string, TCacheValue> valueFactory) overload will be used.

Now, the GetOrAdd call would cache the CacheItem<int> instead of just the value 1. And it is not very obvious why this is.

Options to prevent this behavior:

  1. Remove the GetOrAdd overloads with factories taking CacheItem<T>. There are still TryGetOrAdd overloads which are more explicit and have the same functionality
  2. Rename those overloads to GetOrAddCacheItem

Both would be breaking changes although I don't think it would have a very big impact and should be fine.