I wish to use System.Runtime.Caching.MemoryCache
but I'm wondering how to use it with generics.
In the following example, I would be in trouble if T
is a value type.
public T GetItem<T>(string key, Func<T> loadItemFromDb)
{
var cachedItem = (T) memoryCache.Get(key);
if(cachedItem != null)
return cachedItem;
// call db
//put result in cache
// return result
}
MemoryCache.Get(string key)
returns null
if the cache entry identified by key
doesn't exist and it would raise NullReferenceException
as it tries to do (T)null
(with T
a value type)
How could I get similar behaviour for every T
?
EDIT : I removed where T : class
as this constraint prevents the case I'm describing.
EDIT 2 : I add some code to provide intent
The problem is that the cast can fail if the value is null. So don't cast if the value is null.
public T GetItem<T>(string key, Func<T> loadItemFromDb)
{
object cachedItem = memoryCache.Get(key);
if (cachedItem is T)
return (T)cachedItem;
T item = loadItemFromDb();
memoryCache.Add(key, item, somePolicy);
return item;
}
There's no problem with value types here; if T is a value type, and cachedItem
is not a boxed T
, then we never cast cachedItem
to T
.
FYI in C# 7 you can tighten that up a bit to:
if (cachedItem is T t)
return t;
and now there's no cast at all!