/// <summary>
        /// If the specified value is of any numeric type, retrieves the value as a <c>decimal</c>,
        /// casting if necessary.
        /// <para>The result is empty if the specified value is not of a numeric type.</para>
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Opt <decimal> NumericValueAsDecimalOpt(this IConvertible value)
        {
            switch (Classify(value))
            {
            case SimpleTypeClassification.Decimal:
            {
                return(value.DecimalValueOpt());
            }

            case SimpleTypeClassification.FloatingPoint:
            {
                return(value
                       .FloatingPointValueOpt()
                       .SelectFix(doubleValue => (decimal)doubleValue));
            }

            case SimpleTypeClassification.SignedIntegral:
            {
                return(value
                       .SignedIntegralValueOpt()
                       .SelectFix(longValue => (decimal)longValue));
            }

            case SimpleTypeClassification.UnsignedIntegral:
            {
                return(value
                       .UnsignedIntegralValueOpt()
                       .SelectFix(ulongValue => (decimal)ulongValue));
            }

            default:
                return(Opt.Empty <decimal>());
            }
        }