I have a generic method in a MySQL connector witch make generic conversion. I simplify it for the question, cause it makes lot of things. At the end, it make a generic conversion and work fine, but I have a problem to convert Int64 to Int32.
object var1 = (long)64;
int? var2 = Select<int?>(var1); // E开发者_如何转开发RROR Int32Converter from Int64
public T Select<T>(object value)
{
return (T)System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value);
}
How can I fix it ?
Can't you use Convert.ChangeType
instead?
int value = Convert.ChangeType(var1, TypeCode.Int32);
or
int value = Convert.ToInt32(var1);
note that these will throw exceptions if var
is outside the allowable range of Int32
You can't convert from a larger type to a narrower type without an explicit cast.
The problem is that ChangeType isn't compatible with nullable value types (eg. int?).
If you test for Nullable<T> and then convert to the non-nullable type instead it should work. eg.
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 is a handy extension method for 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;
}
精彩评论