在编程中,类型转换是一个常见的需求,但每种技术都有其局限性。本文提供了一种在CLR能够执行类型转换时,适用于所有情况的替代方案。
在类型转换的问题上,有两种流行的解决方案:使用System.Convert.ChangeType
,或者获取System.ComponentModel.TypeConverter
并调用其ConvertFrom
方法。第一种方法在尝试将值类型T
转换为System.Nullable
时会失败;第二种方法在尝试转换不同的数值类型时,例如从float
转换到double
时也会失败。这些限制特别令人沮丧,因为CLR内置了执行这两种转换的能力。
一种利用这些类型转换能力的方法是构建一个LINQlambda表达式,将其编译为Func
,然后每次需要在两种类型之间转换时使用编译后的委托。下面是一个实现这种方法的代码示例,它被封装成了System.Type
的扩展方法。
public static class TypeCast {
// 这是暴露其余功能的方法
public static object Cast(this Type type, object obj) {
return GetConverter(type, obj)(obj);
}
private static readonly IDictionary> converters = new Dictionary>();
private static readonly ParameterExpression convParameter = Expression.Parameter(typeof(object), "val");
// 这是实现的"核心"方法
[MethodImpl(MethodImplOptions.Synchronized)]
private static Func
double? x = typeof(double?).Cast(1.0);
int y = typeof(int).Cast(1.2345);