我在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);
}
我该如何解决?
答案 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;
}