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