Cache wrapper - Generics vs Dynamic I've implemented a common wrapper pattern I've seen for the .NET cache class using generics as follows:

private static T CacheGet&lt;T&gt;(Func&lt;T&gt; refreashFunction, [CallerMemberName]string keyName = null)
{
    if (HttpRuntime.Cache[keyName] == null)
        HttpRuntime.Cache.Insert(keyName, refreashFunction(), null, DateTime.UtcNow.AddSeconds(600), System.Web.Caching.Cache.NoSlidingExpiration);
    return (T)HttpRuntime.Cache[keyName];
}


It could then be called like so:

public static Dictionary&lt;string, string&gt; SomeCacheableProperty
{
    get
    {
        return CacheGet(() =&gt;
        {
            Dictionary&lt;string, string&gt; returnVal = AlotOfWork();
            return returnVal;
        });
    }
}


However, the CacheGet method could be implemented using dynamic:

private static dynamic CacheGet(Func&lt;object&gt; refreashFunction, [CallerMemberName]string keyName = null)
{
    if (HttpRuntime.Cache[keyName] == null)
        HttpRuntime.Cache.Insert(keyName, refreashFunction(), null, DateTime.UtcNow.AddSeconds(600), System.Web.Caching.Cache.NoSlidingExpiration);
    return HttpRuntime.Cache[keyName];
}


The questions I have:


Is there a technically (or philosophically) superior preference between these two implementations?
Are these different at runtime?
If they are both left in, which one is being called in the getter method?
First of all, I think you misspelled refresh as refreash.
Second, your usage can probably be simplified
CacheGet(AlotOfWork);

Finally, you might want to check if refreshFunction returns null and maybe log a warning then as that function returning null would cause a cache miss every time.
Now to answer your specific questions.

I'll say it, the generic implementation is better. dynamic is a great trapdoor when you get really bogged down with generics or anonymous types and there's neat things you can do with it (see Dapper) but it still has some gotchas. For example, I do not think your function with dynamic will work in most cases.
HttpRuntime.Cache expects and returns object types meaning all types are being downcast or boxed. Therefore, if your function returns a User object, what is stored is still an object and what is returned from the cache is downcast likewise. Therefore your user.Username property will not be available until you cast, even though it's dynamic.

Yes. The generic version - with some subtle yet real differences - will run as if it was written for the type you're filling &lt;T&gt; with. The dynamic version will just be a &quot;value&quot; and let the DLR figure out how to invoke members (which again, unless you're calling ToString() or GetHashCode(), will fail). dynamic will also be slower as the runtime binding has to be done every time, though admittedly this is unlikely to be any sort of bottleneck.

Obviously I'm going to say always use the generic version in this case.