Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot implicitly convert type 'T' to 'T

I'm writing a fluent registration for a cache provider, but for some reason my generics are not happy. I'm getting an error on this bit: value = _loadFunction();

Cannot implicitly convert type 'T' to 'T [HttpRuntimeCache.cs(10)]

Code Below:

using IDM.CMS3.Service.Cache;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Caching;

namespace IDM.CMS3.Web.Public.CacheProviders
{
    public class HttpRuntimeCache<T> : IFluentCacheProvider<T>
    {
        string _key;
        Func<T> _loadFunction;
        DateTime? _absoluteExpiry;
        TimeSpan? _relativeExpiry;

        public HttpRuntimeCache()
        {

        }

        public IFluentCacheProvider<T> Key(string key)
        {
            _key = key;
            return this;
        }

        public IFluentCacheProvider<T> Load(Func<T> loadFunction)
        {
            _loadFunction = loadFunction;
            return this;
        }

        public IFluentCacheProvider<T> AbsoluteExpiry(DateTime absoluteExpiry)
        {
            _absoluteExpiry = absoluteExpiry;
            return this;
        }

        public IFluentCacheProvider<T> RelativeExpiry(TimeSpan relativeExpiry)
        {
            _relativeExpiry = relativeExpiry;
            return this;
        }

        public T Value()
        {
            return FetchAndCache<T>();
        }

        public void InvalidateCacheItem(string cacheKey)
        {
            throw new NotImplementedException();
        }

        T FetchAndCache<T>()
        {
            T value;
            if (!TryGetValue<T>(_key, out value))
            {
                value = _loadFunction();
                if (!_absoluteExpiry.HasValue)
                    _absoluteExpiry = Cache.NoAbsoluteExpiration;

                if (!_relativeExpiry.HasValue)
                    _relativeExpiry = Cache.NoSlidingExpiration;

                HttpContext.Current.Cache.Insert(_key, value, null, _absoluteExpiry.Value, _relativeExpiry.Value);

            }
            return value;
        }

        bool TryGetValue<T>(string key, out T value)
        {
            object cachedValue = HttpContext.Current.Cache.Get(key);
            if (cachedValue == null)
            {
                value = default(T);
                return false;
            }
            else
            {
                try
                {
                    value = (T)cachedValue;
                    return true;
                }
                catch
                {
                    value = default(T);
                    return false;
                }
            }
        }
    }
}
like image 789
Jason More Avatar asked Jun 21 '26 22:06

Jason More


1 Answers

The T FetchAndCache<T> and bool TryGetValue<T> are redefining a new T type separate from the one declared on the class level. I think once you remove the extra generic declaration it should work fine. That is, rewrite them to be:

T FetchAndCache()
{
     ...
}

bool TryGetValue(string key, out T value)
{
     ...
}

Once you do that, the compiler will recognize the T here as the one declared on the class.

like image 156
Chris Sinclair Avatar answered Jun 24 '26 12:06

Chris Sinclair