/// <summary>
 /// Gets the specified key.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="cache">The cache.</param>
 /// <param name="key">The key.</param>
 /// <param name="tag">The tag.</param>
 /// <param name="values">The values.</param>
 /// <returns></returns>
 /// <exception cref="ArgumentNullException">key</exception>
 public static async Task <T> GetAsync <T>(this IMemoryCache cache, MemoryCacheRegistration key, object tag, params object[] values) => await GetOrCreateUsingLockAsync <T>(cache, key ?? throw new ArgumentNullException(nameof(key)), tag, values);
 /// <summary>
 /// Determines whether this instance contains the object.
 /// </summary>
 /// <param name="cache">The cache.</param>
 /// <param name="key">The key.</param>
 /// <param name="values">The values.</param>
 /// <returns>
 ///   <c>true</c> if [contains] [the specified key]; otherwise, <c>false</c>.
 /// </returns>
 public static bool Contains(this IMemoryCache cache, MemoryCacheRegistration key, params object[] values) => cache.Contains(key.GetName(values));
 /// <summary>
 /// Gets the specified key as MemoryCacheResult.
 /// </summary>
 /// <param name="cache">The cache.</param>
 /// <param name="key">The key.</param>
 /// <param name="tag">The tag.</param>
 /// <param name="values">The values.</param>
 /// <returns></returns>
 public static MemoryCacheResult GetResult(this IMemoryCache cache, MemoryCacheRegistration key, object tag, params object[] values) => Get <MemoryCacheResult>(cache, key, tag, values);
 /// <summary>
 /// Removes the specified key.
 /// </summary>
 /// <param name="cache">The cache.</param>
 /// <param name="key">The key.</param>
 /// <param name="values">The values.</param>
 public static void Remove(this IMemoryCache cache, MemoryCacheRegistration key, params object[] values) => cache.Remove(key.GetName(values));