Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing numeric Value stored in object >= to another object

In my program, i'm reading SchemData from a table. I need to determine the column size and decide at runtime if a given value matches the column size and could be written to that column. In case of alpha-numeric Types like char, nvarchar,... this is no problem.

But in case of numeric values i cannot compare the value with the column size, because column size will give me the amount of bytes to store inside that column, if my understanding here is correct.

So i want to check, if my numeric values are inside the MaxValue range of that particular data type stored inside a System.Type variable of that column.

I started with determining the MaxValue using reflection and also recognizing nullable types like that:

public static Object GetMaxValue(this Type type)
{
    var t = GetNullableType(type);
    var f = t.GetField("MaxValue");
    if (f == null)
        return null;
    else
        return f.GetValue(null);
}

public static Type GetNullableType(Type type)
{
    Type retType = type;
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
        var nullableConverter = new System.ComponentModel.NullableConverter(type);
        retType = nullableConverter.UnderlyingType;
    }
    return retType;
}

Now i get an object, storing the MaxValue information.

How can i compare the MaxValue stored inside an object with another value, stored inside another object (or maybe a string). The value inside the second object (or string, as mentioned before) are read from a xml file, therefor this is not a specific type like int. It needs to be from type object.

The only thing to solve the comparison thing i thought of was implementing a method and checking for every single numeric type inside a switch and performing a try parse and return true/false.

First example method looks like this:

    public static bool TestMaxValue(this Type type, object compare)
    {
        var t = GetNullableType(type);
        var mv = t.GetMaxValue();
        bool ret = false;
        switch (Type.GetTypeCode(t))
        {
            case TypeCode.Byte:
                {
                    Byte b;
                    if (Byte.TryParse(compare.ToString(), out b))
                        ret =(Convert.ToByte(mv) >= b);

                    break;
                }
            case TypeCode.Decimal:
                {
                    Decimal b;
                    if (Decimal.TryParse(compare.ToString(), out b))
                        ret = (Convert.ToDecimal(mv) >= b);

                    break;
                }
            case TypeCode.Double:
                {
                    Double b;
                    if (Double.TryParse(compare.ToString(), out b))
                        ret = (Convert.ToDouble(mv) >= b);

                    break;
                }
            case TypeCode.Int16:
                {
                    Int16 b;
                    if (Int16.TryParse(compare.ToString(), out b))
                        ret = (Convert.ToInt16(mv) >= b);

                    break;
                }
            case TypeCode.Int32:
                {
                    Int32 b;
                    if (Int32.TryParse(compare.ToString(), out b))
                        ret = (Convert.ToInt32(mv) >= b);

                    break;
                }
        }
        return ret;
    }

Does anyone have a better idea than implementing such a method? Thanks in advance.

like image 991
Dom84 Avatar asked Sep 02 '25 09:09

Dom84


1 Answers

You can use Convert.ChangeType and IComparable to solve this. All primitive types are inherited from IComparable. This snippet is working at my end. Make sure u catch the exception inside or outside as ChangeType throws format exception if the conversion type is incorrect.

 public static bool TestMaxValue(this Type type, object compare)
    {
        var t = GetNullableType(type);
        var mv = t.GetMaxValue();
        bool ret = false;
        try
        {
            IComparable maxValue = Convert.ChangeType(mv, t) as IComparable;
            IComparable currentValue = Convert.ChangeType(compare, t) as IComparable;
            if (maxValue != null && currentValue != null)
                ret = maxValue.CompareTo(currentValue) > 0;
        }
        catch (FormatException exception)
        {
            //handle is here
            ret = false;
        }
        return ret;
    }

Although its recommended to not write extension methods as it reduces type safety. Create extension methods for specific types separately like

 public static bool TestMaxValue(this int? value, int compareValue)
        {
            var intValue = value.GetValueOrDefault();
            var ret = intValue.CompareTo(compareValue) > 0;
            return ret;
        }
like image 68
Akanksha Gaur Avatar answered Sep 04 '25 22:09

Akanksha Gaur