How to use reflection to determine if a type can be resolved to a number?

When using reflection, I thought it type.IsPrimitivewould be enough to tell me if that number was, however it turned out to be wrong. Decimalnot a primitive type.

Without typing a long list of types of numbers, such as Int64, Int32, Int16, UInt64etc. How to get around determining whether a particular object is a number? I feel that there is an easier way to do this, besides listing all the types and comparing them with the type in question.

One more step, how to find out if a number is an integer or contains decimals , but doesn't look like Bool? I guess I would like an extension of reflection for IsNumeric, IsWholeNumberand IsFloatingPoint, but they do not exist, as far as I know.

EDIT:

I do not agree with what is marked as a duplicate, because the solution uses the list case statement to find out if this is a number. I want to know if a better solution exists, since the answer is> 3 years.

UPDATE:

If someone else is looking for this, I created an extension library based on the accepted answer for this “duplicate question”. Hope this helps.

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;
            }
        }
    }
}
+4
source share

No one has answered this question yet.

Source: https://habr.com/ru/post/1546047/


All Articles