使用Int64进行通用转换

时间:2011-02-16 13:36:38

标签: c# generics

我在MySQL连接器中有一个泛型方法,可以进行泛型转换。 我为这个问题简化了它,因为它做了很多事情。 最后,它进行了一般转换并正常工作,但是我将Int64转换为Int32时遇到了问题。

object var1 = (long)64;
int? var2 = Select<int?>(var1); // ERROR Int32Converter from Int64

public T Select<T>(object value)
{
  return (T)System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value);
}

我该如何解决?

3 个答案:

答案 0 :(得分:4)

您不能使用Convert.ChangeType吗?

int value = Convert.ChangeType(var1, TypeCode.Int32);

int value = Convert.ToInt32(var1);

请注意,如果var超出允许范围Int32

,这些会抛出异常

答案 1 :(得分:3)

如果没有明确的演员,您无法从较大的类型转换为较窄的类型。

答案 2 :(得分:2)

问题是ChangeType与可空值类型(例如int?)不兼容。

如果你测试Nullable&lt; T&gt;然后转换为非可空类型,它应该工作。例如

object var1 = (long)64;
int? var2 = Select<int?>(var1); 

public T Select<T>(object value)
{
    var type = typeof(T);
    if (type.InheritsOrImplements(typeof(Nullable<>)))
        type = type.GetGenericArguments().First();
    // Non-nullable type can be cast as Nullable equivalent
    return (T)TypeDescriptor.GetConverter(type).ConvertFrom(value);
}

BTW ... InheritsOrImplements是Type

的一个方便的扩展方法
public static bool InheritsOrImplements(this Type child, Type parent)
{
    if (child == null || parent == null) return false;

    parent = resolveGenericTypeDefinition(parent);
    if (parent.IsAssignableFrom(child)) return true;

    var currentChild = child.IsGenericType ? child.GetGenericTypeDefinition() : child;
    while (currentChild != typeof(object))
{
        if (parent == currentChild || hasAnyInterfaces(parent, currentChild)) return true;
        currentChild = currentChild.BaseType != null && currentChild.BaseType.IsGenericType
            ? currentChild.BaseType.GetGenericTypeDefinition() 
            : currentChild.BaseType;

        if (currentChild == null) return false;
    }
return false;
}