将存储在对象> =中的数值与另一个对象进行比较

时间:2013-09-19 10:33:39

标签: c# object compare type-conversion

在我的程序中,我正在从表中读取SchemData。 我需要确定列大小,并在运行时决定是否给定值 匹配列大小,可以写入该列。 如果是字母数字类型,如char,nvarchar,......这没问题。

但是在数值的情况下,我无法将该值与列大小进行比较,因为如果我的理解正确,则列大小将为我提供存储在该列中的字节数。

所以我想检查一下,如果我的数值在该列的System.Type变量中存储的特定数据类型的MaxValue范围内。

我开始使用反射来确定MaxValue,并且还识别可以为空的类型:

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;
}

现在我得到一个对象,存储MaxValue信息。

如何将存储在对象内的MaxValue与存储在另一个对象(或可能是字符串)中的另一个值进行比较。 第二个对象(或字符串,如前所述)中的值是从xml文件中读取的,因此这不是像int这样的特定类型。它需要来自类型对象。

我想到的唯一解决比较问题的方法是实现一个方法并检查交换机内的每个数字类型并执行try解析并返回true / false。

第一个示例方法如下所示:

    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;
    }

有没有人比实施这样的方法更好? 提前谢谢。

1 个答案:

答案 0 :(得分:3)

您可以使用Convert.ChangeType和IComparable来解决此问题。所有原始类型都继承自IComparable。 这个片段在我的最后工作。 确保你在内部或外部捕获异常,因为如果转换类型不正确,ChangeType会抛出格式异常。

 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;
    }

虽然建议不要编写扩展方法,因为它会降低类型安全性。单独为特定类型创建扩展方法,如

 public static bool TestMaxValue(this int? value, int compareValue)
        {
            var intValue = value.GetValueOrDefault();
            var ret = intValue.CompareTo(compareValue) > 0;
            return ret;
        }