/// <summary>
        /// Returns the default value for the type being operated on
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static object DefaultValue(this Type type)
        {
            if (_defaultTypeValues.TryGetValue(type, out var cached))
            {
                return(cached);
            }
            var method = DefaultvalueGeneric.MakeGenericMethod(type);
            var result = method.Invoke(null, null);

            _defaultTypeValues.TryAdd(type, result);
            return(result);
        }
        /// <summary>
        /// Returns true if the type being operated on can be
        /// implicitly upcast to the target type
        /// </summary>
        /// <param name="src"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static bool CanImplicitlyUpcastTo(
            this Type src, Type target
            )
        {
            var  convertSpecific = TryConvertGeneric.MakeGenericMethod(target);
            var  defaultSpecific = DefaultvalueGeneric.MakeGenericMethod(src);
            var  defaultValue    = defaultSpecific.Invoke(null, null);
            bool canConvert;

            try
            {
                convertSpecific.Invoke(null, new[] { defaultValue });
                canConvert = true;
            }
            catch
            {
                canConvert = false;
            }
            return(canConvert);
        }