I have a wrapper around Cache library and have the following method to retrieve the cached valued based on Key:
public async Task<T> GetAsync<T>(string key)
{
var serializedObject = await _cache.GetStringAsync(key);
return JsonConvert.DeserializeObject<T>(serializedObject);
}
The problem is there is nothing in cache, I receive an error from the DeserializeObject method. I'm stuck on what how to return either null or the default value of T when nothing is stored cache.
I tried:
public async Task<T> GetAsync<T>(string key)
{
var serializedObject = await _cache.GetStringAsync(key);
if (serializedObject == null) return Task.CompletedTask;
return JsonConvert.DeserializeObject<T>(serializedObject);
}
But Task.CompletedTask cannot be converted to Task<T>
I tried:
public async Task<T> GetAsync<T>(string key)
{
var serializedObject = await _cache.GetStringAsync(key);
if (serializedObject == null) return Task.FromResult<T>(null);
return JsonConvert.DeserializeObject<T>(serializedObject);
}
But null is not a valid parameter for T.
How do I get GetAsync to return either null or the default value of T?
Update
I got the following to work:
public async Task<T> GetAsync<T>(string key)
{
var serializedObject = await _cache.GetStringAsync(key);
return serializedObject == null ? default(T) : JsonConvert.DeserializeObject<T>(serializedObject);
}
You have three options:
T : class
constraintThe first implementation lets your approach compile:
public async Task<T> GetAsync<T>(string key) where T : class {
var serializedObject = await _cache.GetStringAsync(key);
if (serializedObject == null) {
return await Task.FromResult<T>(null);
}
return JsonConvert.DeserializeObject<T>(serializedObject);
}
Here is the second implementation:
class CacheResult<T> {
public bool IsSuccess {get;}
public T Value {get;}
public CacheResult(T val, bool isSuccess) {
Value = val;
IsSuccess = isSuccess;
}
}
public async Task<CacheResult<T>> GetAsync<T>(string key) {
var serializedObject = await _cache.GetStringAsync(key);
if (serializedObject == null) {
return new CacheResult(default(T), false);
}
return new CacheResult(
JsonConvert.DeserializeObject<T>(serializedObject)
, true
);
}
Here is the third implementation:
public async Task<T> GetAsync<T>(string key, Func<string,T> make) {
var serializedObject = await _cache.GetStringAsync(key);
if (serializedObject == null) {
var res = make(key);
_cache.PutStringAsync(key, JsonConvert.SerializeObject(res));
return res;
}
return JsonConvert.DeserializeObject<T>(serializedObject);
}
The caller would need to provide a "factory" delegate to the second method in order to make a new object if a cached one is not available.
Have you tried this?
return default(T);
Because you're returning the default value of T
, you might as well return it synchronously.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With