3

在我的程序中,我正在从表中读取 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 这样的特定类型。它需要来自类型对象。

我想到的唯一解决比较问题的方法是实现一个方法并检查开关内的每个数字类型并执行尝试解析并返回真/假。

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

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

有没有人有比实施这种方法更好的主意?提前致谢。

4

1 回答 1

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;
        }
于 2013-09-19T11:40:10.430 回答