c# – Is it possible to refactor these two similar methods that handle T and List?

I’m not sure I fully understand the question, but the first thing that leapt to mind is:

<T> can encompass a IList<SomeType> already.

I mean, the first 75% of GetValue() already works with using IList as the generic type:

public async Task<T> GetValue<T>(
        string cacheKey,
        Func<Task<T>> getItem,
        MemoryCacheEntryOptions memoryCacheEntryOptions = null)
{
    if (_memoryCache.TryGetValue(cacheKey, out T cacheEntry))
    {
        return cacheEntry;
    }
    else
    {
        cacheEntry = await getItem(); 

        return SetValue(cacheKey, cacheEntry, memoryCacheEntryOptions);
    }
}

… memoryCache.TryGetValue() works exactly the same, and will operate correctly. cacheEntry will be the correct type (an IList of something.) getItem() works perfectly, too, since it’s a Func that returns the appropriate IList.

Literally the only thing that’s different is ‘SetValue’ vs ‘SetValues’. Which, from your original post, looks to be the call into the 3rd party API.

Well, it begs the question of whether SetValue() in the vendor API will work for an IList?
If it does, your probably is immediately solved: just use GetValue for everything and call it a day.

Assuming that it doesn’t, maybe the question would be whether something like this would work:

public async Task<T> GetValue<T>(string cacheKey, Func<Task<T>> getItem, MemoryCacheEntryOptions memoryCacheEntryOptions = null)
{
    return GetValue(cacheKey, getItem, x => SetValue(cacheKey, x, memoryCacheEntryOptions));
}
public async Task<T> GetValues<T>(string cacheKey, Func<Task<T>> getItem, MemoryCacheEntryOptions memoryCacheEntryOptions = null)
{
    return GetValue(cacheKey, getItem, x => SetValues(cacheKey, x, memoryCacheEntryOptions));
}

private async Task<T> GetValue<T>(string cacheKey, Func<Task<T>> getItem, Func<T, Task<T>> setItem)
{
    if (_memoryCache.TryGetValue(cacheKey, out T cacheEntry))
    {
        return cacheEntry;
    }
    else
    {
        cacheEntry = await getItem(); 

        return setItem(cacheEntry);
    }
}