这是关于使用反射转换值的问题的后续行动.将某种类型的对象转换为另一种类型可以这样做:
object convertedValue = Convert.ChangeType(value, targetType);
Run Code Online (Sandbox Code Playgroud)
给定两个Type实例(比如FromType和ToType),有没有办法测试转换是否成功?
我可以写一个像这样的扩展方法:
public static class TypeExtensions
{
public static bool CanChangeType(this Type fromType, Type toType)
{
// what to put here?
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:这就是我现在所拥有的.丑陋,但我还没有看到另一种方式......
bool CanChangeType(Type sourceType, Type targetType)
{
try
{
var instanceOfSourceType = Activator.CreateInstance(sourceType);
Convert.ChangeType(instanceOfSourceType, targetType);
return true; // OK, it can be converted
}
catch (Exception ex)
{
return false;
}
Run Code Online (Sandbox Code Playgroud)
esa*_*sac 32
我刚刚遇到同样的问题,我使用Reflector来查看ChangeType的源代码.ChangeType在3种情况下抛出异常:
检查完3个后,保证可以转换.因此,您可以通过简单地自行检查这3个内容来节省大量性能并删除try {}/catch {}块:
public static bool CanChangeType(object value, Type conversionType)
{
if (conversionType == null)
{
return false;
}
if (value == null)
{
return false;
}
IConvertible convertible = value as IConvertible;
if (convertible == null)
{
return false;
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
检查反射器中的Convert.ChangeType方法我在静态构造函数中找到了这个:
ConvertTypes = new Type[] {
typeof(Empty), typeof(object), typeof(DBNull), typeof(bool), typeof(char), typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal),
typeof(DateTime), typeof(object), typeof(string)
};
Run Code Online (Sandbox Code Playgroud)
最后,此方法只是检查源是否正在实现IConvertible,或者目标是否是上面的ConvertTypes之一.所以你的方法应该看起来像这样(非常粗糙):
return (ConvertTypes.Contains(toType) || typeof(IConvertible).IsAssignableFrom(fromType));
Run Code Online (Sandbox Code Playgroud)