如何使用反射来确定某个类型是否可以解析为数字?

时间:2014-06-25 19:52:46

标签: c# reflection .net-4.5

使用反射时,我认为type.IsPrimitive足以告诉我它是否是一个数字,但事实证明这是错误的。 Decimal不是原始类型。

没有输入很长的数字类型列表,例如Int64Int32Int16UInt64等。如何确定某个特定对象是一个数字?除了列出所有类型并将它们与相关类型进行比较之外,我觉得有一种更简单的方法可以做到这一点。

更进一步,如何判断数字是整数还是包含小数,但不是Bool?我想我想要IsNumericIsWholeNumberIsFloatingPoint的反射扩展,但据我所知它们并不存在。

编辑:

我不同意标记为重复,因为该解决方案使用list \ case语句来确定它是否为数字。我想知道是否存在更好的解决方案,因为答案是> 3岁。

更新:

如果其他人正在搜索此内容,我会根据此“重复问题”的接受答案制作一个扩展程序库。希望这会有所帮助。

namespace HelperLibrary.Extensions
{
    /// <summary>
    /// Extensions for the Type class.
    /// </summary>
    public static class TypeExtensions
    {
        /// <summary>
        /// Gets a value indicating whether the current System.Type is represented in a numeric format.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsNumeric(this Type type)
        {
            if (type == null)
            {
                return false;
            }
            var typeCode = Type.GetTypeCode(type);
            switch (typeCode)
            {
                case TypeCode.Byte:
                case TypeCode.Decimal:
                case TypeCode.Double:
                case TypeCode.Int16:
                case TypeCode.Int32:
                case TypeCode.Int64:
                case TypeCode.SByte:
                case TypeCode.Single:
                case TypeCode.UInt16:
                case TypeCode.UInt32:
                case TypeCode.UInt64:
                    return true;
                //case TypeCode.Char: cannot resolve without object value
                //case TypeCode.String: cannot resolve without object value
                case TypeCode.Object:
                    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
                    {
                        return IsNumeric(Nullable.GetUnderlyingType(type));
                    }
                    return false;
                default:
                    return false;
            }
        }

        /// <summary>
        /// Gets a value indicating whether the current System.Type is a floating point number.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsFloatingPoint(this Type type)
        {
            if (type == null)
            {
                return false;
            }

            var typeCode = Type.GetTypeCode(type);
            switch (typeCode)
            {
                case TypeCode.Decimal:
                case TypeCode.Double:
                case TypeCode.Single:
                    return true;
                //case TypeCode.String: cannot resolve without object value
                case TypeCode.Object:
                    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
                    {
                        return IsFloatingPoint(Nullable.GetUnderlyingType(type));
                    }
                    return false;
                default:
                    return false;
            }
        }

        /// <summary>
        /// Gets a value indicating whether the current System.Type is a whole number.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsWholeNumber(this Type type)
        {
            if (type == null)
            {
                return false;
            }

            var typeCode = Type.GetTypeCode(type);
            switch (typeCode)
            {
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.Int32:
                case TypeCode.Int64:
                case TypeCode.SByte:
                case TypeCode.UInt16:
                case TypeCode.UInt32:
                case TypeCode.UInt64:
                    return true;
                //case TypeCode.Char: cannot resolve without object value
                //case TypeCode.String: cannot resolve without object value
                case TypeCode.Object:
                    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
                    {
                        return IsWholeNumber(Nullable.GetUnderlyingType(type));
                    }
                    return false;
                default:
                    return false;
            }
        }
    }
}

0 个答案:

没有答案